|
使用51單片機(jī)Timer2模擬一個(gè)半雙工串口的c語(yǔ)言代碼
- /************* 功能說(shuō)明 **************
- 使用STC15系列的Timer2做的模擬串口. P3.0接收, P3.1發(fā)送, 半雙工.
- 假定測(cè)試芯片的工作頻率為22118400Hz. 時(shí)鐘為5.5296MHZ ~ 35MHZ.
- 波特率高,則時(shí)鐘也要選高, 優(yōu)先使用 22.1184MHZ, 11.0592MHZ.
- 測(cè)試方法: 上位機(jī)發(fā)送數(shù)據(jù), MCU收到數(shù)據(jù)后原樣返回.
- 串口固定設(shè)置: 1位起始位, 8位數(shù)據(jù)位, 1位停止位, 波特率在范圍如下.
- 1200 ~ 115200 bps @ 33.1776MHZ
- 600 ~ 115200 bps @ 22.1184MHZ
- 600 ~ 76800 bps @ 18.4320MHZ
- 300 ~ 57600 bps @ 11.0592MHZ
- 150 ~ 19200 bps @ 5.5296MHZ
- ******************************************/
- #include <reg52.h>
- #define MAIN_Fosc 22118400UL //定義主時(shí)鐘
- #define UART3_Baudrate 115200UL //定義波特率
- #define RX_Lenth 32 //接收長(zhǎng)度
- #define UART3_BitTime (MAIN_Fosc / UART3_Baudrate)
- typedef unsigned char u8;
- typedef unsigned int u16;
- typedef unsigned long u32;
- sfr IE2 = 0xAF;
- sfr AUXR = 0x8E;
- sfr INT_CLKO = 0x8F;
- sfr T2H = 0xD6;
- sfr T2L = 0xD7;
- u8 Tx3_read; //發(fā)送讀指針
- u8 Rx3_write; //接收寫指針
- u8 idata buf3[RX_Lenth]; //接收緩沖
- u16 RxTimeOut;
- bit B_RxOk; //接收結(jié)束標(biāo)志
- //===================== 模擬串口相關(guān)===========================
- sbit P_RX3 = P3^0; //定義模擬串口接收IO
- sbit P_TX3 = P3^1; //定義模擬串口發(fā)送IO
- u8 Tx3_DAT; // 發(fā)送移位變量, 用戶不可見(jiàn)
- u8 Rx3_DAT; // 接收移位變量, 用戶不可見(jiàn)
- u8 Tx3_BitCnt; // 發(fā)送數(shù)據(jù)的位計(jì)數(shù)器, 用戶不可見(jiàn)
- u8 Rx3_BitCnt; // 接收數(shù)據(jù)的位計(jì)數(shù)器, 用戶不可見(jiàn)
- u8 Rx3_BUF; // 接收到的字節(jié), 用戶讀取
- u8 Tx3_BUF; // 要發(fā)送的字節(jié), 用戶寫入
- bit Rx3_Ring; // 正在接收標(biāo)志, 低層程序使用, 用戶程序不可見(jiàn)
- bit Tx3_Ting; // 正在發(fā)送標(biāo)志, 用戶置1請(qǐng)求發(fā)送, 底層發(fā)送完成清0
- bit RX3_End; // 接收到一個(gè)字節(jié), 用戶查詢 并清0
- //=============================================================
- void UART_Init(void);
- /******************** 主函數(shù) **************************/
- void main(void)
- {
-
- UART_Init(); //PCA初始化
- EA = 1;
-
- while (1) //user's function
- {
- if (RX3_End) // 檢測(cè)是否收到一個(gè)字節(jié)
- {
- RX3_End = 0; // 清除標(biāo)志
- buf3[Rx3_write] = Rx3_BUF; // 寫入緩沖
- if(++Rx3_write >= RX_Lenth) Rx3_write = 0; // 指向下一個(gè)位置, 溢出檢測(cè)
- RxTimeOut = 1000; //裝載超時(shí)時(shí)間
- }
- if(RxTimeOut != 0) // 超時(shí)時(shí)間是否非0?
- {
- if(--RxTimeOut == 0) // (超時(shí)時(shí)間 - 1) == 0?
- {
- B_RxOk = 1;
- AUXR &= ~(1<<4); //Timer2 停止運(yùn)行
- INT_CLKO &= ~(1 << 6); //禁止INT4中斷
- T2H = (65536 - UART3_BitTime) / 256; //數(shù)據(jù)位
- T2L = (65536 - UART3_BitTime) % 256; //數(shù)據(jù)位
- AUXR |= (1<<4); //Timer2 開(kāi)始運(yùn)行
- }
- }
-
- if(B_RxOk) // 檢測(cè)是否接收OK?
- {
- if (!Tx3_Ting) // 檢測(cè)是否發(fā)送空閑
- {
- if (Tx3_read != Rx3_write) // 檢測(cè)是否收到過(guò)字符
- {
- Tx3_BUF = buf3[Tx3_read]; // 從緩沖讀一個(gè)字符發(fā)送
- Tx3_Ting = 1; // 設(shè)置發(fā)送標(biāo)志
- if(++Tx3_read >= RX_Lenth) Tx3_read = 0; // 指向下一個(gè)位置, 溢出檢測(cè)
- }
- else
- {
- B_RxOk = 0;
- AUXR &= ~(1<<4); //Timer2 停止運(yùn)行
- INT_CLKO |= (1 << 6); //允許INT4中斷
- }
- }
- }
- }
- }
- //========================================================================
- // 函數(shù): void UART_Init(void)
- // 描述: UART初始化程序.
- // 參數(shù): none
- // 返回: none.
- // 版本: V1.0, 2013-11-22
- //========================================================================
- void UART_Init(void)
- {
- Tx3_read = 0;
- Rx3_write = 0;
- Tx3_Ting = 0;
- Rx3_Ring = 0;
- RX3_End = 0;
- Tx3_BitCnt = 0;
- RxTimeOut = 0;
- B_RxOk = 0;
- AUXR &= ~(1<<4); // Timer2 停止運(yùn)行
- T2H = (65536 - UART3_BitTime) / 256; // 數(shù)據(jù)位
- T2L = (65536 - UART3_BitTime) % 256; // 數(shù)據(jù)位
- INT_CLKO |= (1 << 6); // 允許INT4中斷
- IE2 |= (1<<2); // 允許Timer2中斷
- AUXR |= (1<<2); // 1T
- }
- //======================================================================
- //========================================================================
- // 函數(shù): void timer2_int (void) interrupt 12
- // 描述: Timer2中斷處理程序.
- // 參數(shù): None
- // 返回: none.
- // 版本: V1.0, 2012-11-22
- //========================================================================
- void timer2_int (void) interrupt 12
- {
- if(Rx3_Ring) //已收到起始位
- {
- if (--Rx3_BitCnt == 0) //接收完一幀數(shù)據(jù)
- {
- Rx3_Ring = 0; //停止接收
- Rx3_BUF = Rx3_DAT; //存儲(chǔ)數(shù)據(jù)到緩沖區(qū)
- RX3_End = 1;
- AUXR &= ~(1<<4); //Timer2 停止運(yùn)行
- INT_CLKO |= (1 << 6); //允許INT4中斷
- }
- else
- {
- Rx3_DAT >>= 1; //把接收的單b數(shù)據(jù) 暫存到 RxShiftReg(接收緩沖)
- if(P_RX3) Rx3_DAT |= 0x80; //shift RX data to RX buffer
- }
- }
- if(Tx3_Ting) // 不發(fā)送, 退出
- {
- if(Tx3_BitCnt == 0) //發(fā)送計(jì)數(shù)器為0 表明單字節(jié)發(fā)送還沒(méi)開(kāi)始
- {
- P_TX3 = 0; //發(fā)送開(kāi)始位
- Tx3_DAT = Tx3_BUF; //把緩沖的數(shù)據(jù)放到發(fā)送的buff
- Tx3_BitCnt = 9; //發(fā)送數(shù)據(jù)位數(shù) (8數(shù)據(jù)位+1停止位)
- }
- else //發(fā)送計(jì)數(shù)器為非0 正在發(fā)送數(shù)據(jù)
- {
- if (--Tx3_BitCnt == 0) //發(fā)送計(jì)數(shù)器減為0 表明單字節(jié)發(fā)送結(jié)束
- {
- P_TX3 = 1; //送停止位數(shù)據(jù)
- Tx3_Ting = 0; //發(fā)送停止
- }
- else
- {
- Tx3_DAT >>= 1; //把最低位送到 CY(益處標(biāo)志位)
- P_TX3 = CY; //發(fā)送一個(gè)bit數(shù)據(jù)
- }
- }
- }
- }
- /********************* INT4中斷函數(shù) *************************/
- void Ext_INT4 (void) interrupt 16
- {
- AUXR &= ~(1<<4); //Timer2 停止運(yùn)行
- T2H = (65536 - (UART3_BitTime / 2 + UART3_BitTime)) / 256; //起始位 + 半個(gè)數(shù)據(jù)位
- T2L = (65536 - (UART3_BitTime / 2 + UART3_BitTime)) % 256; //起始位 + 半個(gè)數(shù)據(jù)位
- AUXR |= (1<<4); //Timer2 開(kāi)始運(yùn)行
- Rx3_Ring = 1; //標(biāo)志已收到起始位
- Rx3_BitCnt = 9; //初始化接收的數(shù)據(jù)位數(shù)(8個(gè)數(shù)據(jù)位+1個(gè)停止位)
-
- INT_CLKO &= ~(1 << 6); //禁止INT4中斷
- T2H = (65536 - UART3_BitTime) / 256; //數(shù)據(jù)位
- T2L = (65536 - UART3_BitTime) % 256; //數(shù)據(jù)位
- }
復(fù)制代碼
匯編語(yǔ)言:
- ;************* 功能說(shuō)明 **************
- ;使用STC15系列的Timer2做的模擬串口. P3.0接收, P3.1發(fā)送, 半雙工.
- ;假定測(cè)試芯片的工作頻率為22118400Hz. 時(shí)鐘為5.5296MHZ ~ 35MHZ.
- ;波特率高,則時(shí)鐘也要選高, 優(yōu)先使用 22.1184MHZ, 11.0592MHZ.
- ;測(cè)試方法: 上位機(jī)發(fā)送數(shù)據(jù), MCU收到數(shù)據(jù)后原樣返回.
- ;串口固定設(shè)置: 1位起始位, 8位數(shù)據(jù)位, 1位停止位, 波特率在范圍如下.
- ;******************************************
- ;UART3_BitTime EQU 9216 ; 1200bps @ 11.0592MHz UART3_BitTime = (MAIN_Fosc / Baudrate)
- ;UART3_BitTime EQU 4608 ; 2400bps @ 11.0592MHz
- ;UART3_BitTime EQU 2304 ; 4800bps @ 11.0592MHz
- ;UART3_BitTime EQU 1152 ; 9600bps @ 11.0592MHz
- ;UART3_BitTime EQU 576 ;19200bps @ 11.0592MHz
- ;UART3_BitTime EQU 288 ;38400bps @ 11.0592MHz
- ;UART3_BitTime EQU 192 ;57600bps @ 11.0592MHz
- ;UART3_BitTime EQU 15360 ; 1200bps @ 18.432MHz
- ;UART3_BitTime EQU 7680 ; 2400bps @ 18.432MHz
- ;UART3_BitTime EQU 3840 ; 4800bps @ 18.432MHz
- ;UART3_BitTime EQU 1920 ; 9600bps @ 18.432MHz
- ;UART3_BitTime EQU 960 ;19200bps @ 18.432MHz
- ;UART3_BitTime EQU 480 ;38400bps @ 18.432MHz
- ;UART3_BitTime EQU 320 ;57600bps @ 18.432MHz
- ;UART3_BitTime EQU 18432 ; 1200bps @ 22.1184MHz
- ;UART3_BitTime EQU 9216 ; 2400bps @ 22.1184MHz
- ;UART3_BitTime EQU 4608 ; 4800bps @ 22.1184MHz
- ;UART3_BitTime EQU 2304 ; 9600bps @ 22.1184MHz
- ;UART3_BitTime EQU 1152 ;19200bps @ 22.1184MHz
- ;UART3_BitTime EQU 576 ;38400bps @ 22.1184MHz
- ;UART3_BitTime EQU 384 ;57600bps @ 22.1184MHz
- UART3_BitTime EQU 192 ;115200bps @ 22.1184MHz
- ;UART3_BitTime EQU 27648 ; 1200bps @ 33.1776MHz
- ;UART3_BitTime EQU 13824 ; 2400bps @ 33.1776MHz
- ;UART3_BitTime EQU 6912 ; 4800bps @ 33.1776MHz
- ;UART3_BitTime EQU 3456 ; 9600bps @ 33.1776MHz
- ;UART3_BitTime EQU 1728 ;19200bps @ 33.1776MHz
- ;UART3_BitTime EQU 864 ;38400bps @ 33.1776MHz
- ;UART3_BitTime EQU 576 ;57600bps @ 33.1776MHz
- ;UART3_BitTime EQU 288 ;115200bps @ 33.1776MHz
- IE2 DATA 0AFH
- AUXR DATA 08EH
- INT_CLKO DATA 08FH
- T2H DATA 0D6H
- T2L DATA 0D7H
- ;===================== 模擬串口相關(guān) ===========================
- P_RX3 BIT P3.0 ; 定義模擬串口接收IO
- P_TX3 BIT P3.1 ; 定義模擬串口發(fā)送IO
- Rx3_Ring BIT 20H.0 ; 正在接收標(biāo)志, 低層程序使用, 用戶程序不可見(jiàn)
- Tx3_Ting BIT 20H.1 ; 正在發(fā)送標(biāo)志, 用戶置1請(qǐng)求發(fā)送, 底層發(fā)送完成清0
- RX3_End BIT 20H.2 ; 接收到一個(gè)字節(jié), 用戶查詢 并清0
- B_RxOk BIT 20H.3 ; 接收結(jié)束標(biāo)志
- Tx3_DAT DATA 30H ; 發(fā)送移位變量, 用戶不可見(jiàn)
- Rx3_DAT DATA 31H ; 接收移位變量, 用戶不可見(jiàn)
- Tx3_BitCnt DATA 32H ; 發(fā)送數(shù)據(jù)的位計(jì)數(shù)器, 用戶不可見(jiàn)
- Rx3_BitCnt DATA 33H ; 接收數(shù)據(jù)的位計(jì)數(shù)器, 用戶不可見(jiàn)
- Rx3_BUF DATA 34H ; 接收到的字節(jié), 用戶讀取
- Tx3_BUF DATA 35H ; 要發(fā)送的字節(jié), 用戶寫入
- ;=================================================================
- RxTimeOutH DATA 36H ;
- RxTimeOutL DATA 37H ;
- Tx3_read DATA 38H ; 發(fā)送讀指針
- Rx3_write DATA 39H ; 接收寫指針
- RX_Lenth EQU 32 ; 接收長(zhǎng)度
- buf3 EQU 40H ; 40H ~ 5FH 接收緩沖
- STACK_POIRTER EQU 0D0H ;堆棧開(kāi)始地址
- ;*******************************************************************
- ;*******************************************************************
- ORG 00H ;reset
- LJMP F_Main
- ORG 63H ;12 Timer2 interrupt
- LJMP F_Timer2_Interrupt
- ORG 83H ;16 INT4 interrupt
- LJMP F_INT4_Interrupt
- ;******************** 主程序 **************************/
- F_Main:
-
- MOV SP, #STACK_POIRTER
- MOV PSW, #0
- USING 0 ;選擇第0組R0~R7
- ;================= 用戶初始化程序 ====================================
- LCALL F_UART_Init ;UART初始化
- SETB EA
-
-
- ;=================== 主循環(huán) ==================================
- L_MainLoop:
- JNB RX3_End, L_QuitRx3 ; 檢測(cè)是否收到一個(gè)字節(jié)
- CLR RX3_End ; 清除標(biāo)志
- MOV A, #buf3
- ADD A, Rx3_write
- MOV R0, A
- MOV @R0, Rx3_BUF ; 寫入緩沖
- MOV RxTimeOutH, #HIGH 1000 ; 裝載超時(shí)時(shí)間
- MOV RxTimeOutL, #LOW 1000 ;
- INC Rx3_write ; 指向下一個(gè)位置
- MOV A, Rx3_write
- CLR C
- SUBB A, #RX_Lenth ; 溢出檢測(cè)
- JC L_QuitRx3
- MOV Rx3_write, #0
- L_QuitRx3:
- MOV A, RxTimeOutL
- ORL A, RxTimeOutH
- JZ L_QuitTimeOut ; 超時(shí)時(shí)間是否非0?
- MOV A, RxTimeOutL
- DEC RxTimeOutL ; (超時(shí)時(shí)間 - 1) == 0?
- JNZ $+4
- DEC RxTimeOutH
- DEC A
- ORL A, RxTimeOutH
- JNZ L_QuitTimeOut
-
- SETB B_RxOk ; 超時(shí), 標(biāo)志接收完成
- ANL AUXR, #NOT (1 SHL 4) ; Timer2 停止運(yùn)行
- ANL INT_CLKO, #NOT (1 SHL 6) ; 禁止INT4中斷
- MOV T2H, #HIGH (65536 - UART3_BitTime) ;數(shù)據(jù)位
- MOV T2L, #LOW (65536 - UART3_BitTime) ;
- ORL AUXR, #(1 SHL 4) ; Timer2 開(kāi)始運(yùn)行
- L_QuitTimeOut:
- JNB B_RxOk, L_QuitTx3 ; 檢測(cè)是否接收OK?
- JB Tx3_Ting, L_QuitTx3 ; 檢測(cè)是否發(fā)送空閑
- MOV A, Tx3_read
- XRL A, Rx3_write
- JZ L_TxFinish ; 檢測(cè)是否發(fā)送完畢
- MOV A, #buf3
- ADD A, Tx3_read
- MOV R0, A
- MOV Tx3_BUF, @R0 ; 從緩沖讀一個(gè)字符發(fā)送
- SETB Tx3_Ting ; 設(shè)置發(fā)送標(biāo)志
- INC Tx3_read ; 指向下一個(gè)字符位置
- MOV A, Tx3_read
- CLR C
- SUBB A, #RX_Lenth
- JC L_QuitTx3 ; 溢出檢測(cè)
- MOV Tx3_read, #0
- SJMP L_QuitTx3
- L_TxFinish:
- CLR B_RxOk
- ANL AUXR, #NOT (1 SHL 4) ; Timer2 停止運(yùn)行
- ORL INT_CLKO, #(1 SHL 6) ; 允許INT4中斷
- L_QuitTx3:
- LJMP L_MainLoop
- ;=================== 主程序結(jié)束 ==================================
- ;========================================================================
- ; 函數(shù): F_UART_Init
- ; 描述: UART初始化程序.
- ; 參數(shù): none
- ; 返回: none.
- ; 版本: V1.0, 2013-11-22
- ;========================================================================
- F_UART_Init:
- MOV Tx3_read, #0
- MOV Rx3_write, #0
- CLR Tx3_Ting
- CLR RX3_End
- CLR Rx3_Ring
- MOV Tx3_BitCnt, #0
- MOV RxTimeOutH, #0
- MOV RxTimeOutL, #0
- CLR B_RxOk
- ANL AUXR, #NOT(1 SHL 4) ; Timer2 停止運(yùn)行
- MOV T2H, #HIGH (65536 - UART3_BitTime) ; 數(shù)據(jù)位
- MOV T2L, #LOW (65536 - UART3_BitTime) ; 數(shù)據(jù)位
- ORL INT_CLKO, #(1 SHL 6) ; 允許INT4中斷
- ORL IE2, #(1 SHL 2) ; 允許Timer2中斷
- ORL AUXR, #(1 SHL 2) ; 1T模式
- RET
- ;======================================================================
- ;========================================================================
- ; 函數(shù): void F_Timer2_Interrupt
- ; 描述: Timer2中斷處理程序.
- ; 參數(shù): None
- ; 返回: none.
- ; 版本: V1.0, 2012-11-22
- ;========================================================================
- F_Timer2_Interrupt:
- PUSH PSW
- PUSH ACC
- JNB Rx3_Ring, L_QuitRx ; 已收到起始位
- DJNZ Rx3_BitCnt, L_RxBit ; 接收完一幀數(shù)據(jù)
-
- CLR Rx3_Ring ; 停止接收
- MOV Rx3_BUF, Rx3_DAT ; 存儲(chǔ)數(shù)據(jù)到緩沖區(qū)
- SETB RX3_End ;
- ANL AUXR, #NOT (1 SHL 4); Timer2 停止運(yùn)行
- ORL INT_CLKO, #(1 SHL 6); 允許INT4中斷
- SJMP L_QuitRx
-
- L_RxBit:
- MOV A, Rx3_DAT ; 把接收的單b數(shù)據(jù) 暫存到 RxShiftReg(接收緩沖)
- MOV C, P_RX3
- RRC A
- MOV Rx3_DAT, A
- L_QuitRx:
- JNB Tx3_Ting, L_QuitTx ; 不發(fā)送, 退出
- MOV A, Tx3_BitCnt
- JNZ L_TxData ; 發(fā)送計(jì)數(shù)器為0 表明單字節(jié)發(fā)送還沒(méi)開(kāi)始
- CLR P_TX3 ; 發(fā)送開(kāi)始位
- MOV Tx3_DAT, Tx3_BUF ; 把緩沖的數(shù)據(jù)放到發(fā)送的buff
- MOV Tx3_BitCnt, #9 ; 發(fā)送數(shù)據(jù)位數(shù) (8數(shù)據(jù)位+1停止位)
- SJMP L_QuitTx
- L_TxData: ; 發(fā)送計(jì)數(shù)器為非0 正在發(fā)送數(shù)據(jù)
- DJNZ Tx3_BitCnt, L_TxBit ; 發(fā)送計(jì)數(shù)器減為0 表明單字節(jié)發(fā)送結(jié)束
- SETB P_TX3 ; 送停止位數(shù)據(jù)
- CLR Tx3_Ting ; 發(fā)送停止
- SJMP L_QuitTx
- L_TxBit:
- MOV A, Tx3_DAT ; 把最低位送到 CY(益處標(biāo)志位)
- RRC A
- MOV P_TX3, C ; 發(fā)送一個(gè)bit數(shù)據(jù)
- MOV Tx3_DAT, A
- L_QuitTx:
- POP ACC
- POP PSW
- RETI
-
- ;===================== INT4中斷函數(shù) ==================================
- F_INT4_Interrupt:
- PUSH PSW
- PUSH ACC
- ANL AUXR, #NOT(1 SHL 4) ;Timer2 停止運(yùn)行
- MOV T2H, #HIGH (65536 - (UART3_BitTime / 2 + UART3_BitTime)) ; 起始位 + 半個(gè)數(shù)據(jù)位
- MOV T2L, #LOW (65536 - (UART3_BitTime / 2 + UART3_BitTime)) ; 起始位 + 半個(gè)數(shù)據(jù)位
- ORL AUXR, #(1 SHL 4) ;Timer2 開(kāi)始運(yùn)行
- SETB Rx3_Ring ; 標(biāo)志已收到起始位
- MOV Rx3_BitCnt, #9 ; 初始化接收的數(shù)據(jù)位數(shù)(8個(gè)數(shù)據(jù)位+1個(gè)停止位)
-
- ANL INT_CLKO, #NOT(1 SHL 6); //禁止INT4中斷
- MOV T2H, #HIGH (65536 - UART3_BitTime) ; 數(shù)據(jù)位
- MOV T2L, #LOW (65536 - UART3_BitTime) ; 數(shù)據(jù)位
- POP ACC
- POP PSW
- RETI
- END
復(fù)制代碼
所有資料51hei提供下載:
使用51單片機(jī)Timer2模擬一個(gè)半雙工串口.rar
(18.4 KB, 下載次數(shù): 12)
2018-11-22 11:16 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
|