找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11640|回复: 13
收起左侧

[51单片机+仿真Proteus]利用模数转换DAC0832输出各种波形

  [复制链接]
ID:102341 发表于 2019-1-28 14:31 | 显示全部楼层 |阅读模式
使用DAC0832作为信号发生器输出四种波形:方波、三角波、锯齿波、梯形波。
基本思路:
第一按钮选择波形:方波、三角波、锯齿波、梯形波;
第二按钮增加幅值;
第三个按钮减小幅值。仿真电路图:
51hei.gif

示波器效果如下:
方波:

方波.png
三角波:
三角波.png
锯齿波:
锯齿波.png
梯形波:
正弦波.png

主程序<chengxu.c>:
  1. #include "reg52.h"
  2. #include "init.h"        //DAC0832初始化
  3. #include "single.h" //DAC0832用到的函数
  4. #include "delay.h"        //延时
  5. #include "Key.h"        //按键

  6. #define uchar unsigned char
  7. #define uint  unsigned int

  8. int main(void)
  9. {
  10.     uchar Model=0;        //0-方波 1-三角波 2-锯齿波 3-梯形波
  11.     uint Count=0;        //计数器
  12.     uint Squ_Per=256;
  13.     uint Tri_Per=256;
  14.     uint Saw_Per=256;
  15.     uint Sin_Per=256;
  16.     init();
  17.     while(1)
  18.     {
  19.         while(Model==0) //方波
  20.         {   
  21.             Square_wave(Squ_Per,&Count);
  22.             Count+=4;
  23.             Squ_Per=Key_Plus(Squ_Per);
  24.             Squ_Per=Key_Subc(Squ_Per);
  25.             Model=Key_Model(Model,&Squ_Per,&Count); //每次退出当前while时记得复原Period和Count的数据
  26.         }   
  27.         while(Model==1) //三角波
  28.         {
  29.             Triangle_wave(Tri_Per,&Count);
  30.             Count+=4;
  31.             Tri_Per=Key_Plus(Tri_Per);
  32.             Tri_Per=Key_Subc(Tri_Per);
  33.             Model=Key_Model(Model,&Tri_Per,&Count);
  34.         }
  35.         while(Model==2) //锯齿波
  36.         {
  37.             Sawtooth_wave(Saw_Per,&Count);
  38.             Count+=4;
  39.             Saw_Per=Key_Plus(Saw_Per);
  40.             Saw_Per=Key_Subc(Saw_Per);
  41.             Model=Key_Model(Model,&Saw_Per,&Count);
  42.         }
  43.         while(Model==3) //波
  44.         {
  45.             Sin_wave(Sin_Per,&Count);
  46.             Count+=4;
  47.             Sin_Per=Key_Plus(Sin_Per);
  48.             Sin_Per=Key_Subc(Sin_Per);
  49.             Model=Key_Model(Model,&Sin_Per,&Count);
  50.         }
  51.     }
  52.      return 0;
  53. }
复制代码
延时<delay.c>:
  1. void delay(unsigned int r)
  2. {
  3.         unsigned int i,j;
  4.         for(i=r;i>0;i--)
  5.         for(j=110;j>0;j--);
  6. }
复制代码
延时头文件<delay.h>:
  1. #ifndef __DELAY_H__
  2. #define __DELAY_H__

  3. #include <intrins.h>
  4. #define NOP() _nop_()

  5. void delay(unsigned int r);

  6. #endif
复制代码
芯片初始化<init.c>:

  1. #include "reg52.h"
  2. sbit CS_DAC=P1^5; //DAC0832的片选端口
  3. sbit WR_DAC=P1^6; //DAC0832的数据写入端口

  4. extern void init(void)
  5. {
  6.     P0=0xff;
  7.     P1=0xff;
  8.     P2=0xff;
  9.     P3=0xff;
  10.     CS_DAC=0;//一直片选中DAC0832,低电平有效啊~
  11.     WR_DAC=0;//一直写入数据到DAC0832
  12. }
复制代码
芯片初始化头文件<init.h>:
  1. #ifndef __INIT_H__
  2. #define __INIT_H__

  3. extern void init(void);

  4. #endif
复制代码
按键识别<key.c>:

  1. #include "reg52.h"
  2. #include "Key.h"
  3. #include "delay.h"

  4. sbit key1=P3^2;    //波形选择按键
  5. sbit key2=P3^3;    //幅值增加按键
  6. sbit key3=P3^4;    //幅值减少按键

  7. //波形选择
  8. unsigned char Key_Model(unsigned char Model,unsigned int *Pre,unsigned int *Count)
  9. {
  10.     if(key1==0)
  11.     {
  12.         delay(10);
  13.         if(key1==0)
  14.         {
  15.             Model=Model+1;
  16.             *Pre=256;
  17.             *Count=0;   
  18.         }
  19.     }
  20.     while(key1==0);
  21.     if(Model>3)
  22.     {
  23.         Model=0;
  24.     }
  25.     return Model;
  26. }
  27. //幅值增加
  28. unsigned int Key_Plus(unsigned int Per)
  29. {
  30.     if(key2==0)
  31.     {
  32.         delay(10);
  33.         if(key2==0)
  34.         {
  35.             Per=Per+8;   
  36.         }
  37.     }
  38.     while(key2==0);
  39.     if(Per>256)
  40.     {
  41.         Per=0;
  42.     }
  43.     return Per;        
  44. }
  45. //幅值减少
  46. unsigned int Key_Subc(unsigned int Per)
  47. {
  48.     if(key3==0)
  49.     {
  50.         delay(10);
  51.         if(key3==0)
  52.         {
  53.             Per=Per-8;   
  54.         }
  55.     }
  56.     while(key3==0);
  57.     if(Per<0)
  58.     {
  59.         Per=256;
  60.     }
  61.     return Per;        
  62. }
复制代码
按键识别头文件<key.h>:

  1. #ifndef __KEY_H__
  2. #define __KEY_H__

  3. unsigned char Key_Model(unsigned char Model,unsigned int *Pre,unsigned int *Count);
  4. unsigned int Key_Plus(unsigned int Per);
  5. unsigned int Key_Subc(unsigned int Per);

  6. #endif
复制代码
绘制波形函数<single.c>:

  1. #include "reg52.h"
  2. #include "single.h"
  3. #include "delay.h"
  4. #define DATA P0
  5. //方波
  6. void Square_wave(unsigned int Per,unsigned int *Count)
  7. {
  8.     if(*Count>=Per) *Count=0;
  9.     if(*Count<Per/2)
  10.     {
  11.         DATA=0x00;
  12.     }   
  13.     else
  14.     {
  15.         DATA=0xFF;
  16.     }
  17. }
  18. //三角波
  19. void Triangle_wave(unsigned int Per,unsigned int *Count)
  20. {
  21.     if(*Count>=Per) *Count=0;
  22.     if(*Count<Per/2)
  23.     {
  24.         DATA=*Count;
  25.     }   
  26.     else
  27.     {
  28.         DATA=Per-*Count;
  29.     }   
  30. }
  31. //锯齿波
  32. void Sawtooth_wave(unsigned int Per,unsigned int *Count)
  33. {
  34.     if(*Count>=Per) *Count=0;
  35.     if(*Count<Per)
  36.     {
  37.         DATA=*Count;
  38.     }        
  39. }
  40. //波
  41. void Sin_wave(unsigned int Per,unsigned int *Count)
  42. {
  43.     if(*Count>Per) *Count=0;
  44.     if(*Count<Per/2)
  45.     {
  46.         DATA=*Count;
  47.     }   
  48.     else if(*Count==Per/2)
  49.     {
  50.         delay(100);   
  51.     }
  52.     else if(*Count<Per)
  53.     {
  54.         DATA=Per-*Count;
  55.     }   
  56.     else if(*Count==Per)
  57.     {
  58.         delay(100);
  59.     }
  60. }
复制代码
绘制波形函数头文件<single.h>:
  1. #ifndef __SINGLE_H__
  2. #define __SINGLE_H__

  3. void Square_wave(unsigned int Per,unsigned int *Count);
  4. void Triangle_wave(unsigned int Per,unsigned int *Count);
  5. void Sawtooth_wave(unsigned int Per,unsigned int *Count);
  6. void Sin_wave(unsigned int Per,unsigned int *Count);

  7. #endif
复制代码

资料51hei下载地址(Proteus仿真+代码):
利用模数转换DAC0832输出各种波形.7z (578.99 KB, 下载次数: 357)

评分

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

查看全部评分

回复

使用道具 举报

ID:32289 发表于 2019-1-28 19:42 | 显示全部楼层
输出通到多少频率啊?
回复

使用道具 举报

ID:102341 发表于 2019-1-28 23:34 | 显示全部楼层
rrqxx 发表于 2019-1-28 19:42
输出通到多少频率啊?

51芯片+12M晶振,CPU位1us,定时器描点256个,每个20us,全部跑完5120us,频率最大1/(5120/1000000)=195.3125Hz,从虚拟示波器格子也可大约估算出来都没超过100Hz。
回复

使用道具 举报

ID:540111 发表于 2019-5-20 18:26 | 显示全部楼层
请问这个这个可以加12864吗/怎么加啊/
回复

使用道具 举报

ID:513931 发表于 2019-6-25 21:33 | 显示全部楼层
请问这个可以同时输出两个不同的波形吗?
回复

使用道具 举报

ID:139165 发表于 2020-5-7 07:34 | 显示全部楼层
厉害了,学习学习
回复

使用道具 举报

ID:516413 发表于 2020-5-22 11:09 | 显示全部楼层
这个厉害
回复

使用道具 举报

ID:889256 发表于 2021-3-14 16:35 | 显示全部楼层
波形是从哪个口输出的呀
回复

使用道具 举报

ID:918224 发表于 2021-5-9 20:02 | 显示全部楼层
单片机频率能改吗
回复

使用道具 举报

ID:928166 发表于 2021-5-27 22:34 | 显示全部楼层
请教大神们,如何设计一个dac输出可控电压范围0~10v,分辨率为0.1v嘛? 谢谢!
回复

使用道具 举报

ID:918467 发表于 2021-10-11 21:16 | 显示全部楼层
wxkn937 发表于 2019-5-20 18:26
请问这个这个可以加12864吗/怎么加啊/

我也在做这个,我已经用555产生波形了,但是不知道怎么用12864显示,请问你现在解决了吗,可以帮我一下吗,谢谢啦
回复

使用道具 举报

ID:971889 发表于 2021-10-24 08:36 来自手机 | 显示全部楼层
周期为多少?
回复

使用道具 举报

ID:971889 发表于 2021-10-24 08:44 来自手机 | 显示全部楼层
周期为多少?
回复

使用道具 举报

ID:828888 发表于 2022-4-20 13:27 | 显示全部楼层
程序要用Keil2打开
仿真用Proteus7.5或者8.8版本才行
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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