标题:
基于单片机压控PWM波源程序 双机串行通信
[打印本页]
作者:
叶俊哥哥
时间:
2020-6-22 14:27
标题:
基于单片机压控PWM波源程序 双机串行通信
程序目的
:
甲机接收ADC0808转换的电压信号,并在四位数码管显示电压值,将该电压信号发送到乙机;
乙机接收字符串,并将该信息转换为PWM波频率,生成相应PWM波
Snipaste_2020-06-21_23-12-30.png
(84.97 KB, 下载次数: 54)
下载附件
2020-6-22 14:21 上传
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;
}
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1