C_and_CPP 板


LINE

開發平台(Platform): (Ex: Win10, Linux, ...) Windows 7 編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出) Keil C51 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) reg51.h, stdio.h 問題(Question): 在一個把終端機藉由UART送一個一個字元給8051、再讓8051與LCD溝通使LCD顯示終端機送 的字元的練習中,發現陣列索引使用uchar和uint宣告,得到的結果不同(索引最大到31)。 LCD是16*2顯示,我構想的是在終端機上一個字輸入完後按enter再輸入下一個字,排列滿 LCD第一列16字時就寫到第二列,最高塞滿31字,當輸入超過第31個字時,所有的字往前擠 一位,第一位被捨棄,而第31位放最新輸入的字,以此類推。 餵入的資料(Input): 例: 1234567890abcdef ghijklmnopqrstu_ (_是游標) -->再輸入v(enter) w(enter) x(enter)三個字元 預期的正確結果(Expected Output): 4567890abcdefghi jklmnopqrstuvwx_ 錯誤結果(Wrong Output): vwx_567890abcdef ghijklmnopqrstu 程式碼(Code):(請善用置底文網頁, 記得排版,禁止使用圖檔) #include <reg51.h> #include <stdio.h> (省略LCD1602介面函數) void init_uart(void) { SCON = 0x50; TMOD = 0x20; TCON = 0x40; TH1 = 253; TI = 1; PCON |=0x80; } void main() { unsigned char k; unsigned char MSG[31]; unsigned int MSG_count = 0; init_uart(); initial(); while(1) { if (MSG_count <=30) { scanf("%s", &MSG[MSG_count]); MSG_count++; } else { for (k=0; k<30; k++) MSG[k] = MSG[k+1]; scanf("%s", &MSG[30]); } WriteString(MSG_count, MSG); } } 補充說明(Supplement): 預期結果的部分是由上述程式碼正確得出的,但在debug前我是將標黃色的那欄宣告成 uchar形態,發現送的字超過第31個時會跑到第一位去;debug模式下觀察發現MSG_count會 從30(0x1E)直接跳回1(0x01),進不去else的迴圈,而造成LCD顯示成上述的錯誤結果;然 而改成uint後MSG_count會一直卡在31,符合我的期望。 想不透為什麼,照理來說uchar範圍是0-255,不應該在這出現溢位跑回0而進不了else迴圈 才對?能否有人告知我哪裡有錯誤?感謝。 因為在debug模式中觀察到的行為與LCD顯示相同,故推測中間跟LCD1602的溝通介面應該與 上述錯誤無關,為了方便閱讀,將其省略,若有人懷疑問題源於介面,我會再po上來。 --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 141.113.69.183
※ 文章網址: https://webptt.com/m.aspx?n=bbs/C_and_CPP/M.1534161353.A.22D.html
1F:→ yvb: MSG_count=30 時, scanf("%s", ...); 字串結束字元放到...?! 08/13 20:10
放到MSG[MSG_count=30],請問這步有什麼可能的問題嗎? ※ 編輯: brominelove (141.113.69.183), 08/13/2018 20:23:49
2F:→ Lipraxde: 可能會寫到外面去啊,MSG[n], n = 0~30 08/13 21:05
3F:→ Lipraxde: 你的結束字元就被放到MSG[31]去了 08/13 21:05
4F:→ Lipraxde: 結果就是把你的uchar弄成0了 08/13 21:05
Lipraxde:我理解你的意思了,那請問為什麼令成uint時不會有這現象呢?
5F:→ yvb: 你要的是 scanf("%s"...? scanf("%c"...? getchar()? 還是? 08/13 21:38
yvb: 我想要的是單一字符(0xXX),但我使用%c與getchar無法排除結束字元,會顯示在LCD 上,在keil上使用fflush也不成功,所以最後使用%s,請問有更好的建議嗎? ※ 編輯: brominelove (141.113.69.183), 08/13/2018 21:46:56
6F:→ Lipraxde: 應該是中間被插了空格用來對齊,你會用debugger的話可 08/13 22:02
7F:→ Lipraxde: 以注意看看記憶體位置 08/13 22:02
8F:→ Lipraxde: 我建議練習一下uart中斷處理、在isr裡面手動做處理 08/13 22:06
9F:→ yvb: 用 scanf("%s"... 是讀入字串, 且用空白字元分段(略過), 08/13 22:19
10F:→ yvb: 而不是逐字讀取; 至於如何排除結束字元? 不要印它不行嗎? 08/13 22:20
11F:→ yvb: 意思就是檢查若是結束字元(其實是enter吧?) 就不加MSG_count. 08/13 22:22
12F:→ sarafciel: getchar讀進來是結束字元濾掉就好了吧 08/13 22:25
13F:→ yvb: 這樣 WriteString() 就不會多印出enter符號了. 08/13 22:25
謝謝樓上幾位解說,我弄懂了也解掉bug了 :) ※ 編輯: brominelove (94.218.215.219), 08/14/2018 00:36:18







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Tech_Job站內搜尋

TOP