小編今天筆記一下串口的收發實驗,實驗的靈感來源于對藍牙模塊收發的學習。我們在電路中使用藍牙,其實就是把藍牙看做是一個中轉站,這個中轉站在透傳的模式下,不會對接收到的數據做任何變動,而是直接轉發出去。
那么,我們只要知道單片機串口收發和PC端鍵盤的輸入都是以字符的ASCII碼的形式進行的,PC端收到后顯示則是正常字符的形式
即:
鍵盤鍵入字符(ASCII碼形式)–>單片機收到字符(ASCII碼形式)
敲擊3,實質鍵入0x33–>單片機讀buff收到消息0x33
單片機發送字符(ASCII嗎形式)–>模擬PC收到字符(正常形式顯示)
單片機發送字符3,實質寫buff發0x33–>模擬PC收到后顯示3
廢話少說,上仿真電路圖:
代碼:
main.c
#include #include #define uint unsigned int #define uchar unsigned char #define ulong unsigned long sbit LSA=P2^2; sbit LSB=P2^3; sbit LSC=P2^4; //38譯碼器的片選 bit lanya = 0 ; //藍牙發送標志,單片機發送給PC uchar LanYa_DATA_count=0; //用于后面LnaYa_receive[]數組的各位數賦值,相當于[i]中的i uchar LanYa_receive[4]; //LanYa串口接收數據緩存 uint Receive_Data; //最后單片機接收的整合的數據 ,必須是uint,因為uchar不能超過255 uchar Display_Data[3]; //處理要顯示在數碼管的數據緩沖數組 uchar Computer[4]; //要發給PC的數組 uchar T0RH = 0; //用于后面的TH0賦值 uchar T0RL = 0; //用于后面的TL0賦值 uchar UART_data; /*設一個中間變量,獲取讀sbuf的數據,在串口中斷服務函數中用到*/ uchar code smgduan[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79}; /******************************************************** 函數名稱:void delay(uint i) 函數作用:延時函數 參數說明: ********************************************************/ void delay(uint i){ //延時函數 while(i--); } /******************************************************** 函數名稱:ConfigUart(uint baud) 函數作用:串口初始化函數 參數說明: baud:要設置的波特率 ********************************************************/ void ConfigUart(uint baud){ SCON = 0x50; //配置串口:工作方式1,既可以接,也可以收 TMOD |= 0x20; //配置定時器T1為工作方式2:自動重裝 ;使用T1的目的就是作為波特率發生去的一部分 TH1 = 256 - (11059200/12/32)/baud; //利用公式,加上參數,計算T1重載值 TL1 = TH1; //初值等于重載值 ET1 = 0; //禁止定時器T1中斷(因為它作為波特發生器一部分) TR1 = 1; //啟動T1,即使能T1 EA=1; //開總中斷 ES=1; //開串行口中斷 } /******************************************************** 函數名稱:send_char_com(uchar ch) 函數作用:利用串口發送一個字符 ,串口接/收的其實就是8位的ASCII,即一個字符 參數說明: uchar ch:要發送的字符 ********************************************************/ void send_char_com(uchar ch) { SBUF=ch; //發sbuf,發送字符ch while(TI==0); //TI被硬件置1表示發送成功,跳出死循環 TI=0; //軟件將TI置零,接著準備下次發送 } /******************************************************** 函數名稱:send_string_com(unsigned char *str,unsigned int strlen) 函數作用:利用串口發送字符串 參數說明: unsigned char *str:指針指向字符串的首地址,unsigned int strlen:想發送的長度(這個字符串的字符個數) ********************************************************/ void send_string_com(uchar *str,uint strlen){ uint k=0; do { send_char_com(*(str + k)); /*這里應該是用來指針的首地址+偏移量*/ k++; } while(k < strlen); } /******************************************************** 函數名稱:void ConfigTimer0(unsigned int ms) 函數作用:定時器0初始化函數,ms級定時溢出中斷 參數說明: unsigned int ms:設置定時溢出的ms數 ********************************************************/ void ConfigTimer0(uint ms){ ulong tmp; tmp = 11059200/12; tmp = (tmp * ms)/1000; tmp = 65536 - tmp; tmp = tmp + 18; EA = 1; T0RH = (uchar)(tmp >> 8); T0RL = (uchar)tmp; //上面的這些行直接用就行 TMOD &= 0xF0; TMOD |= 0x01; //設置TMOD的定時器0,方式1,需要重裝初值的 TH0 = T0RH; TL0 = T0RL; ET0 = 1; //開定時器0的中斷允許 TR0 = 1; //開定時器0的使能 } /******************************************************** 函數名稱:void dispiay() 函數作用:數據處理并顯示 參數說明: 無 ********************************************************/ void dispiay(){ uchar i; Display_Data[0]=smgduan[Receive_Data/100]; Display_Data[1]=smgduan[Receive_Data%100/10] | 0x80; //0x80是加個小數點 Display_Data[2]=smgduan[Receive_Data%10]; for(i=0;i<3;i++){ //先分別選中位,循環和switch實現 switch(i){ case 0: LSA=0;LSB=0;LSC=0;break; case 1: LSA=1;LSB=0;LSC=0;break; case 2: LSA=0;LSB=1;LSC=0;break; } P0=Display_Data[2-i]; //選中位后,傳段選數據 delay(100); //延時1ms P0=0x00; //消隱 } } /******************************************************** 函數名稱:void main() 函數作用:數據處理并顯示 參數說明: 無 ********************************************************/ void main(){ //主程序 uchar i; ConfigUart(9600); //波特率設置為9600 ConfigTimer0(5); //定時器T0 5ms while(1){ for(i=0;i<4;i++){ Computer[i]= LanYa_receive[i]; } dispiay(); //顯示在數碼管 if(lanya==1&&(UART_data=='r')){//藍牙標志位置1,表單片機發送,并且讀buff收到回車字符(表示PC端發送結束) send_string_com(Computer,4); //將從PC端接收到的數據發送給PC端 send_char_com('r'); //發送r,表換行 lanya = 0; //藍牙標志清零,單片機發送結束 } } } /******************************************************** 函數名稱:void InterruptTimer0() interrupt 1 函數作用:定時器0中斷服務程序 參數說明: 無 ********************************************************/ void InterruptTimer0() interrupt 1{ static uchar tmr1s = 0; TH0 = T0RH; //重新加載重載值 TL0 = T0RL; tmr1s++; if(tmr1s >= 200) //這個tmr1s變量起緩沖的 { tmr1s = 0; lanya = 1; //將”lanya“標志位置1,準備在main中單片機發送數據 } } /******************************************************** 函數名稱:void uart(void) interrupt 4 函數作用:串口中斷服務程序 參數說明: 無 ********************************************************/ void uart(void) interrupt 4 { uchar a,b,c; if(RI) { UART_data=SBUF; if(UART_data=='r'){ //如果檢測到回車按鍵則得到Receive_Data,將其(PC發送給單片機的數)通過display函數顯示在數碼管上 a = LanYa_receive[0]-0x30; /*這些數都減0x30的原因是:微機原理中,數字0-9,對應ASCII嗎為30H-39H 字母A-Z 對應ASCII碼就是41H-5AH,字母a-z ASCII碼就是61H-7AH 這樣減30H就可以得到顯示正確的數字*/ b = LanYa_receive[1]-0x30; c = LanYa_receive[3]-0x30; Receive_Data = a*100+b*10+c; LanYa_DATA_count=0; } else{ //否則將PC傳來的字符串一個字符一個字符的存放至LanYa_receive[]數組中 LanYa_receive[LanYa_DATA_count]=UART_data; LanYa_DATA_count++; } } RI=0; } 仿真結果 鍵盤鍵入**.則 數碼管顯示*.* PC端顯示**.*并換行循環顯示直至鍵入新的數
上一篇:51單片機實驗1——串行通信(TX/RX)
下一篇:小白學習HC-05藍牙透傳模塊
推薦閱讀
史海拾趣
除了航空領域,龐巴迪公司在鐵路運輸方面也取得了重要進展。其生產的CITYFLO系列自動列車控制系統在全球范圍內得到了廣泛應用。該系統采用了先進的電子技術和算法,實現了列車的自動駕駛和精確控制,大大提高了鐵路運輸的安全性和效率。此外,龐巴迪還生產了各種鐵路車輛和相關電子設備,為全球鐵路運輸業的發展做出了重要貢獻。
以上五個故事展示了龐巴迪公司在電子行業發展中的關鍵歷程和成就。從水上飛機到現代商用噴氣客機,從航空電子系統到鐵路運輸控制系統,龐巴迪憑借其卓越的技術實力和創新能力,在電子行業中樹立了杰出的品牌形象。
面對海洋環境的獨特挑戰,Contrinex推出了海洋系列傳感器。這些傳感器采用全金屬技術,外殼材質為V4A/AISI 316L不銹鋼,防護等級高達IP68/IP69K,能夠抵御惡劣的海洋環境。同時,該系列傳感器還具備卓越的EMC防護性能,能夠滿足各種海洋應用需求。這一創新產品的推出,進一步鞏固了Contrinex在傳感器行業的領先地位。
隨著電子行業的快速發展,町洋不斷投入研發資源,致力于技術創新和產品升級。公司成功開發出了一系列具有高性能、高可靠性和高安全性的接線端子產品,滿足了不同客戶的需求。同時,町洋還積極引進國際先進技術和管理經驗,不斷提升自身的競爭力和市場占有率。
隨著全球半導體行業向中國市場的轉移,明微公司意識到拓展海外市場的重要性。為了加快海外市場拓展步伐,公司積極加強與國際知名企業的合作與交流,引進先進的技術和管理經驗。同時,公司還積極參加國際展會和論壇等活動,提升品牌影響力。這些舉措使明微公司在國際市場上逐漸樹立起良好的口碑和形象。
Harbour Industries成立于1965年,起初主要專注于電纜的生產與銷售。在20世紀60年代末和70年代初期,隨著全球航空航天市場的迅速增長,Harbour敏銳地捕捉到了這一機遇。為了服務這一市場,公司進行了大規模的工廠擴建,并引入了先進的生產設備和技術。這一舉措不僅提升了公司的產能,還確保了產品質量能夠滿足航空領域的高標準。通過不懈努力,Harbour逐漸在航空電纜市場中占據了一席之地。
隨著科技的進步,客戶對電子元器件的性能要求也越來越高。CalRamic Technologies意識到,要想在激烈的市場競爭中脫穎而出,必須不斷進行技術創新。因此,公司投入大量資源進行產品研發,特別是在陶瓷電容器領域取得了顯著的技術突破。他們開發的新型陶瓷電容器不僅體積更小,性能也更加穩定,很快就受到了市場的熱烈歡迎。
前在C6713上,寫過一個簡單的bootloader代碼,但是現在看來,實用價值太低,而且還有錯誤,主要體現在對不同的段的處理上,沒有很好的處理const段落。 現在,想重新寫一個BootLoader的程序,不知道各位能否給點建議! ...… 查看全部問答∨ |
|
1. 切勿輕信他人 職場是一個利益交換的場所,品德好的人往往樹敵眾多,而壞人卻順風順水。你可以不學壞人那樣去害人,但至少要有保護自己的能力。別人要來害你,最簡單 的方式是利用你的善良,其次是因為你輕信于人。而在職場中,信任往往應該 ...… 查看全部問答∨ |
用UART接收報文,一般的單片機都是采用超時(自己在寫的定時器的函數)來判斷一條報文是否結束。 在看STM32的時候,發現USART帶有一個空閑總線的中斷標志,于是想通過這個來判斷,一條報文是否結束。 但,從調試的結果來看,讓人很無語。 通過在 ...… 查看全部問答∨ |
M4 Hanker開發板:uc/GUI的移植(加觸摸功能+心得體會) 發現Triton.zhang老大提供的uc/GUI例程沒有觸摸功能,所以將觸摸功能加入,同時跑了幾個uc/GUI的小例子,因為下周有好多考試,所以沒有進行深入的擴展,不足之處還請見諒!順便請假一周!不然要掛啦!要說uc /GUI的c文件,那叫一個多呀!為了方便編 ...… 查看全部問答∨ |
|
avr studio 6.0 下 mega 64 串口中斷問題 我是AVR 新手,在avr studio 6.0 下學習 mega64 的串口0 ,波特率已經配置成9600,發送函數調試成功,現在調不通中斷方式下的接收程序,程序片段如下,望知道的好友指導指導,謝謝 中斷使能 void Usart0InterruptConfig() { &nb ...… 查看全部問答∨ |