隨著微控制器的使用日益頻繁,用其作前置機進行採集和通訊也常見於各種應用,一般是利用前置機採集各種終端資料後進行處理、儲存,再主動或被動上報給管理站。這種情況下下,採集會需要乙個串列埠,上報又需要另乙個串列埠,這就要求微控制器具有雙串列埠的功能,但我們知道一般的51系列只提供乙個串列埠,那麼另乙個串列埠只能靠程式模擬。
本文所說的模擬串列埠, 就是利用51的兩個輸入輸出引腳如p1.0和p1.1,置1或0分別代表高低電平,也就是串列埠通訊中所說的位,如起始位用低電平,則將其置0,停止位為高電平,則將其置1,各種資料位和校驗位則根據情況置1或置0。至於串列埠通訊的波特率,說到底只是每位電平持續的時間,波特率越高,持續的時間越短。如波特率為9600bps,即每一位傳送時間為1000ms/9600=0.104ms,即位與位之間的延時為為0.104毫秒。微控制器的延時是通過執行若干條指令來達到目的的,因為每條指令為1-3個指令週期,可即是通過若干個指令週期來進行延時的,微控制器常用11.0592m的的晶振,現在我要告訴你這個奇怪數字的來歷。用此頻率則每個指令週期的時間為(12/11.0592)us,那麼波特率為9600bps每位要間融多少個指令週期呢?指令週期s=(1000000/9600)/(12/11.0592)=96,剛好為一整數,如果為4800bps則為96x2=192,如為19200bps則為48,別的波特率就不算了,都剛好為整數個指令週期,妙吧。至於別的晶振頻率大家自已去算吧。
現在就以11.0592m的晶振為例,談談三種模擬串列埠的方法。
方法一:延時法
通過上述計算大家知道,串列埠的每位需延時0.104秒,中間可執行96個指令週期。
#define uchar unsigned char
#define rxd p1_0
#define txd p1_1
#define wrdyn 44 //寫延時
#define rddyn 43 //讀延時
sbit p1_0 = 0x90;
sbit p1_1 = 0x91;
sbit p1_2 = 0x92;
/* 延時程式 */
void delay2cp(unsigned char i)
/* 往串列埠寫乙個位元組 */
void wbyte(uchar input)
//傳送校驗位(無)
//...
txd = (bit)1; //傳送結束位
delay2cp(46);
}/* 從串列埠讀乙個位元組 */
uchar rbyte(void)
//在指定的時間內搜尋結束位。
while(--temp)
return output;
}
此種方法在接收上存在一定的難度,主要是取樣定位存在需較準確,另外還必須知道每條語句的指令週期數。此法可能模擬若干個串列埠,實際中採用它的人也很多,但如果你用keil c,本人不建議使用此種方法,上述程式在p89c52、at89c52、w78e52三種微控制器上實驗通過。
方法二:計數法
51的計數器在每指令週期加1,直到溢位,同時硬體置溢位標誌位。這樣我們就可以通過預置初值的方法讓機器每96個指令週期產生一次溢位,程式不斷的查詢溢位標誌來決定是否傳送或接收下一位。
/* 計數器初始化 */
void s2ini(void)
void wbyte(uchar input)
//傳送校驗位(無)
//...
//傳送結束位
txd = (bit)1;
waittf0();
tr0 = 0;
}/* 查詢計數器溢位標誌位 */
void waittf0( void )
接收的程式,可以參考下一種方法,不再寫出。這種辦法個人感覺不錯,接收和傳送都很準確,另外不需要計算每條語句的指令週期數。
方法三:中斷法
中斷的方法和計數器的方法差不多,只是當計數器溢位時便產生一次中斷,使用者可以在中斷程式中置標誌,程式不斷的查詢該標誌來決定是否傳送或接收下一位,當然程式中需對中斷進行初始化,同時編寫中斷程式。本程式使用timer0中斷。
#define tm0_flag p1_2 //設傳輸標誌位
/* 計數器及中斷初始化 */
void s2ini(void)
/* 接收乙個字元 */
uchar rbyte()
while (!tm0_flag)
tr0 = 0; //停止
timer0
return output;
}/* 中斷1處理程式 */
void inttimer0() interrupt 1
/* 查詢傳輸標誌位 */
void waittf0( void )
另外還需註明的是本文所說的串列埠就是通常的三線制非同步通訊串列埠(uart),只用rxd、txd、gnd。 GPIO口模擬IIC通訊
define sda 254 定義sda所對應的gpio介面編號 define scl 255 定義scl所對應的gpio介面編號 define outp 1 表示gpio介面方向為輸出 define inp 0 表示gpio介面方向為輸入 i2c起始條件 int i2c start i2c終止條件...
C6748的GPIO口配置使用
2018年1月17日更新 這幾天用了創龍的c6748的庫,對於gpio配置十分不爽,我移植了rk6748的庫,用起來十分酸爽,把下面的檔案加入到工程中,然後include標頭檔案後就可以使用。非常好使。以下文章都是基於這個庫的。請配置後使用!以下是原文 主要就是前三句rk6748 pinmuxcon...
07 24 c51串列埠 資料傳送 資料接收
首先是介紹下串列埠的相關暫存器 這裡著重介紹下scon 序列控制暫存器 和它的工作方式。下面是scon各位的意義。在scon中,sm0和sm1的組合決定了序列口的工作方式.在這裡我們串列埠資料傳送和接受用到的是方式1,當ren 1時允許序列口接收資料 得出01010000 所以scon 0x50 而...