51单片机GPIO口模拟串口通信
Posted Kroner
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51单片机GPIO口模拟串口通信相关的知识,希望对你有一定的参考价值。
本文章已收录于:
分类:
作者同类文章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口模拟串口通信的主要内容,如果未能解决你的问题,请参考以下文章