如何向單片機(jī)寫字符串
本文引用地址:http://cafeforensic.com/article/201611/315789.htm 單片機(jī)實(shí)現(xiàn)接收從電腦發(fā)送過(guò)來(lái)的字符串的方法 很多朋友會(huì)碰到這個(gè)問(wèn)題:?jiǎn)纹瑱C(jī)接收從電腦串口發(fā)送出來(lái)的一串字符串,卻只能接收到第一個(gè)字符,其他的都丟失了或者是接收到的是亂碼,卻不知道是什么原因。其實(shí),那是因?yàn)椋m然單片機(jī)的是全雙工串口,但是串口的緩沖區(qū)(SBUF)卻一般只有一個(gè)字節(jié),即1Byte,遠(yuǎn)沒(méi)有像電腦串口的緩沖區(qū)以KB計(jì)算那么大,并且,單片機(jī)的處理速度是很有限的,試想一下,假如要求一串字符串以9600bps的速率,一個(gè)起始位,一個(gè)結(jié)束位,無(wú)校正位,相當(dāng)于960Byte/s傳輸?shù)絾纹瑱C(jī),單片機(jī)要是能夠全部接收的話,那么單片機(jī)接收和處理一個(gè)字節(jié)的時(shí)間僅為約1ms的時(shí)間。這說(shuō)明了,如果單片機(jī)的處理速度不夠快,還沒(méi)有將接收到的上一幀數(shù)據(jù)及時(shí)轉(zhuǎn)送到單片機(jī)的RAM中,而電腦串口又傳輸過(guò)來(lái)一幀新的數(shù)據(jù),這幀新的數(shù)據(jù)就會(huì)把單片機(jī)的串口輸入緩沖區(qū)的SBUF給刷新掉,或者說(shuō)單片機(jī)壓根就沒(méi)有接收到新的一幀數(shù)據(jù),造成了數(shù)據(jù)的丟失或接收到亂碼。 如果需要單片機(jī)接收到從串口發(fā)送過(guò)來(lái)的一段很長(zhǎng)的字符串,并且能夠都正常接收和顯示,這在網(wǎng)上還找不到例子。 在這里,筆者提供了一種方法,通過(guò)單片機(jī)內(nèi)部最高中斷等級(jí)的中斷源不斷的查詢從電腦串口發(fā)送過(guò)來(lái)的字符,并及時(shí)將接收到的字符串通過(guò)外接的1602顯示屏顯示出來(lái)。 這里用最為常見的51單片機(jī)作為例程,因?yàn)?1單片機(jī)處理速度比較慢,所以需要將電腦串口發(fā)送速率調(diào)整為最低的600bps,那么單片機(jī)端接收和處理一個(gè)字符的時(shí)間約要求為14ms左右,基本足夠了。這個(gè)14ms間隔的定時(shí)處理和查詢工作,由單片機(jī)的最高等級(jí)內(nèi)部中斷源來(lái)控制,以保證電腦發(fā)送過(guò)來(lái)的每個(gè)字符單片機(jī)都能及時(shí)的去處理。 //1602實(shí)時(shí)顯示單片機(jī)串口接收到電腦串口發(fā)送的字符串 //波特率600bps由T2中斷產(chǎn)生,晶振12M //最高等級(jí)中斷T0負(fù)責(zé)定時(shí)查詢串口輸入SBUF //作者:小宣-天堂雨林博客blog.sina.com.cn/acerCopyright@2009 //接線注釋: //P2.0-P2.7:LCD并行接口P0-P7 //P3.2-P3.4:LCD的RS、RW、E //P3.0、P3.1:編程串口RXD、TXD #include unsigned char receive[32]; unsigned char k; sbit rs=P3^2; sbit rw=P3^3; sbit e =P3^4; void delay1ms(unsigned int f) { } void receivem(void) { } void timer_int(void) { TMOD=0x11;//00010001 SCON =0x50; T2CON=0x30; RCAP2H=0xFD; RCAP2L=0x8F; EA=1; TR0=1; TR1=0; TR2=1; ET0=ET1=ET2=1; } void time0(void) interrupt 1 using 1 { TH0=0xCD; TL0=0x50; receivem();//定時(shí)將SBUF接收 } void write_com(unsigned char com) { } void write_da { } void lcd_int(void) { } void dis(void) { unsigned char i; if(k>0 && k<16) { write_com(0x80); for(i=0;i } if(k>=16 && k<32) { write_com(0xC0); for(i=16;i } } void main() { timer_int(); lcd_int(); write_com(0x01); while(1) {dis();} } |
評(píng)論