請教關於C語言的語法 |
答題得分者是:miyu
|
Maueking
一般會員 發表:1 回覆:5 積分:1 註冊:2002-06-18 發送簡訊給我 |
|
miyu
中階會員 發表:13 回覆:96 積分:91 註冊:2003-05-01 發送簡訊給我 |
引言: 請教各位先進: 小弟現在是用inp的方式在RS232的transaction上將字元讀進來 但是inp似乎只能每次抓取一個字元 若小弟希望一次抓取5個字元的話... 在Turboc裏面還有其他的語法嗎?? 是用inport嗎?? 還是有其它方式 因為一次抓取一個字元,有時PC端會lose掉字元 int lsr = 0x3fd ; while(!(1 & inp(lsr))) { ... }如果你要用polling mode, 要讀幾個字只能polling幾次. Serial port的設計是, 當serial port 收滿8bits以後, 會把資料丟到Base Port 0, 然後把 Base Port 5 bit 0 點起來. 而 turbo c 的 inp, 事實上是 in port byte align 的包裝. 它的意思是, 以某個port number為base, 讀取byte align 的資料 換句話說, 如果你讀 word align, 它是讀到 base port 與 base port 1 的資料. 而不是連續讀 n 次 base port. 我建議你, 要不就放慢速度, 要不就改用ISR. 下面是 ISR sample static int In = 0; static int Out = 0; unsigned char DataBuf[1024]; void interrupt SerialPortISR(void) { unsigned char Byte; do { Byte = inportb(BasePort 5); if (Byte & 1) { DataBuf[In ] = inportb(BasePort); if (In == 1024) In = 0; } } while (Byte & 1); outportb(0x20, 0x20); // ISR end } int main(void) { // Save status, ignore setvect(0x0C, SerialPortISR); // 0x0C = COM1/COM3, 0x0B = COM2/COM4 // Set baud rate, ignore outportb(0x21, (inportb(0x21) & 0xEF)); // SET PIC, COM1/COM3 = 0xEF, COM2/COM4 = 0xE7 outportb(PortBase 1, 0x01); // turn on interrupt, when data come do { unsigned char Ch; if (In != Out) { Ch = DataBuf[Out ]; if (Out == 1024) Out = 0; printf("X, " Ch); } // if key press, break. ignore } outportb(BasePort 1, 0); // turn off interrupt outportb(0x21,(inportb(0x21) | 0x10)); // Mask PIC, COM1/COM3 = 0x10, COM2/COM4 = 0x08 // maybe restore status. ignore }發表人 - Miyu 於 2003/08/11 17:59:20 |
miyu
中階會員 發表:13 回覆:96 積分:91 註冊:2003-05-01 發送簡訊給我 |
|
Maueking
一般會員 發表:1 回覆:5 積分:1 註冊:2002-06-18 發送簡訊給我 |
|
Maueking
一般會員 發表:1 回覆:5 積分:1 註冊:2002-06-18 發送簡訊給我 |
不好意思,baud rate的設定是下列這行嗎??
如果我要設9600,8Bits,Parity Even,Stop Bit 1的話要怎麼設呢??
// Set baud rate, ignore
outportb(0x21, (inportb(0x21) & 0xEF)); // SET PIC, COM1/COM3 = 0xEF, COM2/COM4 = 0xE7
outportb(PortBase 1, 0x01); // turn on interrupt, when data come
|
miyu
中階會員 發表:13 回覆:96 積分:91 註冊:2003-05-01 發送簡訊給我 |
引言: 不好意思,baud rate的設定是下列這行嗎?? 如果我要設9600,8Bits,Parity Even,Stop Bit 1的話要怎麼設呢?? // Set baud rate, ignore outportb(0x21, (inportb(0x21) & 0xEF)); // SET PIC, COM1/COM3 = 0xEF, COM2/COM4 = 0xE7 outportb(PortBase 1, 0x01); // turn on interrupt, when data come那段code只是順手寫的sample, 基本上只是一個示意. 我也不保證能過compiler... XD 寫成 "// xxx, ignore" 的句子, 表示xxx這個動作我省略了, 請你自己補上. 換句話說, set baud rate的動作我省略了. 這個部分有困難嗎? outportb(BasePort 3, 0x80); // SET DLAB ON outportb(BasePort 0, 0x0C); // Set Baud rate - Divisor Latch Low Byte // 0x01 = 115,200 BPS // 0x02 = 57,600 BPS // 0x03 = 38,400 BPS // 0x06 = 19,200 BPS // 0x0C = 9,600 BPS // 0x18 = 4,800 BPS // 0x30 = 2,400 BPS outportb(BasePort 1 , 0x00); // Set Baud rate - Divisor Latch High Byte outportb(BasePort 3 , 0x03); // 8 Bits, No Parity, 1 Stop Bit |
Maueking
一般會員 發表:1 回覆:5 積分:1 註冊:2002-06-18 發送簡訊給我 |
|
miyu
中階會員 發表:13 回覆:96 積分:91 註冊:2003-05-01 發送簡訊給我 |
引言: 再次感謝您的指導~~~~ 勞煩您的費心~~~ 小弟在此不勝感激~~~~ 可否再請您指點關於status的設定~~~ :p 小弟才疏學淺~~~ 若您方便的話~~~ 可否幫我介紹關於使用ISR之類的書籍~~~ Thanks~~~~至少自己找一下資料吧... Serial port的資料, 我剛剛在 google search 一下滿滿都是. 看不懂要問倒是再說 ISR = Interrupt Services Ruutine. 這個部分我大概說一下, 記憶中應該沒什麼中文書會講這個了. 英文/日文書倒是還有... 說穿了其實就跟一般的function沒什麼不一樣, 只是最後是用 iret 回返而已. 在x86 segment 架構下, call 有分為far call 跟 near call 當碰到near call的instruction時, cpu 會把這個instruction 分解成為: 1. push current ip 2. change current ip to target address ( = jump) 當碰到far call的時候, 情況也是類似: 1. push current cs 2. push current ip 3. change current cs, ip to target address ( = far jump) cpu 看到 ret 這個 instruction, 他會pop 一個word, 然後把他塞到 ip 去. cpu 看到 retf 這個 instrction 時, 他會 pop 一個 word, 塞到 ip, 再 pop 一個 word 塞到 cs 去. 當然, call(far) 跟 ret(far) 不一定要有成對的關係, 只不過如果失控了, 程式就不知道跑哪去了. 但是, 如果你有寫過病毒, debugger, monitor program (類似一個小型的OS core), exec file decoder 一類的東西就知道, 其實常常有機會自己去填 stack 然後 return, 或是去偷換 stack 裡面的東西. 而 ISR -- interrupt services routine 最後是用 iret 回返. 你其實可以把 ISR 看成是需要儲存 flag status 的 far call fnction. iret 會作這樣的動作: 1. pop word, 然後塞到 ip 去 2. pop word, 然後塞到 cs 去 3. pop word, 然後塞到 flag 去 重點是在 3. , 這說明了 iret 會 restore flag. 而一般呼叫 isr, 則是透過 int xx 指令 (0xCD, 0x??) int xx 會作這樣的動作: 1. push flag 2. push cs 3. push ip 3. far jump to 0:[xx*4] 在古早的dos年代, c compiler 為了那個架構而有相應的extened keyword: 'interrupt' 這個keyword等於是告訴compiler, 最後離開的時候要放 iret 而不是 ret. 如果有空又有心, 其實可以去 intel 抓那三本 pdf 電子書 "IA-32 Intel Architecture Software Developer's Manual" Vol.1 Basic Architecture Vol.2 Instruction Set Reference Vol.3 System Programming Guide 第二本當成參考手冊查閱指令很好用, 有空不妨把給個指令看一次, 有很多指令可以結省你的時間. 第一跟第三本挑幾個架構的重點看, 英文如我這般破, 唸到要暑修的人都可以白天上班, 用半夜的時間一個月看完了... 我想應該英文文法不會很刁難才是.. |
Maueking
一般會員 發表:1 回覆:5 積分:1 註冊:2002-06-18 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |