找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1816|回复: 0
打印 上一主题 下一主题
收起左侧

基于单片机压控PWM波源程序 双机串行通信

[复制链接]
跳转到指定楼层
楼主
程序目的       甲机接收ADC0808转换的电压信号,并在四位数码管显示电压值,将该电压信号发送到乙机;
乙机接收字符串,并将该信息转换为PWM波频率,生成相应PWM波


Keil涉及:AD转换、串行通信、PWM
Proteus需要:ADC0809 AT89C52 四位数码管
甲机代码:
  1. /*(一)用ADC0808采集电压,完成:
  2. 将 采集结果 在数码管上显示出来,并将采集结果 数字量 传送到乙机*/
  3. #include<reg52.h>
  4. #define baud 9600                        //设置波特率;
  5. bit flag = 0;               
  6. sbit START = P2^0;                         //定义p2.0为START;
  7. sbit OE = P2^2;                                  //定义P2.2为OE;
  8. unsigned char s[5];                  //定义要被发送的字符串数组;
  9. unsigned char code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0xff};
  10. unsigned char DSY_BUFF[4]={0xff,0xff,0xff,0xff};//数码管显示值        
  11. unsigned char d;                                                  //定义电压测量比
  12. unsigned int dat;                                                  //定义电压测量比d转换后数值
  13. void main()
  14. {
  15. /*初始化*/                  
  16.         TMOD = 0x21;
  17.         SCON = 0x50;                                                  //8位异步收发,波特率可变
  18.         TH0 = (65536-922)/256;                                //设定时器T0初值,使用11.0592MHz;1ms
  19.         TL0 = (65536-922)%256;
  20.         TH1 = 256 - (11059200/12/32)/baud;                          //设定时器T1初值
  21.         TL1 = TH1;
  22.         IT0 = 1;                                                                          //设置完跳变沿触发方式
  23.         EA = 1;                                                                                  //开启总中断
  24.         ET0 = 1;                                                                          //开启定时器T0中断
  25.         ES = 1;                                                                              //开启串口中断源
  26.         EX0 = 1;                                                                       //开启外部中断
  27.         TR1 = 1;
  28.         TR0 = 1;                                                                           //开启定时器
  29.         START = 0;START = 1;START = 0;                                 //启动ADC0808
  30.         while(1)
  31.         {
  32. /*标志位flag置位:执行电压信号转换、上位机发送程序*/
  33.                 if(flag==1)               
  34.                 {         
  35.                         flag = 0;                                                          //初始化flag
  36.                         dat = d*5000.0/255.0;                                  //计算电压值
  37.                         DSY_BUFF[0] = DSY_CODE[11];                        //数码管显示数值最低位
  38.                         DSY_BUFF[1] = DSY_CODE[dat/10%10];
  39.                         DSY_BUFF[2] = DSY_CODE[dat/100%10];
  40.                         DSY_BUFF[3] = DSY_CODE[dat/1000];
  41.                         s[0]=dat/1000+0x30;                                        //定义电压值最高位
  42.                         s[1]=dat/100%10+0x30;
  43.                         s[2]=dat/10%10+0x30;
  44.                         s[3]='V';
  45.                         s[4]='\0';
  46.                         SBUF = s[0];                                                   //上位机发送开始
  47.                 }
  48.         }
  49. }
  50. void EX0_Int() interrupt 0                                                  //外部中断0
  51. {
  52.                 OE = 1;                                                                        //输出使能
  53.                 d = P1;                                                                         //读取转换结果
  54.                 OE = 0;
  55.                 flag = 1;                                                                 //标志位flag置一
  56. }
  57. /*T0定时器中断********数码管动态显示,开启测量电压值*/
  58. void Boom_big() interrupt 1                                                  
  59. {                             
  60.         static unsigned char i,cnt;
  61.         TH0 = (65536-922)/256;                                                 //重装初值
  62.         TL0 = (65536-922)%256;
  63.         P0 = 0xFF;                                                                         //消鬼
  64.         P2 = (0x80>>i)|(P2&0x0F);
  65.         P0 = DSY_BUFF[i];
  66.         i++;
  67.         if(i>=4)
  68.         {
  69.                 P0 &= 0x7F;
  70.                 i = 0;
  71.         }
  72.         cnt++;
  73.         if(cnt>=200)                                                                 //每隔200ms测量电压值
  74.         {
  75.                 cnt = 0;
  76.                 START = 0;START = 1;START = 0;
  77.         }
  78. }
  79. /*串口中断,甲机发送电压转换值字符串*/
  80. void UART_ISR() interrupt 4                                                  
  81. {
  82.         static unsigned char n = 1;
  83.         if(RI)
  84.         {
  85.                 RI = 0;        
  86.         }
  87.         if(TI)
  88.         {  
  89.                 TI = 0;
  90.                 if(s[n] !='\0')                                  //直到s[6]发完为止
  91.                 {
  92.                         SBUF = s[n];                          //发送字符数组s[]
  93.                         n++;
  94.                 }
  95.                 else                                                //发完i清零,下次使用  
  96.                 {
  97.                         n = 1;        
  98.                 }
  99.         }
  100. }
复制代码

乙机代码:
  1. /*乙机接收数据,并产生相应PWM波*/
  2. #include<reg52.h>
  3. #define baud 9600                                                 //设置波特率
  4. bit flag = 0;
  5. sbit PWM = P2^2;                                                //PWM脉冲引脚P2^2
  6. unsigned char s[4];                                                //设置接收字符串的数组
  7. unsigned int freq;                                                 //频率初值
  8. unsigned char dc = 25;                                           //占空比
  9. unsigned char HighTH,HighTL,LowTH,LowTL;
  10. void main()
  11. {
  12. /*初始化串口中断、定时器中断*/
  13.         SCON = 0x50;
  14.         TMOD = 0x21;
  15.         HighTH = (65536-11059200/12/freq*dc/100) / 256;                                //设高脉冲初值
  16.         HighTL = (65536-11059200/12/freq*dc/100) % 256;        
  17.         LowTH = (65536-11059200/12/freq*(100-dc)/100) / 256;                //设低脉冲初值
  18.         LowTL = (65536-11059200/12/freq*(100-dc)/100) % 256;
  19.         TH0=HighTH;
  20.         TL0=HighTL;
  21.         TH1 = 256-(11059200/12/32)/baud;                                                          //定时器T1设初值
  22.         TL1 = TH1;
  23.         PWM = 1;
  24.         EA = 1;
  25.         ET0 = 0;                                                                                                           //关定时器T0中断
  26.         TR0 = 1;
  27.         ES = 1;                                                                                                           //开启串口中断
  28.         TR1 = 1;
  29.         while(1)
  30.         {
  31.                 if(flag==1)
  32.                 {
  33.                         flag = 0;
  34.                         freq = ((s[0]-0x30)*100+(s[1]-0x30)*10+(s[2]-0x30));//转换字符串s[]:PWM频率freq           
  35.                         HighTH = (65536-11059200/12/freq*dc/100) / 256;                //设高脉冲初值
  36.                         HighTL = (65536-11059200/12/freq*dc/100) % 256;        
  37.                         LowTH = (65536-11059200/12/freq*(100-dc)/100) / 256;//设低脉冲初值
  38.                         LowTL = (65536-11059200/12/freq*(100-dc)/100) % 256;         
  39.                         ET0 = 1;                                                                                           //开启定时器T0中断

  40.                 }
  41.         }
  42. }
  43. void Big_Boomm() interrupt 4                        //串口中断
  44. {
  45.         static unsigned char i;
  46.         if(RI)
  47.         {
  48.                 RI =0;
  49.                 s[i] = SBUF;                                          //接收数据到数组s[]
  50.                 if(s[i]=='V')
  51.                 {
  52.                         s[i] = '\0';
  53.                         i = 0;  
  54.                         flag = 1;                                          //接收结束,标志位flag置位
  55.                 }
  56.                 else
  57.                 i++;
  58.         }
  59. }
  60. /*定时器T0 PWM发生器*/
  61. void BoooM() interrupt 1                                //定时器T0中断
  62. {
  63.         if(PWM==1)
  64.         {
  65.                 TH0=LowTH;
  66.                 TL0=LowTL;
  67.                 PWM = 0;
  68.         }
  69.         else
  70.         {
  71.                 TH0=HighTH;
  72.                 TL0=HighTL;
  73.                 PWM = 1;
  74.         }
  75. }
复制代码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表