程序目的: 甲機接收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;
- }
- }
復制代碼
|