找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1340|回复: 0
收起左侧

基于51单片机的信号发生器Proteus仿真程序

[复制链接]
ID:1049106 发表于 2022-10-25 10:31 | 显示全部楼层 |阅读模式
基于51单片机的信号发生器,仿真用的proteus,程序用的是keil,数模转换重要用的是DAC0832,可实现波形转换。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)

仿真图

仿真图
51hei.gif

单片机源程序如下:
#include"key.h"
#include"math.h"
unsigned int  fword = 1000;
unsigned char Duty;
unsigned char gFunctionCount=0;
unsigned char gTimeCount=0;
unsigned char gType=0;
char FreqNum[5]={0,1,0,0,0};
char AmpNum[2]={5,0};
char DutyNum[2]={5,0};

/*延时函数:按键消抖用*/
static void delay10ms(void)
{
        unsigned char j,i;
        for(j=0;j<110;j++)
                for(i=0;i<100;i++);
}

/*按键扫描函数:主函数主循环只调用此函数,其完成参数设定以及下达功能*/
void key_scan(void)
{
        unsigned int  freqtemp;
        unsigned int  amptemp;
        unsigned char dutytemp;
        if(KEY1==0)                  //功能键按下
        {
                delay10ms();
                if(KEY1==0)
                {
                        gFunctionCount++;
                        //功能设定一:设置波形
                        if(gFunctionCount==1)     
                        {
                                gTimeCount=0;
                                EA = 0;
                                LCDDispChar(8,1,'#');
                        }
                        //功能设定二:设置频率
                        else if(gFunctionCount==2)
                        {
                                 gTimeCount=0;
                                LCDCursor();
                                LCDDispChar(8,1,' ');
                                LCDDispNum(6,2,FreqNum[3]);
                        }
                        //功能设定三:设置方波占空比
                        else if((gFunctionCount==3)&&(gType==1))   //        ((gFunctionCount==4)&&(gType==1))
                        {
                                gTimeCount=0;
                                LCDCursor();
                                LCDDispNum(14,2,DutyNum[1]);
                                LCDDispNum(13,2,DutyNum[0]);
                        }
                        //设定完毕
                        else if((gFunctionCount==4)||((gFunctionCount==3)&&(gType!=1)))                 //         ((gFunctionCount==5)||((gFunctionCount==4)&&(gType!=1)))
                        {
                                gFunctionCount=0;
                                
                                LCDNotCursor();
                                //计算频率值               
                                freqtemp=(unsigned int )FreqNum[0]*10000+(unsigned int )FreqNum[1]*1000+(unsigned int)FreqNum[2]*100+(unsigned int)FreqNum[3]*10+(unsigned int)FreqNum[4];
                                if(freqtemp>10000)//当输入频率大于10kHz时,将频率设置成10kHz
                                {
                                        freqtemp = 10000;
                                        LCDDispNum(3,2,1);LCDDispNum(4,2,0);LCDDispNum(5,2,0);LCDDispNum(6,2,0);LCDDispNum(7,2,0);
                                        FreqNum[0]=1;FreqNum[1]=0;FreqNum[2]=0;FreqNum[3]=0;FreqNum[4]=0;
                                }
                                else if(freqtemp<1)//当输入频率小于1Hz时,将频率设置成1Hz
                                {
                                        freqtemp = 1;
                                        LCDDispNum(3,2,0);LCDDispNum(4,2,0);LCDDispNum(5,2,0);LCDDispNum(6,2,0);LCDDispNum(7,2,1);
                                        FreqNum[0]=0;FreqNum[1]=0;FreqNum[2]=0;FreqNum[3]=0;FreqNum[4]=1;
                                }
                                //幅值
                            amptemp =50;
                                //计算占空比
                                dutytemp=(unsigned char)DutyNum[0]*10   +(unsigned char)DutyNum[1];
                                if(dutytemp>90)//当输入占空比大于90%时,将占空比设置成90%
                                {        
                                        dutytemp = 90;
                                        LCDDispNum(13,2,9);LCDDispNum(14,2,0);
                                        DutyNum[0]=9;DutyNum[1]=0;        
                                }
                                else if(dutytemp<10)//当输入占空比小于10%时,将占空比设置成10%
                                {        
                                        dutytemp = 10;
                                        LCDDispNum(13,2,1);LCDDispNum(14,2,0);
                                        DutyNum[0]=1;DutyNum[1]=0;        
                                }
                                if(gType!=1)//当波形不为方波时,显示横杠表示无效
                                {        LCDDispString(13,2,"--");}
                                //设置数据处理完成,以下代码进行DA输出设置
                                fword = (unsigned int)(freqtemp*1.009);        //设置频率控制字
                                AmPort = (unsigned char)(50*5.1);        //设置幅值
                                Duty = dutytemp;        //设置方波占空比
                                EA = 1;        
                        }
                }while(!KEY1);           //循环到松手        
        }
        if(KEY2==0)                  //设定键按下
        {
                delay10ms();
                if(KEY2==0)
                {
                        gTimeCount++;
                        /*********************************************************
                        波形设定
                        *********************************************************/
                        if(gFunctionCount==1 && gTimeCount==1)
                        {        LCDDispString(5,1,"Squ");gType=1; }
                        else if(gFunctionCount==1 && gTimeCount==2)
                        {        LCDDispString(5,1,"Tri");gType=2; }
                        else if(gFunctionCount==1 && gTimeCount==3)
                        {        LCDDispString(5,1,"Saw");gType=3;}
                        else if(gFunctionCount==1 && gTimeCount==4)
                        {        gTimeCount=0;LCDDispString(5,1,"Sin");gType=0; }
                        /*********************************************************
                        频率设定
                        *********************************************************/
                        else if(gFunctionCount==2 && gTimeCount==1)
                        {        LCDDispNum(5,2,FreqNum[2]);        }
                        else if(gFunctionCount==2 && gTimeCount==2)
                        {        LCDDispNum(4,2,FreqNum[1]);        }
                        else if(gFunctionCount==2 && gTimeCount==3)
                        {        LCDDispNum(3,2,FreqNum[0]);        }
                        else if(gFunctionCount==2 && gTimeCount==4)
                        {        LCDDispChar(2,2,' ');        }
                        else if(gFunctionCount==2 && gTimeCount==5)
                        {        gTimeCount=0;LCDDispNum(6,2,FreqNum[3]);        }
                        /*********************************************************
                        方波设定
                        *********************************************************/
                        else if(gFunctionCount==3 && gTimeCount==1)
                        {        LCDDispChar(12,2,':');        }
                        else if(gFunctionCount==3 && gTimeCount==2)
                        {        gTimeCount=0;LCDDispNum(13,2,DutyNum[0]);        }

                }while(!KEY2);           //循环到松手        
        }
        if(KEY3==0)                  //加键按下
        {
                delay10ms();
                if(KEY3==0)
                {
                        if(gFunctionCount==2 && gTimeCount==1)
                        {
                                FreqNum[3]++;
                                if(FreqNum[3]==10)
                                        FreqNum[3]=0;
                                LCDDispNum(6,2,FreqNum[3]);LCDDispNum(5,2,FreqNum[2]);        
                        }
                        else if(gFunctionCount==2 && gTimeCount==2)
                        {        
                                FreqNum[2]++;
                                if(FreqNum[2]==10)
                                        FreqNum[2]=0;
                                LCDDispNum(5,2,FreqNum[2]);LCDDispNum(4,2,FreqNum[1]);               
                        }

Keil代码与Proteus仿真下载: 基于51单片机的信号发生器.7z (52.17 KB, 下载次数: 44)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表