初学单片机,.附件是对程序的分析和proteus仿真,适合初学搭建电路,按键1,2程序功能有问题,不知道那步的逻辑出现了问题,没有实现频率微调的功能.
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
Proteus仿真中ANOLOGUE示波器使用简述: 第一次运行示波器会自动打开,在关闭示波器也就是叉了之后,再次运行不会自动打开,需右击示波器选择最下面英文选项. 连接四个扫描口中的一个,对应有四个channal,旋钮调节扫描电压值以改变格子代表单位,,指向为一格所代表的电压值,例如指向2mv,则上下一格代表2mv.滚轮移动上下坐标,可调节使其对其某根线便于测量. Horizontal旋钮横向扫描周期调节,可用于调节周期波形宽度,横向滚轮调节水平坐标.小旋扭都为微调. 
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改变值,然后打开中断.
单片机源程序如下:
- #include<reg51.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit s1=P3^5;
- sbit s2=P3^6;
- sbit s3=P3^7;
- sbit s4=P3^4;
- int pinlv=100,bujin=1;
- unsigned int m;
- char boxing,u;
- int a,b;
- uchar code sin[64]={
- 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,
- 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
- }; //正弦波取码
- uchar code juxing[64]={
- 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,
- 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
- }; //矩形波取码
- uchar code sanjiao[64]={
- 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,
- 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
- }; //三角波取码
- uchar code juchi[64]={
- 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,
- 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
- }; //锯齿波取码
- void initclock()
- {
- TMOD=0x01;
- TH0=a ;
- TL0=b ;
- EA=1;
- ET0=1;
- TR0=1;
- }
-
- void delay(uint xms)
- {
- int c,d;
- for (c=xms;c>0;c--)
- for(d=110;d>0;d--);
- }
- 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;
- }
- }
- }
-
- void main()
- {
- m=65536-(150000/pinlv);
- a=m/256;
- b=m%256;
- initclock();
- while(1)
- {
- keyscan();
-
- switch(boxing)
- {
- case 0 : P1=sin[u]; break;
- case 1 : P1=juxing[u]; break;
- case 2 : P1=sanjiao[u]; break;
- case 3 : P1=juchi[u]; break;
- }
- }
- }
-
- void T0_time()interrupt 1
- {
- TH0= a ;
- TL0= b ;
- u++;
- if(u>=64)
- u=0;
- }
复制代码
所有资料51hei提供下载:
波形发生器.rar
(334.09 KB, 下载次数: 144)
|