单片机软件模拟串口
前言
關(guān)于寫這篇文章完全是記錄自己的學(xué)習(xí)心得,方便后期忘記回頭復(fù)習(xí)!
1、什么是模擬串口
模擬串口就是利用兩個輸入輸出引腳如P1.0和P1.1,置1或0分別代表高低電平,也就是串口通信中所說的位,如起始位用低電平,則將其置0,停止位為高電平,則將其置1,各種數(shù)據(jù)位和校驗(yàn)位則根據(jù)情況置1或置0。
2、什么是波特率
串口通信的波特率,說到底只是每位電平持續(xù)的時間,波特率越高,持續(xù)的時間越短。如波特率為9600bps,即每一位傳送時間為1000ms/9600=0.104ms,即位與位之間的延時為0.104毫秒。
3、串口物理層:TX、RX兩條信號線
4、協(xié)議層:起始位(低電平)+8位數(shù)據(jù)(低位在前)+1位停止位(高電平),每位的持續(xù)時間根據(jù)波特率而定;例如波特率9600,每位的持續(xù)時間為:1/9600≈104us。
模擬發(fā)送實(shí)現(xiàn)比較簡單,根據(jù)協(xié)議來編寫即可。
sbit sys_tm0_flag;//100us中斷1次 void sys_delay(u8 i) {while(1){if(i == 0){return;}if(sys_tm0_flag){sys_tm0_flag = 0;i--;}} }/* io軟件模擬串口發(fā)送一個字節(jié) * 協(xié)議:起始位(低電平)+8位數(shù)據(jù)(低位在前)+1位停止位(高電平),波特率2450:間隔時間1/2450≈400us * PT1_5 TX * 100us 定時 * 波特率2450 */ void uart_software_putc(u8 i) {u8 temp8;PT1_5 = 1; PT1EN_5 = 1;sys_delay(1);PT1_5 = 0;//起始位低電平sys_delay(4);//波特率2450,每一位間隔1/2450≈400usfor(temp8 = 0;temp8 < 8;temp8++)//數(shù)據(jù)位{if(i & 0x01){PT1_5 = 1;}else{PT1_5 = 0;}i = i >> 1;sys_delay(4);}PT1_5 = 1;//停止位高電平sys_delay(4); }串口模擬接收相較發(fā)送略微復(fù)雜。
u8 uart_software_rxdata[30];//模擬串口接收存放數(shù)組 u8 uart_software_rxp;//接收字節(jié)計(jì)數(shù)/* io模擬串口接收 * 協(xié)議:起始位(低電平)+8位數(shù)據(jù)(低位在前)+1位停止位(高電平),間隔時間1/2450≈400us * PT1_4 RX * 此接收函數(shù)放在100us 定時中斷中 * 波特率2450 */ void uart_software_receive(void) {static u8 delay;static u8 cnt;if(delay > 1)//延時{delay--;return;}switch (cnt){case 0:if(PT1_4)//首先空閑時應(yīng)是高電平狀態(tài){cnt++;}break;case 1:if(PT1_4 == 0)//空閑時判斷當(dāng)起始位低電平來到,延時一半取電平信號的中間即穩(wěn)定電平{cnt++;delay = 2;}break;case 2://如果起始位中間是1,錯誤直接回到0;(中間的意思是取電平信號的中間值即穩(wěn)定值)//起始位中間是0,0.4ms后讀取第一位;if(PT1_4){cnt = 0;}else{cnt++;delay = 4;}break;case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:uart_software_rxdata[uart_software_rxp] = uart_software_rxdata[uart_software_rxp] >> 1;//低位在前,所以要把先接收到的低位右移if(PT1_4){uart_software_rxdata[uart_software_rxp] |= 0x80;//低位在前}cnt++;delay = 4;break;case 11://這個地方是停止位中間:但是不再判斷高低了,視為一個字節(jié)的接收結(jié)束uart_software_rxp++;if(uart_software_rxp > 29)uart_software_rxp = 29;cnt = 0;break;default:cnt = 0;break;} }清除接收數(shù)組函數(shù)
/* io模擬串口清除數(shù)接收組、接收字節(jié)計(jì)數(shù) */ void uart_software_clear_rxdata(void) {u8 i;for ( i = 0; i < 30; i++){uart_software_rxdata[i] = 0;}uart_software_rxp = 0; }接收到數(shù)據(jù)立馬發(fā)出
if(uart_software_rxp > 0){for(; uart_software_rxp >0; uart_software_rxp--){uart_software_putc(uart_software_rxdata[uart_software_rxp]);}uart_software_clear_rxdata();}總結(jié)
- 上一篇: 张宇1000题线性代数 第三章 矩阵运算
- 下一篇: 最小二乘法拟合三维直线