找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4222|回复: 3
收起左侧

基于51单片机的DAC0832波形发生器,是学校的比赛,硬件以实现有图

[复制链接]
ID:283491 发表于 2018-12-6 23:49 | 显示全部楼层 |阅读模式
本人第一次发技术贴,是学校一个比赛项目,项目要求如下:简单说就是用51单片机产生频率可调的方波,正弦波,锯齿波和三角波。
本人使用DAC0832芯片和LM358N完成数模转换及信号放大。正弦波形有一点点失真。欢迎大神给后续意见,仅供学习。
keil文件及c语言文件在下面。
电路原理图如下:

原理图

原理图


示波器实测波形如下:
e146dbbe5c8179887ec2616fe7047e9.jpg c65aed90695b760468d8d9f1275c8b5.jpg 6461629f0d842351bea6a9b31cfc6e0.jpg

单片机源程序如下:
  1. #include<reg51.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. sbit LCD_RST=P0^5;
  5. sbit LCD_CE=P0^4;
  6. sbit LCD_DC=P0^3;
  7. sbit SDIN=P0^2;
  8. sbit SCLK=P0^1;
  9. void LCD_write_byte(unsigned char dat, unsigned char command)                ;
  10. void LCD_init(void);
  11. void delay_1us();
  12. void LCD_set_XY(unsigned char X, unsigned char Y);
  13. void LCD_clear();
  14. void LCD_draw_bmp_pixel(unsigned char X,unsigned char Y,unsigned char *map,unsigned char Pix_x,unsigned char Pix_y);               
  15. bit run=1;
  16. sbit cs=P1^2;//DAC0832的输入寄存器的选择端
  17. sbit wr=P1^3;//DAC0832输入寄存器的写选通信号
  18. sbit s1=P3^4;//按键
  19. sbit s2=P3^3;//按键
  20. sbit s3=P3^2;//按键
  21. uchar s1num=0,ys=30;//ys表示延时函数实参的初始值;s1num表示按键切换的代码
  22. uchar code Sin[256]={
  23. 0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2,
  24. …………
  25. …………
  26. …………限于本文篇幅 余下代码请从51黑下载附件…………
  27. 0x00,0x00,0x7F,0x40,0x50,0x48,0x44,0x43,0x44,0x48,0x50,0x40,0xFF,0x00,0x00,0x00};

  28. void keyscanf();//波形切换函数
  29. void delay1(uchar y);//声明延时函数

  30. void main()//主函数
  31. {       
  32.         uchar i;
  33.         IT0=1;
  34.         EX0=1;
  35.         IT1=1;
  36.         EX1=1;
  37.         EA=1;

  38.         LCD_init();//LCD初始化          
  39.         cs=0;//打开输入寄存器选择端(详见DAC0832的操作时序)
  40.         while(1)
  41.         {
  42.                 keyscanf();//调用波形切换函数
  43.                 if(s1num==0)//方波(s1没有按下)
  44.         {       
  45.                 if(run==1)
  46.          {
  47.                  LCD_draw_bmp_pixel(0,0,dang,16,16) ;
  48.                 LCD_draw_bmp_pixel(17,0,qian,16,16) ;
  49.                 LCD_draw_bmp_pixel(33,0,shu,16,16) ;
  50.                 LCD_draw_bmp_pixel(49,0,chu,16,16) ;
  51.                 LCD_draw_bmp_pixel(65,0,fang,16,16) ;
  52.                 LCD_draw_bmp_pixel(0,2,bo,16,16) ;
  53.                 LCD_draw_bmp_pixel(17,2,douhao,16,16) ;
  54.                 LCD_draw_bmp_pixel(33,2,an,16,16) ;
  55.                 LCD_draw_bmp_pixel(49,2,xia,16,16) ;
  56.                 LCD_draw_bmp_pixel(65,2,shu,16,16) ;
  57.                 LCD_draw_bmp_pixel(0,4,chu,16,16) ;
  58.                 LCD_draw_bmp_pixel(17,4,san,16,16) ;
  59.                 LCD_draw_bmp_pixel(33,4,jiao,16,16) ;
  60.                 LCD_draw_bmp_pixel(49,4,bo,16,16) ;
  61.                 run=0;
  62.         }
  63.                 for(i=0;i<255;i++)
  64.                 {
  65.                         P2=0x00;
  66.                         wr=0;//输入寄存器写选通信号有效(详见DAC0832的操作时序)
  67.                         wr=1;//关闭写选通信号
  68.                 }
  69.                 delay1(ys);//通过延时时间的长短改变信号的频率
  70.                 for(i=0;i<255;i++)
  71.                 {
  72.                         P2=0xff;
  73.                         wr=0;
  74.                         wr=1;
  75.                 }
  76.                 delay1(ys);//通过延时时间的长短改变信号的频率
  77.         }
  78.         if(s1num==1)//三角波(s1第一次按下)
  79.         {       
  80.                 if(run==1)
  81.          {
  82.                  LCD_draw_bmp_pixel(0,0,dang,16,16) ;
  83.                 LCD_draw_bmp_pixel(17,0,qian,16,16) ;
  84.                 LCD_draw_bmp_pixel(33,0,shu,16,16) ;
  85.                 LCD_draw_bmp_pixel(49,0,chu,16,16) ;
  86.                 LCD_draw_bmp_pixel(65,0,san,16,16) ;
  87.                 LCD_draw_bmp_pixel(0,2,jiao,16,16) ;
  88.                 LCD_draw_bmp_pixel(17,2,bo,16,16) ;
  89.                 LCD_draw_bmp_pixel(33,2,an,16,16) ;
  90.                 LCD_draw_bmp_pixel(49,2,xia,16,16) ;
  91.                 LCD_draw_bmp_pixel(65,2,shu,16,16) ;
  92.                 LCD_draw_bmp_pixel(0,4,chu,16,16) ;
  93.                 LCD_draw_bmp_pixel(17,4,ju,16,16) ;
  94.                 LCD_draw_bmp_pixel(33,4,chi,16,16) ;
  95.                 LCD_draw_bmp_pixel(49,4,bo,16,16) ;
  96.                 run=0;
  97.                 }
  98.         for(i=0;i<255;i++)
  99.         {
  100.         P2=i;
  101.         wr=0;
  102.         wr=1;
  103.         }
  104.         delay1(ys);//通过延时时间的长短改变信号的频率
  105.         for(i=255;i>0;i--)
  106.         {
  107.         P2=i;
  108.         wr=0;
  109.         wr=1;
  110.         }
  111.         delay1(ys);//通过延时时间的长短改变信号的频率
  112.         }
  113.         if(s1num==2)//锯齿波(s1第二次按下)
  114.         {
  115.                 if(run==1)
  116.          {
  117.                  LCD_draw_bmp_pixel(0,0,dang,16,16) ;
  118.                 LCD_draw_bmp_pixel(17,0,qian,16,16) ;
  119.                 LCD_draw_bmp_pixel(33,0,shu,16,16) ;
  120.                 LCD_draw_bmp_pixel(49,0,chu,16,16) ;
  121.                 LCD_draw_bmp_pixel(65,0,ju,16,16) ;
  122.                 LCD_draw_bmp_pixel(0,2,chi,16,16) ;
  123.                 LCD_draw_bmp_pixel(17,2,bo,16,16) ;
  124.                 LCD_draw_bmp_pixel(33,2,an,16,16) ;
  125.                 LCD_draw_bmp_pixel(49,2,xia,16,16) ;
  126.                 LCD_draw_bmp_pixel(65,2,shu,16,16) ;
  127.                 LCD_draw_bmp_pixel(0,4,chu,16,16) ;
  128.                 LCD_draw_bmp_pixel(17,4,zheng,16,16) ;
  129.                 LCD_draw_bmp_pixel(33,4,xian,16,16) ;
  130.                 LCD_draw_bmp_pixel(49,4,bo,16,16) ;
  131.                 run=0;
  132.         }
  133.         for(i=0;i<255;i++)
  134.         {
  135.         P2=i;
  136.         wr=0;
  137.         wr=1;
  138.         }
  139.         delay1(ys);//通过延时时间的长短改变信号的频率
  140.         }
  141.         if(s1num==3)//正弦波(s1第三次按下)
  142.         {
  143.                 if(run==1)
  144.          {
  145.                  LCD_draw_bmp_pixel(0,0,dang,16,16) ;
  146.                 LCD_draw_bmp_pixel(17,0,qian,16,16) ;
  147.                 LCD_draw_bmp_pixel(33,0,shu,16,16) ;
  148.                 LCD_draw_bmp_pixel(49,0,chu,16,16) ;
  149.                 LCD_draw_bmp_pixel(65,0,zheng,16,16) ;
  150.                 LCD_draw_bmp_pixel(0,2,xian,16,16) ;
  151.                 LCD_draw_bmp_pixel(17,2,bo,16,16) ;
  152.                 LCD_draw_bmp_pixel(33,2,an,16,16) ;
  153.                 LCD_draw_bmp_pixel(49,2,xia,16,16) ;
  154.                 LCD_draw_bmp_pixel(65,2,shu,16,16) ;
  155.                 LCD_draw_bmp_pixel(0,4,chu,16,16) ;
  156.                 LCD_draw_bmp_pixel(17,4,fang,16,16) ;
  157.                 LCD_draw_bmp_pixel(33,4,bo,16,16) ;
  158.                 run=0;
  159.                 }
  160.         for(i=0;i<255;i++)
  161.         {
  162.         P2=Sin[i];
  163.         wr=0;
  164.         wr=1;
  165.         }
  166.         delay1(ys);//通过延时时间的长短改变信号的频率
  167.         }
  168.         }
  169. }
  170. void LCD_write_byte(unsigned char dat, unsigned char command)
  171.   {
  172.     unsigned char i;
  173.     LCD_CE = 0;                              //5110片选有效,允许输入数据
  174.     if (command == 0)                        //写命令
  175.          LCD_DC = 0;                          
  176.     else  LCD_DC = 1;                    //写数据
  177.       for(i=0;i<8;i++)                            //传送8bit数据
  178.             {
  179. if(dat&0x80)
  180.                         SDIN = 1;
  181.                   else
  182.                         SDIN = 0;
  183.                   SCLK = 0;
  184.                   dat = dat << 1;
  185.                   SCLK = 1;
  186. }
  187.      LCD_CE = 1;                                //禁止5110
  188.   }


  189. void delay_1us()
  190. {
  191.         unsigned int y;

  192.        
  193.                 for(y=110;y>0;y--)
  194.                 {}
  195. }

  196. /***********************************************************
  197. 函数名称:LCD_init
  198. 函数功能:5110初始化
  199. 入口参数:无
  200. 出口参数:无
  201. 备 注:
  202. ***********************************************************/
  203. void LCD_init(void)
  204.   {
  205.    LCD_RST = 0;     // 产生一个让LCD复位的低电平脉冲
  206.     delay_1us();
  207.    LCD_RST = 1;

  208.    LCD_CE = 0;     // 关闭LCD
  209.     delay_1us();
  210.    LCD_CE = 1;     // 使能LCD
  211.     delay_1us();

  212.     LCD_write_byte(0x21, 0);      // 使用扩展命令设置LCD模式
  213.     LCD_write_byte(0xc8, 0);      // 设置液晶偏置电压
  214.     LCD_write_byte(0x06, 0);      // 温度校正
  215.     LCD_write_byte(0x13, 0);      // 1:48
  216.     LCD_write_byte(0x20, 0);      // 使用基本命令,V=0,水平寻址
  217.         LCD_clear();                 // 清屏
  218.     LCD_write_byte(0x0c, 0);      // 设定显示模式,正常显示
  219.    
  220.     LCD_CE = 0;      // 关闭LCD
  221.   }

  222. /***********************************************************
  223. 函数名称:LCD_set_XY
  224. 函数功能:设置LCD坐标函数
  225. 入口参数:X       :0-83
  226.           Y       :0-5
  227. 出口参数:无
  228. 备 注:
  229. ***********************************************************/
  230. void LCD_set_XY(unsigned char X, unsigned char Y)
  231. {
  232.     LCD_write_byte(0x40 | Y, 0);              // column
  233.     LCD_write_byte(0x80 | X, 0);        // row
  234. }

  235. /***********************************************************
  236. 函数名称:LCD_draw_bmp_pixel
  237. 函数功能:位图绘制函数
  238. 入口参数:X、Y    :位图绘制的起始X、Y坐标;
  239.           *map    :位图点阵数据;
  240.           Pix_x   :位图像素(长)
  241.           Pix_y   :位图像素(宽)
  242. 出口参数:无
  243. 备 注:
  244. ***********************************************************/
  245. void LCD_draw_bmp_pixel(unsigned char X,unsigned char Y,unsigned char *map,unsigned char Pix_x,unsigned char Pix_y)
  246. {
  247.     unsigned int i,n;
  248.     unsigned char row;
  249.                                             //计算位图所占行数
  250.       if (Pix_y%8==0)             //如果为位图所占行数为整数
  251.            row=Pix_y/8;      
  252.       else
  253.          row=Pix_y/8+1;            //如果为位图所占行数不是整数
  254.    
  255.       LCD_set_XY(X,Y);
  256.     for (n=0;n<row;n++)            //换行
  257.       {      
  258.         for(i=0;i<Pix_x;i++)
  259.           {      
  260.                  LCD_set_XY(X+i,Y+n);
  261.              LCD_write_byte(map[i+n*Pix_x], 1);
  262.           }                        
  263.       }      
  264. }

  265. void LCD_clear()
  266. {
  267.         unsigned char t,k;
  268.         LCD_set_XY(0,0);
  269.         for(t=0;t<6;t++)
  270.         {
  271.                 for(k=0;k<84;k++)
  272.                 LCD_write_byte(0x00,1);
  273.         }

  274. }
  275. void keyscanf()//波形切换函数
  276. {
  277. if(s1==0)//判断按键按下
  278. {
  279. delay1(20);//延时消除抖动
  280. if(s1==0)//重新判断
  281. {
  282. while(!s1);//等待按键释放
  283. s1num++;
  284. run=1;
  285. s1num=s1num%4;//波形的切换由此数值来决定
  286. }
  287. }
  288. }
  289. void delay1(uchar y)//延时函数
  290. {
  291. uchar i;
  292. for(i=y;i>0;i--);
  293. }

  294. void aaaa() interrupt 0
  295. {
  296. if(s3==0)//判断按键按下
  297. {
  298. delay1(20);//延时消除抖动
  299. if(s3==0)//重新判断
  300. {
  301. while(!s3);//等待按键释放
  302.         ys++;
  303. }
  304. }                       

  305. }
  306. void bbbb() interrupt 2
  307. {
  308. if(s2==0)//判断按键按下
  309. {
  310. delay1(20);//延时消除抖动
  311. if(s2==0)//重新判断
  312. {
  313. while(!s2);//等待按键释放
  314.         …………
  315. …………
  316. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
基于51单片机的波形发生器.rar (28.66 KB, 下载次数: 77)

评分

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

查看全部评分

回复

使用道具 举报

ID:514789 发表于 2019-4-24 11:35 | 显示全部楼层
基于STM32可以吗~
回复

使用道具 举报

ID:283491 发表于 2019-11-9 16:45 | 显示全部楼层

可以的,改代码吧
回复

使用道具 举报

ID:421805 发表于 2019-11-13 06:00 来自手机 | 显示全部楼层
谢谢分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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