如题,内容包括protuce仿真及源程序两部分
一、 作品简介:可以通过按键控制STC89C52单片机输出[url=]不同波形[/url][z1] 信号。通过usb给pcb板通5v的电压可以发出方波,三角波,锯齿波,正弦波并在LCD显示屏上显示波形类别,频率和幅值。通过按键可调波形类别,可调节频率步进值有1Hz,10Hz和50Hz。最低频率为10Hz最高频率为800Hz。
二、设计原理:将各种波形的每个周期平均分成255份,把每份的值依次发给P0口,每份的时间间隔通过开启定时器0来控制,当定时时间到时单片机就产生中断,在中断服务程序里面通过P0口将每份的值发出去,这个值通过向D/A换器的输入端按一定的规律发生数据,从而在转换电路的输出端得到相应的电压波形。
三、 功能说明:能够产生方波、锯齿波、三角波、正弦波信号的波形发生器
(1) 按键选择波形。按键控制单片机输出方波、锯齿波、三角波或者正弦波信号。按键K1,K2,K3,K4改变波形类型,K5,K6控制频率的加减。
(2) 波形参数显示。通过液晶屏显示单片机当前输出波形的频率、幅度。
(3) 频率调节。通过外部按键,调节单片机输出波形信号的频率。
单片机源程序如下:
- /****************************************************************************************************************/
- /* 简易波形发生器 程序 */
- /* 编写者 :FHX */
- /* 可输出 正弦波 三角波 方波 按键控制波形、频率、步进值 */
- /* 由于是单片机定时器控制频率 经测试频率只能在10HZ ~ 700HZ 之间 */
- /* 有掉电储存功能 再次上电时 显示掉电前设置好的波形 频率 步进值 */
- /****************************************************************************************************************/
- #include "lcd12864.h"
- #include "key.h"
- #include "24c02.h"
- #include "function.h"
- uchar T1RH = 0; //定时器1重载值高位
- uchar T1RL = 0; //定时器1重载值低位
- uchar T0RH = 0; //定时器0重载值高位
- uchar T0RL = 0; //定时器0重载值低位
- uchar mode = 0;
- sbit led=P2^4;
- sbit led1=P2^7;
- extern uchar Wave_Index; //声明 波形变量
- uchar code sin[32]={ //此数组内的数据为,DA输出对应电压值对应的数字量,0是0V,255是5V
- 127, 152, 176, 198, 217, 233, 245, 252,
- 255, 252, 245, 233, 217, 198, 176, 152,
- 127, 102, 78, 56, 37, 21, 9, 2,
- 0, 2, 9, 21, 37, 56, 78, 102
- }; //正弦波取码
- uchar code juxing[32]={ //一个周期是采样32个点, 所以数组内是32个数据
- 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
- }; //矩形波取码
- uchar code sanjiao[32]={
- 0, 16, 32, 48, 64, 80, 96, 112,
- 128, 144, 160, 176, 192, 208, 224, 240,
- 255, 240, 224, 208, 192, 176, 160, 144,
- 128, 112, 96, 80, 64, 48, 32, 16
- }; //三角波取码
- uchar code jvchi[32]={
- 0, 16, 32, 48, 64, 80, 96, 112,
- 128, 144, 160, 176, 192, 208, 224, 240,
- 255, 0, 16, 32, 48, 64, 80, 96, 112,
- 128, 144, 160, 176, 192, 208, 224
- }; //锯齿波取码
- /*****************子函数声明*****************/
- void Timer1Init(uint ms);
- void SetWaveRate(uint num_2);
- void Control_Key();
- void Refresh_Out();
- /*****************************************************************************/
- /* 主函数 */
- /*****************************************************************************/
- void main()
- { led=1;
- led1=1;
- Timer1Init(1); //初始化定时器1 定时1ms
- LcdInit(); //初始化12864
- Init_Display(); //显示固定内容
- Init_OutPut(); //初始化输出数据和显示
- while(1)
- {
- Refresh_Out(); //更新输出 mode=0:输出波形 独立按键关闭 mode!=0 :关闭波形输出 可用独立按键调整
- Control_Key(); //控制独立按键 调整模式mode
- KeyDrive(); //调整波形、频率及步进值
- }
- }
- /*****************************************************************************/
- /* 按键控制函数 */
- /* 按键KEY_1 :用延时函数判断按下 控制模式变换 */
- /*****************************************************************************/
- void Control_Key()
- {
- if(KEY_1==0) //按下按键1 mode+1
- {
- DelayMs(2);
- if(KEY_1==0)
- {
- while(!KEY_1);
- mode++;
- if(mode > 3)mode = 1;
- }
- }
- }
- /*****************************************************************************/
- /* 更新输出函数 */
- /* 根据不同的模式变量 打开或关闭波形输出 */
- /*****************************************************************************/
- void Refresh_Out()
- {
- if(mode == 0) //不显示箭头 输出波形 独立按键关闭
- {
- ET1=0;
- TR1=0;
- ET0=1;
- TR0=1;
- EA=1;
- Display_Arr(0);
- }
-
- else if(mode == 1) //箭头指向 "波形" 说明是在切换波形
- {
- ET1=1;
- TR1=1;
- ET0=0;
- TR0=0;
- EA=1;
- Display_Arr(1);
- }
-
- else if(mode == 2) //箭头指向 "频率" 说明是在加减频率
- {
- ET1=1;
- TR1=1;
- ET0=0;
- TR0=0;
- EA=1;
- Display_Arr(2);
- }
-
- else if(mode == 3) //箭头指向 "步进值" 说明在加减步进值
- {
- ET1=1;
- TR1=1;
- ET0=0;
- TR0=0;
- EA=1;
- Display_Arr(3);
- }
- }
- /*****************************************************************************/
- /* 按键动作函数 */
- /* 按键 KEY_2 ~ KEY_4 三个按键由定时器1中断扫描 有长按功能 */
- /*****************************************************************************/
- void KeyDown(uchar keycode)
- {
- /*********************************/
- /* "+"键 */
- /*********************************/
- if(keycode == 0x26)
- {
- if(mode == 1) //模式1 向右切换波形
- {
- Convert_Wave(1);
- }
-
- else if(mode == 2) //模式2 增加频率
- {
- Change_Rate(1);
- }
-
- else if(mode == 3) //模式3 增加步进值
- {
- Change_Step(1);
- }
- }
- /*********************************/
- /* "-"键 */
- /*********************************/
- else if(keycode == 0x28)
- {
- if(mode == 1) //模式1 向左切换波形
- {
- Convert_Wave(0);
- }
-
- else if(mode == 2) //模式2 减小频率
- {
- Change_Rate(0);
- }
-
- else if(mode == 3) //模式3 减小步进值
- {
- Change_Step(0);
- }
- }
- /*********************************/
- /* 模式清零键 */
- /*********************************/
- else if(keycode == 0x0D)
- {
- mode = 0;
- }
- }
- /**********频率设置函数****************/
- /************定时器0控制***************/
- void SetWaveRate(uint num_2)
- {
- ulong tmp;
- tmp=(12000000/12)/(num_2*32); //定时器计数频率 是波形频率的32倍
- tmp=65536-tmp; //计算定时器重载值
- tmp=tmp+18; //补偿
- T0RH=(uchar)(tmp>>8);
- T0RL=(uchar)tmp;
- TMOD&=0xF0;
- TMOD|=0x01;
- TH0=T0RH;
- TL0=T0RL;
- }
- /**********定时器1初始化函数***********/
- /**********用于三个独立按键扫描********/
- void Timer1Init(uint ms)
- {
- ulong tmp; //16位长整型变量tmp
- tmp=12000000/12; //用晶振频率除以12得到定时器计数频率
- tmp=(tmp*ms)/1000; //计算出需要多少个机器周期
- tmp=65536-tmp; //定时器的重载值
- tmp=tmp+28; //补偿中断延时响应造成的误差
- T1RH=(uchar)(tmp>>8); //将tmp高8位右移8位 赋值给T1RH
- T1RL=(uchar)tmp; //将tmp低8位赋值给T0RL
- TMOD&=0x0F; //清零T1控制位
- TMOD|=0x10; //选择模式1
- }
- /**********定时器0中断函数**********/
- /*******输出相应频率的波形数据******/
- void InterruptTimer0() interrupt 1
- {
- static uchar cnt; //变量 用于输出波形采样点
- TH0=T0RH;
- TL0=T0RL;
- switch(Wave_Index)
- {
- case 0:DAC_OUT=sin[cnt];break;
- case 1:DAC_OUT=sanjiao[cnt];break;
- case 2:DAC_OUT=juxing[cnt];break;
- }
- cnt++;
- if(cnt>=32)cnt=0;
- }
- void InterruptTimer1() interrupt 3
- {
- TH1=T1RH; //重载初值
- TL1=T1RL;
- KeyScan(); //按键扫描
- }
复制代码
所有资料51hei提供下载:
仿真及程序.rar
(98.29 KB, 下载次数: 214)
程序代码.rar
(100.73 KB, 下载次数: 128)
|