本人第一次發技術貼,是學校一個比賽項目,項目要求如下:簡單說就是用51單片機產生頻率可調的方波,正弦波,鋸齒波和三角波。
本人使用DAC0832芯片和LM358N完成數模轉換及信號放大。正弦波形有一點點失真。歡迎大神給后續意見,僅供學習。
keil文件及c語言文件在下面。
電路原理圖如下:
5e31f5cbbcaaf1113d378146c97b484.jpg (215.58 KB, 下載次數: 25)
下載附件
原理圖
2018-12-6 23:48 上傳
示波器實測波形如下:
e146dbbe5c8179887ec2616fe7047e9.jpg (3.62 MB, 下載次數: 30)
下載附件
2018-12-6 23:48 上傳
c65aed90695b760468d8d9f1275c8b5.jpg (3.54 MB, 下載次數: 30)
下載附件
2018-12-6 23:48 上傳
6461629f0d842351bea6a9b31cfc6e0.jpg (3.6 MB, 下載次數: 25)
下載附件
2018-12-6 23:47 上傳
單片機源程序如下:
- #include<reg51.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit LCD_RST=P0^5;
- sbit LCD_CE=P0^4;
- sbit LCD_DC=P0^3;
- sbit SDIN=P0^2;
- sbit SCLK=P0^1;
- void LCD_write_byte(unsigned char dat, unsigned char command) ;
- void LCD_init(void);
- void delay_1us();
- void LCD_set_XY(unsigned char X, unsigned char Y);
- void LCD_clear();
- void LCD_draw_bmp_pixel(unsigned char X,unsigned char Y,unsigned char *map,unsigned char Pix_x,unsigned char Pix_y);
- bit run=1;
- sbit cs=P1^2;//DAC0832的輸入寄存器的選擇端
- sbit wr=P1^3;//DAC0832輸入寄存器的寫選通信號
- sbit s1=P3^4;//按鍵
- sbit s2=P3^3;//按鍵
- sbit s3=P3^2;//按鍵
- uchar s1num=0,ys=30;//ys表示延時函數實參的初始值;s1num表示按鍵切換的代碼
- uchar code Sin[256]={
- 0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2,
- …………
- …………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
- 0x00,0x00,0x7F,0x40,0x50,0x48,0x44,0x43,0x44,0x48,0x50,0x40,0xFF,0x00,0x00,0x00};
- void keyscanf();//波形切換函數
- void delay1(uchar y);//聲明延時函數
- void main()//主函數
- {
- uchar i;
- IT0=1;
- EX0=1;
- IT1=1;
- EX1=1;
- EA=1;
- LCD_init();//LCD初始化
- cs=0;//打開輸入寄存器選擇端(詳見DAC0832的操作時序)
- while(1)
- {
- keyscanf();//調用波形切換函數
- if(s1num==0)//方波(s1沒有按下)
- {
- if(run==1)
- {
- LCD_draw_bmp_pixel(0,0,dang,16,16) ;
- LCD_draw_bmp_pixel(17,0,qian,16,16) ;
- LCD_draw_bmp_pixel(33,0,shu,16,16) ;
- LCD_draw_bmp_pixel(49,0,chu,16,16) ;
- LCD_draw_bmp_pixel(65,0,fang,16,16) ;
- LCD_draw_bmp_pixel(0,2,bo,16,16) ;
- LCD_draw_bmp_pixel(17,2,douhao,16,16) ;
- LCD_draw_bmp_pixel(33,2,an,16,16) ;
- LCD_draw_bmp_pixel(49,2,xia,16,16) ;
- LCD_draw_bmp_pixel(65,2,shu,16,16) ;
- LCD_draw_bmp_pixel(0,4,chu,16,16) ;
- LCD_draw_bmp_pixel(17,4,san,16,16) ;
- LCD_draw_bmp_pixel(33,4,jiao,16,16) ;
- LCD_draw_bmp_pixel(49,4,bo,16,16) ;
- run=0;
- }
- for(i=0;i<255;i++)
- {
- P2=0x00;
- wr=0;//輸入寄存器寫選通信號有效(詳見DAC0832的操作時序)
- wr=1;//關閉寫選通信號
- }
- delay1(ys);//通過延時時間的長短改變信號的頻率
- for(i=0;i<255;i++)
- {
- P2=0xff;
- wr=0;
- wr=1;
- }
- delay1(ys);//通過延時時間的長短改變信號的頻率
- }
- if(s1num==1)//三角波(s1第一次按下)
- {
- if(run==1)
- {
- LCD_draw_bmp_pixel(0,0,dang,16,16) ;
- LCD_draw_bmp_pixel(17,0,qian,16,16) ;
- LCD_draw_bmp_pixel(33,0,shu,16,16) ;
- LCD_draw_bmp_pixel(49,0,chu,16,16) ;
- LCD_draw_bmp_pixel(65,0,san,16,16) ;
- LCD_draw_bmp_pixel(0,2,jiao,16,16) ;
- LCD_draw_bmp_pixel(17,2,bo,16,16) ;
- LCD_draw_bmp_pixel(33,2,an,16,16) ;
- LCD_draw_bmp_pixel(49,2,xia,16,16) ;
- LCD_draw_bmp_pixel(65,2,shu,16,16) ;
- LCD_draw_bmp_pixel(0,4,chu,16,16) ;
- LCD_draw_bmp_pixel(17,4,ju,16,16) ;
- LCD_draw_bmp_pixel(33,4,chi,16,16) ;
- LCD_draw_bmp_pixel(49,4,bo,16,16) ;
- run=0;
- }
- for(i=0;i<255;i++)
- {
- P2=i;
- wr=0;
- wr=1;
- }
- delay1(ys);//通過延時時間的長短改變信號的頻率
- for(i=255;i>0;i--)
- {
- P2=i;
- wr=0;
- wr=1;
- }
- delay1(ys);//通過延時時間的長短改變信號的頻率
- }
- if(s1num==2)//鋸齒波(s1第二次按下)
- {
- if(run==1)
- {
- LCD_draw_bmp_pixel(0,0,dang,16,16) ;
- LCD_draw_bmp_pixel(17,0,qian,16,16) ;
- LCD_draw_bmp_pixel(33,0,shu,16,16) ;
- LCD_draw_bmp_pixel(49,0,chu,16,16) ;
- LCD_draw_bmp_pixel(65,0,ju,16,16) ;
- LCD_draw_bmp_pixel(0,2,chi,16,16) ;
- LCD_draw_bmp_pixel(17,2,bo,16,16) ;
- LCD_draw_bmp_pixel(33,2,an,16,16) ;
- LCD_draw_bmp_pixel(49,2,xia,16,16) ;
- LCD_draw_bmp_pixel(65,2,shu,16,16) ;
- LCD_draw_bmp_pixel(0,4,chu,16,16) ;
- LCD_draw_bmp_pixel(17,4,zheng,16,16) ;
- LCD_draw_bmp_pixel(33,4,xian,16,16) ;
- LCD_draw_bmp_pixel(49,4,bo,16,16) ;
- run=0;
- }
- for(i=0;i<255;i++)
- {
- P2=i;
- wr=0;
- wr=1;
- }
- delay1(ys);//通過延時時間的長短改變信號的頻率
- }
- if(s1num==3)//正弦波(s1第三次按下)
- {
- if(run==1)
- {
- LCD_draw_bmp_pixel(0,0,dang,16,16) ;
- LCD_draw_bmp_pixel(17,0,qian,16,16) ;
- LCD_draw_bmp_pixel(33,0,shu,16,16) ;
- LCD_draw_bmp_pixel(49,0,chu,16,16) ;
- LCD_draw_bmp_pixel(65,0,zheng,16,16) ;
- LCD_draw_bmp_pixel(0,2,xian,16,16) ;
- LCD_draw_bmp_pixel(17,2,bo,16,16) ;
- LCD_draw_bmp_pixel(33,2,an,16,16) ;
- LCD_draw_bmp_pixel(49,2,xia,16,16) ;
- LCD_draw_bmp_pixel(65,2,shu,16,16) ;
- LCD_draw_bmp_pixel(0,4,chu,16,16) ;
- LCD_draw_bmp_pixel(17,4,fang,16,16) ;
- LCD_draw_bmp_pixel(33,4,bo,16,16) ;
- run=0;
- }
- for(i=0;i<255;i++)
- {
- P2=Sin[i];
- wr=0;
- wr=1;
- }
- delay1(ys);//通過延時時間的長短改變信號的頻率
- }
- }
- }
- void LCD_write_byte(unsigned char dat, unsigned char command)
- {
- unsigned char i;
- LCD_CE = 0; //5110片選有效,允許輸入數據
- if (command == 0) //寫命令
- LCD_DC = 0;
- else LCD_DC = 1; //寫數據
- for(i=0;i<8;i++) //傳送8bit數據
- {
- if(dat&0x80)
- SDIN = 1;
- else
- SDIN = 0;
- SCLK = 0;
- dat = dat << 1;
- SCLK = 1;
- }
- LCD_CE = 1; //禁止5110
- }
- void delay_1us()
- {
- unsigned int y;
-
- for(y=110;y>0;y--)
- {}
- }
- /***********************************************************
- 函數名稱:LCD_init
- 函數功能:5110初始化
- 入口參數:無
- 出口參數:無
- 備 注:
- ***********************************************************/
- void LCD_init(void)
- {
- LCD_RST = 0; // 產生一個讓LCD復位的低電平脈沖
- delay_1us();
- LCD_RST = 1;
-
- LCD_CE = 0; // 關閉LCD
- delay_1us();
- LCD_CE = 1; // 使能LCD
- delay_1us();
-
- LCD_write_byte(0x21, 0); // 使用擴展命令設置LCD模式
- LCD_write_byte(0xc8, 0); // 設置液晶偏置電壓
- LCD_write_byte(0x06, 0); // 溫度校正
- LCD_write_byte(0x13, 0); // 1:48
- LCD_write_byte(0x20, 0); // 使用基本命令,V=0,水平尋址
- LCD_clear(); // 清屏
- LCD_write_byte(0x0c, 0); // 設定顯示模式,正常顯示
-
- LCD_CE = 0; // 關閉LCD
- }
- /***********************************************************
- 函數名稱:LCD_set_XY
- 函數功能:設置LCD坐標函數
- 入口參數:X :0-83
- Y :0-5
- 出口參數:無
- 備 注:
- ***********************************************************/
- void LCD_set_XY(unsigned char X, unsigned char Y)
- {
- LCD_write_byte(0x40 | Y, 0); // column
- LCD_write_byte(0x80 | X, 0); // row
- }
- /***********************************************************
- 函數名稱:LCD_draw_bmp_pixel
- 函數功能:位圖繪制函數
- 入口參數:X、Y :位圖繪制的起始X、Y坐標;
- *map :位圖點陣數據;
- Pix_x :位圖像素(長)
- Pix_y :位圖像素(寬)
- 出口參數:無
- 備 注:
- ***********************************************************/
- void LCD_draw_bmp_pixel(unsigned char X,unsigned char Y,unsigned char *map,unsigned char Pix_x,unsigned char Pix_y)
- {
- unsigned int i,n;
- unsigned char row;
- //計算位圖所占行數
- if (Pix_y%8==0) //如果為位圖所占行數為整數
- row=Pix_y/8;
- else
- row=Pix_y/8+1; //如果為位圖所占行數不是整數
-
- LCD_set_XY(X,Y);
- for (n=0;n<row;n++) //換行
- {
- for(i=0;i<Pix_x;i++)
- {
- LCD_set_XY(X+i,Y+n);
- LCD_write_byte(map[i+n*Pix_x], 1);
- }
- }
- }
- void LCD_clear()
- {
- unsigned char t,k;
- LCD_set_XY(0,0);
- for(t=0;t<6;t++)
- {
- for(k=0;k<84;k++)
- LCD_write_byte(0x00,1);
- }
- }
- void keyscanf()//波形切換函數
- {
- if(s1==0)//判斷按鍵按下
- {
- delay1(20);//延時消除抖動
- if(s1==0)//重新判斷
- {
- while(!s1);//等待按鍵釋放
- s1num++;
- run=1;
- s1num=s1num%4;//波形的切換由此數值來決定
- }
- }
- }
- void delay1(uchar y)//延時函數
- {
- uchar i;
- for(i=y;i>0;i--);
- }
- void aaaa() interrupt 0
- {
- if(s3==0)//判斷按鍵按下
- {
- delay1(20);//延時消除抖動
- if(s3==0)//重新判斷
- {
- while(!s3);//等待按鍵釋放
- ys++;
- }
- }
- }
- void bbbb() interrupt 2
- {
- if(s2==0)//判斷按鍵按下
- {
- delay1(20);//延時消除抖動
- if(s2==0)//重新判斷
- {
- while(!s2);//等待按鍵釋放
- …………
- …………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
基于51單片機的波形發生器.rar
(28.66 KB, 下載次數: 77)
2018-12-6 23:49 上傳
點擊文件名下載附件
keil全部文件 下載積分: 黑幣 -5
|