標(biāo)題: 基于51單片機(jī)的信號發(fā)生器Proteus仿真程序 [打印本頁]

作者: 牛牛與牛牛    時(shí)間: 2022-10-25 10:31
標(biāo)題: 基于51單片機(jī)的信號發(fā)生器Proteus仿真程序
基于51單片機(jī)的信號發(fā)生器,仿真用的proteus,程序用的是keil,數(shù)模轉(zhuǎn)換重要用的是DAC0832,可實(shí)現(xiàn)波形轉(zhuǎn)換。

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


單片機(jī)源程序如下:
#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};

/*延時(shí)函數(shù):按鍵消抖用*/
static void delay10ms(void)
{
        unsigned char j,i;
        for(j=0;j<110;j++)
                for(i=0;i<100;i++);
}

/*按鍵掃描函數(shù):主函數(shù)主循環(huán)只調(diào)用此函數(shù),其完成參數(shù)設(shè)定以及下達(dá)功能*/
void key_scan(void)
{
        unsigned int  freqtemp;
        unsigned int  amptemp;
        unsigned char dutytemp;
        if(KEY1==0)                  //功能鍵按下
        {
                delay10ms();
                if(KEY1==0)
                {
                        gFunctionCount++;
                        //功能設(shè)定一:設(shè)置波形
                        if(gFunctionCount==1)     
                        {
                                gTimeCount=0;
                                EA = 0;
                                LCDDispChar(8,1,'#');
                        }
                        //功能設(shè)定二:設(shè)置頻率
                        else if(gFunctionCount==2)
                        {
                                 gTimeCount=0;
                                LCDCursor();
                                LCDDispChar(8,1,' ');
                                LCDDispNum(6,2,FreqNum[3]);
                        }
                        //功能設(shè)定三:設(shè)置方波占空比
                        else if((gFunctionCount==3)&&(gType==1))   //        ((gFunctionCount==4)&&(gType==1))
                        {
                                gTimeCount=0;
                                LCDCursor();
                                LCDDispNum(14,2,DutyNum[1]);
                                LCDDispNum(13,2,DutyNum[0]);
                        }
                        //設(shè)定完畢
                        else if((gFunctionCount==4)||((gFunctionCount==3)&&(gType!=1)))                 //         ((gFunctionCount==5)||((gFunctionCount==4)&&(gType!=1)))
                        {
                                gFunctionCount=0;
                                
                                LCDNotCursor();
                                //計(jì)算頻率值               
                                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)//當(dāng)輸入頻率大于10kHz時(shí),將頻率設(shè)置成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)//當(dāng)輸入頻率小于1Hz時(shí),將頻率設(shè)置成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;
                                //計(jì)算占空比
                                dutytemp=(unsigned char)DutyNum[0]*10   +(unsigned char)DutyNum[1];
                                if(dutytemp>90)//當(dāng)輸入占空比大于90%時(shí),將占空比設(shè)置成90%
                                {        
                                        dutytemp = 90;
                                        LCDDispNum(13,2,9);LCDDispNum(14,2,0);
                                        DutyNum[0]=9;DutyNum[1]=0;        
                                }
                                else if(dutytemp<10)//當(dāng)輸入占空比小于10%時(shí),將占空比設(shè)置成10%
                                {        
                                        dutytemp = 10;
                                        LCDDispNum(13,2,1);LCDDispNum(14,2,0);
                                        DutyNum[0]=1;DutyNum[1]=0;        
                                }
                                if(gType!=1)//當(dāng)波形不為方波時(shí),顯示橫杠表示無效
                                {        LCDDispString(13,2,"--");}
                                //設(shè)置數(shù)據(jù)處理完成,以下代碼進(jìn)行DA輸出設(shè)置
                                fword = (unsigned int)(freqtemp*1.009);        //設(shè)置頻率控制字
                                AmPort = (unsigned char)(50*5.1);        //設(shè)置幅值
                                Duty = dutytemp;        //設(shè)置方波占空比
                                EA = 1;        
                        }
                }while(!KEY1);           //循環(huán)到松手        
        }
        if(KEY2==0)                  //設(shè)定鍵按下
        {
                delay10ms();
                if(KEY2==0)
                {
                        gTimeCount++;
                        /*********************************************************
                        波形設(shè)定
                        *********************************************************/
                        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; }
                        /*********************************************************
                        頻率設(shè)定
                        *********************************************************/
                        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]);        }
                        /*********************************************************
                        方波設(shè)定
                        *********************************************************/
                        else if(gFunctionCount==3 && gTimeCount==1)
                        {        LCDDispChar(12,2,':');        }
                        else if(gFunctionCount==3 && gTimeCount==2)
                        {        gTimeCount=0;LCDDispNum(13,2,DutyNum[0]);        }

                }while(!KEY2);           //循環(huán)到松手        
        }
        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單片機(jī)的信號發(fā)生器.7z (52.17 KB, 下載次數(shù): 45)





歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1