首页 > 代码库 > 51单片机GPIO口模拟串口通信

51单片机GPIO口模拟串口通信

        51单片机GPIO口模拟串口通信

标签: bytetimer终端存储
本文章已收录于:
 
技术分享 分类:
作者同类文章X
  1 #include "reg52.h"
  2 #include "intrins.h"  
  3 #include "math.h"     
  4 #include "stdio.h"
  5 sbit BT_SND =P1^5;
  6 sbit BT_REC =P1^6;
  7 sbit LED =P1^7;
  8 bit  LED_flage=1;
  9 //IO 口模拟232通讯程序
 10 //使用两种方式的C程序 占用定时器0
 11 #define MODE_QUICK
 12 #define F_TM F0
 13 #define TIMER0_ENABLE  TL0=TH0; TR0=1;
 14 #define TIMER0_DISABLE TR0=0;
 15 sbit ACC0=   ACC^0;
 16 sbit ACC1=   ACC^1;
 17 sbit ACC2=   ACC^2;
 18 sbit ACC3=   ACC^3;
 19 sbit ACC4=   ACC^4;
 20 sbit ACC5=   ACC^5;
 21 sbit ACC6=   ACC^6;
 22 sbit ACC7=   ACC^7;
 23 
 24 void IntTimer0() interrupt 1
 25 {
 26   F_TM=1;
 27 }
 28 //发送一个字符
 29 void PSendChar(unsigned char inch)
 30 {
 31 #ifdef MODE_QUICK
 32     ACC=inch;
 33     F_TM=0;
 34     BT_SND=0; //start bit
 35     TIMER0_ENABLE; //启动
 36     while(!F_TM);
 37     BT_SND=ACC0; //先送出低位
 38     F_TM=0;
 39     while(!F_TM);
 40     BT_SND=ACC1;
 41     F_TM=0;
 42     while(!F_TM);
 43     BT_SND=ACC2;
 44     F_TM=0;
 45     while(!F_TM);
 46     BT_SND=ACC3;
 47     F_TM=0;
 48     while(!F_TM);
 49     BT_SND=ACC4;
 50     F_TM=0;
 51     while(!F_TM);
 52     BT_SND=ACC5;
 53     F_TM=0;
 54     while(!F_TM);
 55     BT_SND=ACC6;
 56     F_TM=0;
 57     while(!F_TM);
 58     BT_SND=ACC7;
 59     F_TM=0;
 60     while(!F_TM);
 61     BT_SND=1;
 62     F_TM=0;
 63     while(!F_TM);
 64     TIMER0_DISABLE; //停止timer
 65     #else
 66     unsigned char ii;
 67      ii=0;
 68      F_TM=0;
 69      BT_SND=0; //start bit
 70      TIMER0_ENABLE; //启动
 71      while(!F_TM);
 72      while(ii<8)
 73         {
 74           if(inch&1)
 75          {
 76           BT_SND=1;
 77          }
 78          else
 79          {
 80           BT_SND=0;
 81          }
 82           F_TM=0;
 83         while(!F_TM);
 84           ii++;
 85          inch>>=1;
 86     }
 87          BT_SND=1;
 88          F_TM=0;
 89          while(!F_TM);
 90     #endif
 91     TIMER0_DISABLE; //停止timer
 92 }
 93 //接收一个字符
 94 unsigned char PGetChar()
 95 {
 96         #ifdef MODE_QUICK
 97         TIMER0_ENABLE;
 98         F_TM=0;
 99         while(!F_TM); //等过起始位
100         ACC0=BT_REC;
101         TL0=TH0;
102         F_TM=0;
103         while(!F_TM);
104         ACC1=BT_REC;
105         F_TM=0;
106         while(!F_TM);
107         ACC2=BT_REC;
108         F_TM=0;
109         while(!F_TM);
110         ACC3=BT_REC;
111         F_TM=0;
112         while(!F_TM);
113         ACC4=BT_REC;
114         F_TM=0;
115         while(!F_TM);
116         ACC5=BT_REC;        
117         F_TM=0;
118         while(!F_TM);
119         ACC6=BT_REC;        
120         F_TM=0;
121         while(!F_TM);
122         ACC7=BT_REC;
123         F_TM=0;
124         while(!F_TM)
125     {
126                 if(BT_REC)
127                 {
128                   break;
129                 }
130     }
131         TIMER0_DISABLE; //停止timer
132         return ACC;
133         #else
134         unsigned char rch,ii;
135         TIMER0_ENABLE;
136         F_TM=0;
137         ii=0;
138         rch=0;
139         while(!F_TM); //等过起始位
140         while(ii<8)
141     {
142             rch>>=1;
143                 if(BT_REC)
144                 {
145                 rch|=0x80;
146                 }                                        
147                 ii++;
148                 F_TM=0;
149                 while(!F_TM);        
150     }
151         F_TM=0;
152          while(!F_TM)
153     {
154                 if(BT_REC)
155                 {
156                    break;
157                 }
158     }
159         TIMER0_DISABLE; //停止timer
160         return rch;
161         #endif
162 }
163 //检查是不是有起始位
164 bit StartBitOn()
165 {
166   return (BT_REC==0);
167 }
168 //定时器1初始化
169 void Time1_Init(void)
170 {
171    TMOD=0x22; //定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装) 
172    PCON=00;
173    TR0=0; //在发送或接收才开始使用
174    TF0=0;
175    TH0=(256-96); //9600bps 就是 1000000/9600=104.167微秒 执行的timer//104.167*11.0592/12= 96
176    TL0=TH0;
177    ET0=1;
178    EA=1;
179 }
180 //发送字符串
181 void Send_Char(char *byte)
182 {
183    int i=0;
184    for(i=0;*(byte+i)!=\0;i++)
185    {
186       PSendChar(*(byte+i));
187    }
188 }
189 //void delay(int x)
190 //{
191 //        int a,b;
192 //        for(a=x;a>0;a--)
193 //                for(b=10;b>0;b--); 
194 //}
195 //void main()
196 //{
197 //   unsigned char gch;
198 //   Time1_Init();
199 //   LED=0;
200 //  // Send_Char("S00.0C00.0%E00.0C00.0%L00000lx");
201 //   while(1)
202 //  {          
203 //      
204 //          PSendChar(‘1‘);
205 //          delay(1000);
206 ////      if(StartBitOn())
207 ////          {
208 ////            gch=PGetChar();
209 ////            if(gch==‘1‘)
210 ////                {
211 ////                  LED=LED_flage;  
212 ////                  delay(1000);
213 ////                  LED_flage=~LED_flage;
214 ////                } 
215 ////                
216 ////          }        
217 //           
218 //  }           
219 //
220 //} 

 

            随着单片机的使用日益频繁,用其作前置机进行采集和通信也常见于各种应用,一般是利用前置机采集各种终端数据后进行处理、存储,再主动或被动上报给管理站。这种情况下下,采集会需要一个串口,上报又需要另一个串口,这就要求单片机具有双串口的功能,但我们知道一般的51系列只提供一个串口,那么另一个串口只能靠程序模拟。

            本文所说的模拟串口, 就是利用51的两个输入输出引脚P1.0和P1.1,置1或0分别代表高低电平,也就是串口通信中所说的位,如起始位用低电平,则将其置0,停止位为高电平,则将其置1,各种数据位和校验位则根据情况置1或置0。

            以11.0592MHz的晶振为例,通过定时计数器0产生中断信号来模拟串口电平,下面附上具体源代码。

    51单片机GPIO口模拟串口通信