1、河南理工大学河南理工大学微机原理与单片机接口技术课程设计报告2012 年 01 月 15 日摘要本设计是本设计是通过软件对键盘输入的频率数值进行处理,处理结果送与 D/A 转换部分实现数/模转换,输出的电流再经过电流/电压转换环节,进而形成模拟电压波形,最后经过过载保护电路输出。信号发生器是一种常用的信号源,广泛地应用于电子电路、自动控制系统和教学实验等领域。目前使用的信号发生器大部分是利用分立元件组成的体积大,可靠性差,准确度低。课程设计需要各个波形的基本输出,这些波形的实现的具体步骤:方波的产生过程是通过定时器产生一个方波半周期的定时信号,每到这个信号产生,就改变一次 D/A 输出的数据,
2、这两个数据值由事先给定的峰峰值计算出,方波的实现是比较简单的。而三角波,则每次累加 1,当达到峰值时,则改为每次累减 1,这个过程需要根据峰峰值算出增加及减小的步数,以及根据频率算出步进间隔,由此间隔算出定时器重装值,以精确定时。锯齿波的产生与三角波类似,但相对简单,同样要算出步数及步进时间间隔,产生精确定时信号,不同的是锯齿波从谷值增加至峰值只是单一方向的增长。该设计使用的是 STC 单片机构成的发生器,可产生三角波、方波、正弦波等多种波形,波形的频率可用程序控制改变。在单片机上加外围器件独立式开关,通过开关控制波形的选择。在单片机的输出端口接 DAC0832 进行 DA 转换,再通过运放进
3、行波形调整,最后输出波形接在示波器上显示. 同时在数码管内显示该频率数值。波形的切换可以通过按键直接实现。关键词:信号发生器 单片机 三角波 锯齿波 方波目录1 概述 41.1 系统框图 41.2 基本要求 .41.3 主要设计思想 .42 系统总体方案及硬件设计 52.1 芯片功能介绍 .53 软件设计 63.1、方波的实现过程 63.2、锯齿波实现过程 63.3、三角波的实现过程 64 Proteus 软件仿真 65 课程设计体会 76 参考文献 8附 1 源程序代码 .8附 2 系统原理图 .281 概述1.1 系统框图1.2 基本要求(1)具有产生方波、锯齿波、三角波三种周期性波形的功
4、能。(2)输出波形的频率范围为 100Hz1kHz;频率步进间隔100Hz。(3)输出波形幅度范围 05V,可按步进 0.1V(峰-峰值)调整。(4)具有显示输出波形的类型、周期和幅度的功能。1.3 主要设计思想(一)、课设需要各个波形的基本输出。如输出三角波、锯齿波、方波。这些波形的实现的具体步骤:方波的产生过程是通过定时器产生一个方波半周期的定时信号,每到这个信号产生,就改变一次 D/A 输出的数据,这两个数据值由事先给定的峰峰值计算出,方波的实现是比较简单的。而三角波,则每次累加1,当达到峰值时,则改为每次累减 1,这个过程需要根据峰峰值算出增加及减小的步数,以及根据频率算出步进间隔,由
5、此间隔算出定时器重装值,以精确定时。锯齿波的产生与三角波类似,但相对简单,同样要算出步数及步进时间间隔,产生精确定时信号,不同的是锯齿波从谷值增加至峰值只是单一方向的增长。(二)、整个程序的设计思想是按照精确产生波形优先的原则,能够简单的设置及显示波形类型,幅值,频率等参数。将波形输出的控制放入定时器中断里执行,在程序里执行的优先级最高,在主程序里有按键扫描,数码管扫描及相关参数修改等内容。这样的程序结构使整个信号发生器能够很好的工作。2 系统总体方案及硬件设计2.1 芯片功能介绍(1)DAC0832 芯片介绍DAC0832 为一个 8 位 D/A 转换器,单电源供电,在+5+15V 范围内均
6、可正常工作。基准电压的范围为10V,电流建立时间为 1s,CMOS 工艺,低功耗 20mW。DAC0832 的内部结构框图如下图所示DI0DI7:数据输入线,TLL 电平。 ILE:数据锁存允许控制信号输入线,高电平有效。 CS:片选信号输入线,低电平有效。 WR1:为输入寄存器的写选通信号。 XFER:数据传送控制信号输入线,低电平有效。 WR2:为 DAC 寄存器写选通输入线。 Iout1:电流输出线。当输入全为 1 时 Iout1 最大。 Iout2: 电流输出线。其值与 Iout1 之和为一常数。 Rfb:反馈信号输入线,芯片内部有反馈电阻.(2)、DAC0832 的应用:DAC083
7、2 一是用作单极性电压输出,二是用作双极性电压输出,最后是用作程控放大器。(3)、DAC0832 与 8031 的连接方式:DAC0832 的与单片机的连接方式有三种方式:一、单缓冲二、双缓冲、三是直通方式。本程序采用的是方式一即单缓冲方式,ILE 为高电平,CS、WR1、WR2、XFER 为低电平。3 软件设计3.1、方波的实现过程方波的产生过程是通过定时器产生一个方波半周期的定时信号,每到这个信号产生,就改变一次 D/A 输出的数据,这两个数据值由事先给定的峰峰值计算出。3.2、锯齿波实现过程锯齿波产生的过程是,通过事先给定的峰峰值以及 D/A 数据每增加 1 所增加的电压值算出产生这个变
8、化范围的电压所需要增加的步数,然后以锯齿波的周期除以这个步数,算出相邻两步之间的时间间隔,用该时间间隔计算出定时器的重装值以产生定时信号。再者利用前述步数计算出 D/A 数据上限及下限值,当D/A 数据每步自增 1 后增加至上限值时就回到下限值继续自增,依此产生一个锯齿波。3.3、三角波的实现过程三角波产生的过程是,通过事先给定的峰峰值以及 D/A 数据每增加 1 所增加的电压值算出产生这个变化范围的电压所需要增加的步数,然后以锯齿波的周期的一半除以这个步数,算出相邻两步之间的时间间隔,用该时间间隔计算出定时器的重装值以产生定时信号。再者利用前述步数计算出 D/A 数据上限及下限值,当 D/A
9、 数据每步自增 1 后增加至上限值时变数据自增为数据自减,当减至下限值时,再次改变为自增,由此产生一个三角波。4 Proteus 软件仿真方波 protues 仿真锯齿波 protues 仿真三角波 protues 仿真5 课程设计体会本次课程设计让我们熟悉了从硬件设计及调试,软件编写及调试及软硬件联合调试的全过程,也熟悉了单片机系统开发的一般过程。从中我们明白了细节决定成败的问题,在这段时间里,我们不断的碰到问题,比如说 protues 不能仿真,硬件电路焊接问题,焊好了不能用的问题,以及许许多多的问题,在不断解决问题的同时我们明白,每一个细节都能可能会导致设计不成功。在这段时间里我们分工合
10、作明确,遇到问题一块讨论解决,不懂的同学间相互讨论解决或是查阅资料,最终我们取得不错的成果,学到了很多以前自己没有学到的知识,收获很多。在设计过程中我们明白分工在设计中的重要作用,分工明确,可以加快时间效率,更有效的解决问题,如果让一个热人同时做很多工作,可能会有很多疏漏,时间效率也比较低。我们俩个都很感谢对方,从对方那里学习到了许多。6 参考文献1川李勋、刘源主编.单片机实用教程.北京:北京航空航天大学出版社,2000.2李珍付、植桐主编.单片机原理与应用技术.北京:清华大学出版社,2003.3李朝清主编.单片机原理及接口技术.北京:北京航空航天大学出版社,1999.4谭浩强主编 C 程序设
11、计.北京:清华大学出版社,2007.附 1 源程序代码#include#define uint unsigned int #define uchar unsigned char#define MAIN_FOSC 11.0592#define DIV (5.0/128)uchar code table=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF; /数码管编码sbit l1=P05; /按键行列定义sbit l2=P06;sbit l3=P0
12、7;sbit h1=P36;sbit h2=P37;sbit cs=P44;sbit wr=P45;uchar frq; /频率uchar vpp; /峰峰值uchar v_h,v_l; /正负向的峰值uchar step,step_z,step_f,t_step,add_step; /步数,正向步数,负向步数,时间间隔,增值间隔uchar dac_dat; /转换数据uchar timer0_load; /定时器重装值uchar key_value;uchar out_type; /输出波形uchar count;bit up; /三角波增长方向变量bit change;bit key_fl
13、ag;void type_set();void amp_set();void frq_set();void tri_init();void saw_init();void squ_init();void dis(uchar,uchar);void dis1(uchar,uchar);void delay(uint);void key_scan();bit key_up();void main()uint time_count=0; /数码管交替显示控制P4SW|=0X70;P1M1=0;P1M0=0XFF;TMOD=0X02;ET0=1;EA=1; /定时器 0 中断初始化cs=1;wr=1;
14、cs=0;wr=0; /0832 初始化dac_dat=0x80;P2=dac_dat;key_value=0;out_type=1;count=0;up=1;change=1;frq=10; vpp=60; /变量初始化while(1)/按键扫描设置/h1=0;l1=l2=l3=1;if(!l1)delay(10);if(!l1) type_set();while(!l1);if(!l2)delay(10);if(!l2) amp_set();while(!l2);if(!l3)delay(10);if(!l3) frq_set();while(!l2);h1=l1=l2=l3=1;/数码管
15、扫描显示,频率、幅值交替/time_count+;if(time_countv_h)up=up;dac_dat-;dac_dat-;elseP2=dac_dat;dac_dat-;if(dac_datv_h)dac_dat=v_l;else if(out_type=3)count+;if(count=t_step) count=0;up=up;if(up) P2=v_h;else P2=v_l;/*三角波输出参数初始化*/void tri_init()step=(uchar)(vpp/(10*DIV)+0.5); /四舍五入求步数if(step%2=0) step_z=step_f=step/
16、2;else if(step%2!=0) step_z=(step-1)/2;step_f=(step+1)/2;v_h=128+step_z; v_l=128-step_f; t_step=(uchar)(100000.0/(frq*2*step)+0.5); /每步间隔,单位微秒timer0_load=(256-(uchar)(t_step*MAIN_FOSC/12+0.5);TH0=timer0_load;TL0=timer0_load;/*锯齿波输出参数初始化*/void saw_init()step=(uchar)(vpp/(10*DIV)+0.5); /四舍五入求步数if(step
17、%2=0) step_z=step_f=step/2;else if(step%2!=0) step_z=(step-1)/2;step_f=(step+1)/2;v_h=128+step_z; v_l=128-step_f; t_step=(uchar)(100000.0/(frq*step)+0.5); /计数变量timer0_load=(256-(uchar)(t_step*MAIN_FOSC/12+0.5);TH0=timer0_load;TL0=timer0_load;/*方波输出参数初始化*/void squ_init()step=(uchar)(vpp/(10*DIV)+0.5)
18、; /四舍五入求步数if(step%2=0) step_z=step_f=step/2;else if(step%2!=0) step_z=(step-1)/2;step_f=(step+1)/2;v_h=128+step_z; v_l=128-step_f; t_step=(uchar)(100000.0/(frq*2)/50)+0.5); /每步间隔,单位微秒count=0; timer0_load=(256-(uchar)(50*MAIN_FOSC/12+0.5); /定时 50 微秒TH0=timer0_load;TL0=timer0_load;/*波形设置*/void type_se
19、t()change=1;key_value=0;while(key_value!=6)if(!key_flag) key_flag=key_up(); /按键未弹起时需检测弹起if(key_flag) key_scan();if(key_value=4)key_flag=0; /前次按键弹起后才能再次扫描按键if(key_value=4)out_type+;if(out_type=4) out_type=1;key_value=0;dis(out_type,1);delay(1);key_value=0;/*幅度设置*/void amp_set()bit set=1;change=1;key_
20、value=0;while(key_value!=6)if(!key_flag) key_flag=key_up(); /按键未弹起时需检测弹起if(key_flag) key_scan();if(key_value!=0)key_flag=0; /前次按键弹起后才能再次扫描按键if(key_value=2) set=set;key_value=0;else if(set)if(key_value=4)vpp+=10;if(vpp99) vpp=(90+vpp%10);key_value=0;if(key_value=5)vpp-=10;if(vpp99) vpp=2;key_value=0;
21、else if(key_value!=6) key_value=0;if(!set)if(key_value=4)vpp=(vpp/10*10)+(vpp%10)+1)%10;key_value=0;if(key_value=5)vpp=(vpp/10*10)+(vpp%10)-1)%10;key_value=0;else if(key_value!=6) key_value=0;dis1(vpp/10,1);delay(1);dis(vpp%10,2);delay(1);key_value=0;/*频率设置*/void frq_set()change=1;key_value=0;while(
22、key_value!=6)if(!key_flag) key_flag=key_up(); /按键未弹起时需检测弹起if(key_flag) key_scan();if(key_value!=0)key_flag=0; /前次按键弹起后才能再次扫描按键if(key_value=4)frq=frq+10;key_value=0;if(frq100) frq=100;else if(key_value=5)frq=frq-10;key_value=0;if(frq=0) frq=10;else if(key_value!=6)key_value=0;dis(0,4);delay(1);dis(0,
23、3);delay(1);dis(frq/10%10,2);delay(1);if(frq/100) dis(1,1);delay(1);key_value=0;/*键盘扫描函数(不等待按键弹起)*/void key_scan(void)h1=1;h2=1;l1=0;l2=0;l3=0;if(h1=0)delay(8);if(h1=0)l1=0;l2=1;l3=1;if(h1=0) key_value=1;l1=1;l2=0;l3=1;if(h1=0) key_value=2;l1=1;l2=1;l3=0;if(h1=0) key_value=3;else if(h2=0)delay(8);if
24、(h2=0)l1=0;l2=1;l3=1;if(h2=0) key_value=4;l1=1;l2=0;l3=1;if(h2=0) key_value=5;l1=1;l2=1;l3=0;if(h2=0) key_value=6;/*按键弹起检测*/bit key_up(void)bit k_up=0;h1=1;h2=1;l1=0;l2=0;l3=0;if(h1=1return k_up;/*1T 单片机延时毫秒程序参数:i延时毫秒数*/void delay(uint i)uint j,k;for(j=i;j0;j-)for(k=850;k0;k-);/*共阴数码管显示程序参数:r显示的数字c第几位数码管*/void dis(uchar r,uchar c)P0=(0x01(c-1);P1=tabler;/*共阴数码管显示程序(带小数点)参数:r显示的数字c第几位数码管*/void dis1(uchar r,uchar c)P0=(0x01(c-1);P1=tabler+10;附 2 系统原理图