程序目的: 甲机接收ADC0808转换的电压信号,并在四位数码管显示电压值,将该电压信号发送到乙机;
乙机接收字符串,并将该信息转换为PWM波频率,生成相应PWM波
Keil涉及:AD转换、串行通信、PWM
Proteus需要:ADC0809 AT89C52 四位数码管
甲机代码:
- /*(一)用ADC0808采集电压,完成:
- 将 采集结果 在数码管上显示出来,并将采集结果 数字量 传送到乙机*/
- #include<reg52.h>
- #define baud 9600 //设置波特率;
- bit flag = 0;
- sbit START = P2^0; //定义p2.0为START;
- sbit OE = P2^2; //定义P2.2为OE;
- unsigned char s[5]; //定义要被发送的字符串数组;
- unsigned char code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0xff};
- unsigned char DSY_BUFF[4]={0xff,0xff,0xff,0xff};//数码管显示值
- unsigned char d; //定义电压测量比
- unsigned int dat; //定义电压测量比d转换后数值
- void main()
- {
- /*初始化*/
- TMOD = 0x21;
- SCON = 0x50; //8位异步收发,波特率可变
- TH0 = (65536-922)/256; //设定时器T0初值,使用11.0592MHz;1ms
- TL0 = (65536-922)%256;
- TH1 = 256 - (11059200/12/32)/baud; //设定时器T1初值
- TL1 = TH1;
- IT0 = 1; //设置完跳变沿触发方式
- EA = 1; //开启总中断
- ET0 = 1; //开启定时器T0中断
- ES = 1; //开启串口中断源
- EX0 = 1; //开启外部中断
- TR1 = 1;
- TR0 = 1; //开启定时器
- START = 0;START = 1;START = 0; //启动ADC0808
- while(1)
- {
- /*标志位flag置位:执行电压信号转换、上位机发送程序*/
- if(flag==1)
- {
- flag = 0; //初始化flag
- dat = d*5000.0/255.0; //计算电压值
- DSY_BUFF[0] = DSY_CODE[11]; //数码管显示数值最低位
- DSY_BUFF[1] = DSY_CODE[dat/10%10];
- DSY_BUFF[2] = DSY_CODE[dat/100%10];
- DSY_BUFF[3] = DSY_CODE[dat/1000];
- s[0]=dat/1000+0x30; //定义电压值最高位
- s[1]=dat/100%10+0x30;
- s[2]=dat/10%10+0x30;
- s[3]='V';
- s[4]='\0';
- SBUF = s[0]; //上位机发送开始
- }
- }
- }
- void EX0_Int() interrupt 0 //外部中断0
- {
- OE = 1; //输出使能
- d = P1; //读取转换结果
- OE = 0;
- flag = 1; //标志位flag置一
- }
- /*T0定时器中断********数码管动态显示,开启测量电压值*/
- void Boom_big() interrupt 1
- {
- static unsigned char i,cnt;
- TH0 = (65536-922)/256; //重装初值
- TL0 = (65536-922)%256;
- P0 = 0xFF; //消鬼
- P2 = (0x80>>i)|(P2&0x0F);
- P0 = DSY_BUFF[i];
- i++;
- if(i>=4)
- {
- P0 &= 0x7F;
- i = 0;
- }
- cnt++;
- if(cnt>=200) //每隔200ms测量电压值
- {
- cnt = 0;
- START = 0;START = 1;START = 0;
- }
- }
- /*串口中断,甲机发送电压转换值字符串*/
- void UART_ISR() interrupt 4
- {
- static unsigned char n = 1;
- if(RI)
- {
- RI = 0;
- }
- if(TI)
- {
- TI = 0;
- if(s[n] !='\0') //直到s[6]发完为止
- {
- SBUF = s[n]; //发送字符数组s[]
- n++;
- }
- else //发完i清零,下次使用
- {
- n = 1;
- }
- }
- }
复制代码
乙机代码:
- /*乙机接收数据,并产生相应PWM波*/
- #include<reg52.h>
- #define baud 9600 //设置波特率
- bit flag = 0;
- sbit PWM = P2^2; //PWM脉冲引脚P2^2
- unsigned char s[4]; //设置接收字符串的数组
- unsigned int freq; //频率初值
- unsigned char dc = 25; //占空比
- unsigned char HighTH,HighTL,LowTH,LowTL;
- void main()
- {
- /*初始化串口中断、定时器中断*/
- SCON = 0x50;
- TMOD = 0x21;
- HighTH = (65536-11059200/12/freq*dc/100) / 256; //设高脉冲初值
- HighTL = (65536-11059200/12/freq*dc/100) % 256;
- LowTH = (65536-11059200/12/freq*(100-dc)/100) / 256; //设低脉冲初值
- LowTL = (65536-11059200/12/freq*(100-dc)/100) % 256;
- TH0=HighTH;
- TL0=HighTL;
- TH1 = 256-(11059200/12/32)/baud; //定时器T1设初值
- TL1 = TH1;
- PWM = 1;
- EA = 1;
- ET0 = 0; //关定时器T0中断
- TR0 = 1;
- ES = 1; //开启串口中断
- TR1 = 1;
- while(1)
- {
- if(flag==1)
- {
- flag = 0;
- freq = ((s[0]-0x30)*100+(s[1]-0x30)*10+(s[2]-0x30));//转换字符串s[]:PWM频率freq
- HighTH = (65536-11059200/12/freq*dc/100) / 256; //设高脉冲初值
- HighTL = (65536-11059200/12/freq*dc/100) % 256;
- LowTH = (65536-11059200/12/freq*(100-dc)/100) / 256;//设低脉冲初值
- LowTL = (65536-11059200/12/freq*(100-dc)/100) % 256;
- ET0 = 1; //开启定时器T0中断
- }
- }
- }
- void Big_Boomm() interrupt 4 //串口中断
- {
- static unsigned char i;
- if(RI)
- {
- RI =0;
- s[i] = SBUF; //接收数据到数组s[]
- if(s[i]=='V')
- {
- s[i] = '\0';
- i = 0;
- flag = 1; //接收结束,标志位flag置位
- }
- else
- i++;
- }
- }
- /*定时器T0 PWM发生器*/
- void BoooM() interrupt 1 //定时器T0中断
- {
- if(PWM==1)
- {
- TH0=LowTH;
- TL0=LowTL;
- PWM = 0;
- }
- else
- {
- TH0=HighTH;
- TL0=HighTL;
- PWM = 1;
- }
- }
复制代码
|