4通道方波发生器
2015-05-04 16:44
127 查看
用51单片机设计一个四通道脉冲发生器,要求每个方波频率、占空比、振幅可单独调节。
这里采用的方法是用定时器产生一个基础方波,在基础方波的基础上叠加方波上升沿下降沿从而实现频率可调。
不足之处:因为采用的是51单片机,方波的频率不会特别高。代码如下:
这里采用的方法是用定时器产生一个基础方波,在基础方波的基础上叠加方波上升沿下降沿从而实现频率可调。
不足之处:因为采用的是51单片机,方波的频率不会特别高。代码如下:
#include "reg52.h" #include "absacc.h" #include "stdio.h" #include "math.h" #include "intrins.h" #define uchar unsigned char #define unint unsigned int /******************************/ sbit key0=P3^0; sbit key1=P3^1; sbit led2=P3^7; sbit led1=P3^6; /***********************************************************************/ //led数码管显示变量定义 /************************************************************************/ uchar digit; //字位 uchar wordbuf[8]; //字型码缓冲区 bit showflag; //数码管显示与否标志 /**************************************************/ //脉冲产生变量定义 /**************************************************/ sbit PWM_1 = P1^1; sbit PWM_2 = P1^2; sbit PWM_3 = P1^2; sbit PWM_4 = P1^2; sbit PWM_out1 = P3^2; sbit PWM_out2 = P3^3; sbit PWM_out3 = P3^4; sbit PWM_out4 = P3^5; int PWM_cnt1=0; int PWM_cnt2=0; int PWM_cnt3=0; int PWM_cnt4=0; int PWM_cnt=0; unint N; long out2_cnt=0,out4_cnt=0; unint cnt=1; bit ji_ou_0=0; bit ji_ou_1=0; bit ji_ou=0; bit PWM_flag0=0; bit PWM_flag1=0; bit PWM_flag=0; bit PWM_flag_=0; int Zkb1=5,Zkb2=5,Delay1=5,Delay2=5; int PWM_speed_l=1,PWM_speed_r=1; int Timer0_val_h=0,Timer1_val_h=0,Timer0_val_l=0,Timer1_val_l=0; bit For_Back=0,Erro_en=0; /***********************************************************************/ //键盘扫描函数声明 /************************************************************************/ //矩阵键盘按键特征码表 uchar code KeyCodeTable[]={0x12,0x22,0x42,0x82,0x14,0x24,0x44,0x84,0x18,0x28,0x48,0x88}; bit k0,k1; /***********************************************************************/ //led数码管显示函数声明 /************************************************************************/ /*根据共阴极字型编码表获取0~9,A~B字型代码*/ uchar getcode(uchar i) { uchar p; switch(i) { case 0: p=0x3f; break; case 1: p=0x06; break; case 2: p=0x5B; break; case 3: p=0x4f; break; case 4: p=0x66; break; case 5: p=0x6D; break; case 6: p=0x7D; break; case 7: p=0x07; break; case 8: p=0x7f; break; case 9: p=0x67; break; case 10: p=0x77; break; case 11: p=0x7C; break; case 12: p=0x39; break; case 13: p=0x5E; break; case 14: p=0x79; break; case 15: p=0x71; break; default: break; } return(p); } /*led显示初始化子程序*/ void Led_display_Init(void) { uchar j; digit=0x01; //从第一位数码管开始动态扫描 /*刚加电时,显示*/ for(j=0;j<8;j++) wordbuf[j]=j; showflag=1; //打开数码管显示 } /*显示函数*/ void display(void) { uchar i; switch(digit) { case 1: i=0;break; case 2: i=1;break; case 4: i=2;break; case 8: i=3;break; case 16: i=4;break; case 32: i=5;break; case 64: i=6;break; case 128: i=7;break; default: break; } P0=0x00; //关闭显示 P2=~digit; //送字位码 P0=getcode(wordbuf[i]); //送字型码 if(digit<0x80) //共8位 digit=digit*2; //左移一位 else digit=0x01; } /***********************************************************************/ //键盘扫描函数声明 /************************************************************************/ //延时 void DelayMS(unint x) { uchar i; while(x--) for(i=0;i<200;i++); } //键盘扫描 uchar Keys_Scan() { uchar sCode,kCode,i,k; //低4位置0,放入4行 P1=0x0e; //若低3位出现0,则有键按下 if((P1&0xf0)!=0x00) { DelayMS(50); //led2=~led2; if((P1&0xf0)!=0x0e) { sCode=0xfd; //行扫描码初值 for(k=0;k<3;k++) //对3行分别进行扫描 { P1=sCode; if((P1&0xf0)!=0xf0) { kCode=~P1; for(i=0;i<12;i++) //查表得到按键序号并返回 if(kCode==KeyCodeTable[i]) return(i); } else sCode=_crol_(sCode,1); } } } return(-1); } //键盘扫描值利用 void key_judge(uchar KeyNo) { switch(KeyNo) { //uchar Zkb1=50,Zkb2=50,Delay1=50,Delay2=50; //uchar PWM_speed_l=5,PWM_speed_r=5; //uchar Timer0_val_h,Timer1_val_h,Timer0_val_l,Timer1_val_l; case 0 : Delay1++ ;if(Delay1>=10) Delay1=1;break; case 1: Delay1-- ;if(Delay1<=0) Delay1=9;break; case 2 : PWM_speed_l++;if(PWM_speed_l>=100) PWM_speed_l=1 ;break; case 3 : ;break; case 4 : Delay2++ ;if(Delay2>=10) Delay2=1;break ; case 5 : Delay2-- ;if(Delay2<=0) Delay2=9;break ; case 6 : PWM_speed_r++;if(PWM_speed_r>=100) PWM_speed_r=1 ;break; case 7 : ;break; case 8 : Zkb1++;if(Zkb1>=10) Zkb1=1;break; case 9 : Zkb2++;if(Zkb2>=10) Zkb2=1 ;break; case 10 : ;break; case 11: ;break; default : break; } } void do_allkey(void) { Timer0_val_h = (1/(float)PWM_speed_l)*917*(Zkb1);//-10/(float)PWM_speed_l*Zkb1*Delay1/100; //N=nms*1000/1.09 ; nms=1/PWM_speed*1000 Timer0_val_l = (1/(float)PWM_speed_l)*917*((10-Zkb1));//-10/(float)PWM_speed_l*Zkb1*Delay1/100; Timer1_val_h = (1/(float)PWM_speed_r)*917*(Zkb2);//-10/(float)PWM_speed_r*Zkb2*Delay1/100; Timer1_val_l = (1/(float)PWM_speed_r)*917*((10-Zkb2));//-10/(float)PWM_speed_r*Zkb2*Delay1/100;//通过设定的每秒产生的波数来确定timer的初始值 } //独立键盘扫描 void Scan_selfkey(void) { if(key0==0) { DelayMS(5); if(key0==0) { k0=1; while(!key0); } } if(key1==0) { DelayMS(5); if(key1==0) { k1=1; while(!key1); } } } //独立键盘利用 void do_selfkey(void) { if(k0==1) { k0=0; For_Back=~For_Back; } // if(k1==1) { k1=0; Erro_en=~Erro_en; } } /**************************************************/ //脉冲产生函数声明 /**************************************************/ void Timer_0_1_Init(void) { TMOD = 0x11; //工作在方式1,16位定时器 ,默认优先级0高 //TH0=-2000/256; //重置2ms定时 //TL0=-2000%256; TH0 = (65536-(50*1000))/256; //1 TL0 = (65536-(50*1000))%256; //TH0 = 0xD8; //10us // TL0 = 0xF0; TH1 = (65536-(50*1000))/256; //10us TL1 = (65536-(50*1000))%256; ET0 = 1; //定时器0中断允许 ET1 = 1; //定时器1中断允许位 } void Timer_2_Init(void) { T2MOD = 0x00; //工作在方式1, T2CON = 0X00; RCAP2H = (65536-2000)/256; RCAP2L = (65536-2000)%256; ET2 = 1; //定时器2中断允许 } void EXint_0_1_Init(void) { IE=0x8F; PT2=1; //中断优先 PT1=1; //中断优先 PT0=1; //中断优先 IT0=0; IT1=0;//低电平触发 } void Timer0(void) interrupt 1 { TH0=(uchar)((65536-4587)/256); //重置2ms定时 TL0=(uchar)((65536-4587)%256); PWM_cnt1++; if(ji_ou_0==0) { if(PWM_cnt1>=(20*Zkb1/PWM_speed_l)) { PWM_out1=~PWM_out1; PWM_cnt1=0; PWM_flag0=1; ji_ou_0=1; } } if(ji_ou_0==1) { if(PWM_cnt1>=(20*(10-Zkb1)/PWM_speed_l)) { PWM_out1=~PWM_out1; PWM_cnt1=0; ji_ou_0=0; } } if(PWM_flag0==1) PWM_cnt2++; if(ji_ou_0==0) { if(PWM_cnt2>=(20*Zkb1*Delay1/PWM_speed_l)/10) { PWM_out2=~PWM_out2; PWM_cnt2=0; // PWM_flag0=0; PWM_flag=1; ji_ou_0=1; } } if(ji_ou_0==1) { if(PWM_cnt2>=(20*(10-Zkb1)*Delay1/PWM_speed_l)/10) { PWM_out2=~PWM_out2; PWM_cnt2=0; PWM_flag0=0; ji_ou_0=0; } } if(PWM_flag==1) PWM_cnt++; if(PWM_cnt>=(20*Zkb1*Delay2/PWM_speed_l)/10);//+(200>>(PWM_speed_r-1))*Zkb2/10) { PWM_flag_=1; PWM_cnt=0; PWM_flag=0; led1=~led1; } } void Timer1(void) interrupt 3 { TH1=(uchar)((65536-4587)/256); //重置2ms定时 TL1=(uchar)((65536-4587)%256); if(PWM_flag_==1) PWM_cnt3++; if(ji_ou_1==0) { if(PWM_flag_==1&&PWM_cnt3>=(20*(10-Zkb2)/PWM_speed_r)) { PWM_out3=~PWM_out3; PWM_cnt3=0; PWM_flag_=0; // PWM_flag=0; PWM_flag1=1; ji_ou_1=1; } } if(ji_ou_1==1) { if(PWM_flag_==1&&PWM_cnt3>=(20*Zkb2/PWM_speed_r)) { PWM_out3=~PWM_out3; PWM_cnt3=0; ji_ou_1=0; } } if(PWM_flag1==1) PWM_cnt4++; if(ji_ou_1==0) { if(PWM_flag1==1&&PWM_cnt4==(20*Zkb2*Delay1/PWM_speed_r)/10) { PWM_out4=~PWM_out4; PWM_cnt4=0; PWM_flag1=0; } ji_ou_1=1; } if(ji_ou_1==1) { if(PWM_flag1==1&&PWM_cnt4==(20*(10-Zkb2)*Delay1/PWM_speed_r)/10) { PWM_out4=~PWM_out4; PWM_cnt4=0; PWM_flag1=0; } ji_ou_1=0; } } void Timer2(void) interrupt 5 { /*定时器0中断服务,2ms定时动态扫描显示 */ TF2=0; if(showflag==1) //注意初值的设定****** display(); //调用显示函数 } void EX_INT0() interrupt 0 { ET0=0; // DelayMS(10); //led1 =~led1; ET0=1; } void EX_INT1() interrupt 2 { ET1=0; //DelayMS(10); //led2 =~led2; ET1=1; } int main(void) { /*****局部变量*****/ uchar P3_LED=0xFF; uchar KeyNo=-1; //按键序号,-1表示无按键 /*****寄存器变量*****/ /*******************/ Timer_0_1_Init(); //EXint_0_1_Init(); Led_display_Init(); Timer_2_Init(); TR0 = 1; //启动定时器0 TR1 = 1; //启动定时器1 TR2 = 1; //启动定时器2 EA = 1; //打开中断 led2=1; led1=1; PWM_out1 = 1; PWM_out2 = 1; PWM_out3 = 0; PWM_out4 = 0; while(1) { /****键盘扫描*****/ KeyNo=Keys_Scan(); //扫描键盘获取按键序号KeyNo if(KeyNo!=-1) { key_judge(KeyNo); //使用键盘扫描 } do_allkey(); /********/ /******显示使用******/ wordbuf[7]= PWM_speed_l/10; wordbuf[6]= PWM_speed_l%10; wordbuf[5]= PWM_speed_r/10; wordbuf[4]= PWM_speed_r%10; wordbuf[3]= Zkb1; wordbuf[2]= Zkb2; wordbuf[1]= Delay1; wordbuf[0]= Delay2; /****独立键盘扫描****/ Scan_selfkey(); do_selfkey(); out2_cnt++; out4_cnt++; } }
相关文章推荐
- MSP430方波发生器
- STC15W4K48S4 它有6通道高精度PWM发生器
- 运放篇——正负对称方波发生器
- 用51单片机做信号发生器,同时输出四种频率的方波
- 基于51单片机的简单方波发生器
- 基于msp430单片机的方波发生器
- 使8253输出1S的方波,使通道外接的发光二极管亮1S,暗1S
- 【基于C++和Python的Opencv3学习笔记之颜色空间缩减、ROI提取及多通道分离合并】
- 高速通道-冗余物理专线接入-健康检查配置
- 什么是Photoshop的Alpha通道(详细图解)
- 通道(channel)和队列(queue)的区别
- DotNetty的通道处理细节
- 在学习opencv 多通道变单通道时 自己出现的一点错误
- STM32之ADC单通道连续例程
- SATA 3.0 双通道 - 硬盘数据线 + 硬盘电源线
- 暗通道优先的图像去雾算法(下)
- Tensorflow 合并通道及加载子模型的方法
- 溢出程序使用通道对抗防火墙
- 介入方式与反馈方式电子化--冷泉科技Cerebus: 128通道数据采集系统
- Photoshop入门与进阶实例:1.7 通道的概念和基本功能