找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5931|回复: 7
收起左侧

51单片机DAC0832波形发生器仿真加程序源码

  [复制链接]
ID:377946 发表于 2018-8-5 11:10 | 显示全部楼层 |阅读模式
初学单片机,.附件是对程序的分析和proteus仿真,适合初学搭建电路,按键1,2程序功能有问题,不知道那步的逻辑出现了问题,没有实现频率微调的功能.

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

Proteus仿真中ANOLOGUE示波器使用简述:

第一次运行示波器会自动打开,在关闭示波器也就是叉了之后,再次运行不会自动打开,需右击示波器选择最下面英文选项.

连接四个扫描口中的一个,对应有四个channal,旋钮调节扫描电压值以改变格子代表单位,,指向为一格所代表的电压值,例如指向2mv,则上下一格代表2mv.滚轮移动上下坐标,可调节使其对其某根线便于测量.

Horizontal旋钮横向扫描周期调节,可用于调节周期波形宽度,横向滚轮调节水平坐标.小旋扭都为微调.



0.png

Proteus仿真

原件:res电阻

  89c51

  DAC0832

  LM358N

  BUTTON

                              GENELECT10U16V



主函数:

void main()

{

              m=65536-(150000/pinlv);           //

              a=m/256;

              b=m%256;

              initclock();

              while(1)

              {

                            if(h==0)

                            {

                                          keyscan();

                            }




              switch(boxing)

                            {

                                          case 0 : P1=sin; break;

                                          case 1 : P1=juxing; break;

                                          case 2 : P1=sanjiao; break;

                                          case 3 : P1=juchi; break;

                            }

              }

}


主函数:

首先给m,a,b赋初值,调用initclock(),initclock

void initclock()

{

              TMOD=0x01;

              TH0=a ;

              TL0=b ;

              EA=1;

              ET0=1;

              TR0=1;

}


定时器方式寄存器TMOD:

TMOD用于写入方式控制字,,以选择定时/计数器的工作状态及控制方式;共八位,高四位与低四位相同,分别是GATE   C/T   M1   M0,高四位控制T1,低四位控制T0.

M1M0用于指定工作方式,通过00 01 10 11的组合,可使定时/计数器分别对应工作在0 1 2 3方式

C/T:选择定时/计数.C,T分别表示计数器和定时器.当C/T=1时,选择计数状态,当C/T=0时选择定时状态

TH0=  TL0=  计数器0的高八位和第八位,组合以放更大的数字,加一计数直至计数器满溢出,这时打开EA(EA=1)开启中断总开关,打开ET0开启计数器一中断开关,TR0=1,开启定时器0开关


实参赋给Initclock()TH0,TL0,a=m/256;b=m%256;赋初值的意义是使计数器提前溢出从而启动中断

void T0_time()interrupt 1

{

              TH0= a ;

              TL0= b ;

              u++;

              if(u>=64)

                            u=0;

}

之后执行循环

while(1)

              {              

              keyscan();


              switch(boxing)

                            {

                                          case 0 : P1=sin; break;

                                          case 1 : P1=juxing; break;

                                          case 2 : P1=sanjiao; break;

                                          case 3 : P1=juchi; break;

                            }

              }

}

循环体首先调用函数按键检测函数keyscan()

void keyscan()

{

              if(s1==0)

              {

                            EA=0;

                            delay(2);

                            if(s1==0)

                            {

                                          while(!s1);

                                          pinlv+=bujin;

                                          if(pinlv>1000)

                                          {

                                                        pinlv=100;

                                          }

                                          m=65536-(150000 / pinlv);

                                          a=m / 256;

                                          b=m % 256;

                                          EA=1;

                            }

              }

              if(s2==0)

              {

                                          delay(5);

                                          if(s2==0)

                                          {

                                                        EA=0;

                                                        while(!s2);

                                                        pinlv-=bujin;

                                                        if(pinlv<100)

                                                        {

                                                                      pinlv=1000;

                                                        }

                                                        m=65536-(150000/pinlv);

                                                        a=m/256;

                                                        b=m%256;

                                                        EA=1;

                                          }

              }

              if(s3==0)

              {

                            delay(5);

                            if(s3==0)

                            {

                                          EA=0;

                                          while(!s3);

                                          boxing++;

                                          if(boxing>=4)

                                          {

                                                        boxing=0;

                                          }


                                          EA=1;

                            }

              }

}

S3是波形变换按键,首先关闭总中断执行下方语句,按钮按下判断,当

S3=0即按钮按下,while(!s3);  语句代表按键按下时,进行死循环不执行下方语句,松开按键后boxing++是波形变换关键,通过变boxing的值,赋给switch()语句选择波形

              switch(boxing)

                            {

                                          case 0 : P1=sin; break;

                                          case 1 : P1=juxing; break;

                                          case 2 : P1=sanjiao; break;

                                          case 3 : P1=juchi; break;

                            }

Sin[] juxing[] sanjiao[] juchi[] 为四个数组,通过赋值给P1并行IO口,传给DAC0832以VREF输出模拟信号,通过中断中的u++实现数组取数组元素的移动,实现信号的变换,在波形显示器上显示波形,然后打开中断执行变换后波形,

按键s1,s2执行波形频率的加减.同样关闭中断,pinglv+=bujin改变值,然后打开中断.


单片机源程序如下:


  1. #include<reg51.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int

  5. sbit s1=P3^5;
  6. sbit s2=P3^6;
  7. sbit s3=P3^7;
  8. sbit s4=P3^4;


  9. int pinlv=100,bujin=1;
  10. unsigned int m;
  11. char boxing,u;
  12. int a,b;
  13. uchar code sin[64]={                                                
  14. 135,145,158,167,176,188,199,209,218,226,234,240,245,249,252,254,254,253,251,247,243,237,230,222,213,204,193,182,170,158,
  15. 146,133,121,108,96,84,72,61,50,41,32,24,17,11,7,3,1,0,0,2,5,9,14,20,28,36,45,55,66,78,90,102,114,128
  16. };                                          //正弦波取码
  17. uchar code juxing[64]={
  18. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  19. 255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  20. };                                          //矩形波取码

  21. uchar code sanjiao[64]={
  22. 0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,
  23. 248,240,232,224,216,208,200,192,184,176,168,160,152,144,136,128,120,112,104,96,88,80,72,64,56,48,40,32,24,16,8,0
  24. };                                                //三角波取码
  25. uchar code juchi[64]={
  26. 0,4,8,12,16,20,24,28,32,36,40,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,130,134,138,142,
  27. 146,150,154,158,162,166,170,174,178,182,186,190,194,198,202,206,210,215,219,223,227,231,235,239,243,247,251,255
  28. };                                          //锯齿波取码


  29. void initclock()
  30. {
  31.         TMOD=0x01;
  32.         TH0=a ;
  33.         TL0=b ;
  34.         EA=1;
  35.         ET0=1;
  36.         TR0=1;
  37. }
  38.         
  39. void delay(uint xms)
  40. {
  41.         int c,d;
  42.         for (c=xms;c>0;c--)
  43.                 for(d=110;d>0;d--);
  44. }


  45. void keyscan()
  46. {
  47.         if(s1==0)
  48.         {
  49.                 EA=0;
  50.                 delay(2);
  51.                 if(s1==0)
  52.                 {
  53.                         while(!s1);
  54.                         pinlv+=bujin;
  55.                         if(pinlv>1000)
  56.                         {
  57.                                 pinlv=100;
  58.                         }
  59.                         m=65536-(150000 / pinlv);
  60.                         a=m / 256;
  61.                         b=m % 256;
  62.                         EA=1;
  63.                 }
  64.         }
  65.         if(s2==0)
  66.         {
  67.                         delay(5);
  68.                         if(s2==0)
  69.                         {
  70.                                 EA=0;
  71.                                 while(!s2);
  72.                                 pinlv-=bujin;
  73.                                 if(pinlv<100)
  74.                                 {
  75.                                         pinlv=1000;
  76.                                 }
  77.                                 m=65536-(150000/pinlv);
  78.                                 a=m/256;
  79.                                 b=m%256;
  80.                                 EA=1;
  81.                         }
  82.         }
  83.         if(s3==0)
  84.         {
  85.                 delay(5);
  86.                 if(s3==0)
  87.                 {
  88.                         EA=0;
  89.                         while(!s3);
  90.                         boxing++;
  91.                         if(boxing>=4)
  92.                         {
  93.                                 boxing=0;
  94.                         }
  95.                
  96.                         EA=1;
  97.                 }
  98.         }
  99. }

  100.                                    

  101. void main()
  102. {
  103.         m=65536-(150000/pinlv);
  104.         a=m/256;
  105.         b=m%256;
  106.         initclock();
  107.    while(1)
  108.         {         
  109.          keyscan();
  110.          
  111.         switch(boxing)
  112.                 {
  113.                         case 0 : P1=sin[u]; break;
  114.                         case 1 : P1=juxing[u]; break;
  115.                         case 2 : P1=sanjiao[u]; break;
  116.                         case 3 : P1=juchi[u]; break;
  117.                 }
  118.         }
  119. }
  120.         
  121. void T0_time()interrupt 1
  122. {
  123.         TH0= a ;
  124.         TL0= b ;
  125.         u++;
  126.         if(u>=64)
  127.                 u=0;
  128. }
复制代码
0.png

所有资料51hei提供下载:

波形发生器.rar (334.09 KB, 下载次数: 144)

评分

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

查看全部评分

回复

使用道具 举报

ID:418900 发表于 2018-11-1 17:56 | 显示全部楼层
下载的压缩文件为什么损坏?
回复

使用道具 举报

ID:283491 发表于 2018-11-13 15:43 | 显示全部楼层
其实加运算放大器有什么用,DA转换不可以直接输出波形吗?
回复

使用道具 举报

ID:396689 发表于 2018-11-22 10:17 | 显示全部楼层
文件不适用
回复

使用道具 举报

ID:241454 发表于 2018-11-25 10:32 | 显示全部楼层
不错不错
回复

使用道具 举报

ID:451464 发表于 2018-12-21 12:44 来自手机 | 显示全部楼层
你好,请问DA0832输出端后面的2电容电阻什么作用
回复

使用道具 举报

ID:417927 发表于 2018-12-29 10:49 | 显示全部楼层
非常有用的资料!!
回复

使用道具 举报

ID:514789 发表于 2019-4-17 17:28 | 显示全部楼层
用STM32可以吗 这是什么原理啊~波形怎么产生的
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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