中文字幕无码不卡一区二区三区_少妇被又大又粗又爽毛片久久黑人_91精品国产在热久久无毒不卡_久久久久久亚洲综合网站

技術(shù)熱線: 4007-888-234

專注差異化嵌入式產(chǎn)品解決方案 給智能產(chǎn)品定制注入靈魂給予生命

提供開發(fā)工具、應(yīng)用測(cè)試 完善的開發(fā)代碼案例庫(kù)分享

從全面的產(chǎn)品導(dǎo)入到強(qiáng)大技術(shù)支援服務(wù) 全程貼心伴隨服務(wù),創(chuàng)造無(wú)限潛能!

技術(shù)支持

從一個(gè)簡(jiǎn)單的AD轉(zhuǎn)換程序(C語(yǔ)言)想開去

更新時(shí)間: 2019-03-23

十年專注單片機(jī)方案開發(fā)的方案公司英銳恩,分享從一個(gè)簡(jiǎn)單的A/D轉(zhuǎn)換程序(C語(yǔ)言)想開去。英銳恩現(xiàn)提供服務(wù)產(chǎn)品涉及主控芯片:8位單片機(jī)、16位單片機(jī)、32位單片機(jī)及各類運(yùn)算放大器等。

從一個(gè)簡(jiǎn)單的A/D轉(zhuǎn)換程序(C語(yǔ)言)想開去

從一個(gè)簡(jiǎn)單的A/D轉(zhuǎn)換程序(C語(yǔ)言)想開去以下是一個(gè)A/D轉(zhuǎn)換程序,所用芯片是16F72 unsigned char adc(void) //使用RA0,VREF=RA3 { unsigned char i; ADCON1=0x05; ADCON0=0x40; ADON=1; i=0x20; while(i--) //等待一段時(shí)間(A/D采樣) ADGO=1; //啟動(dòng)A/D轉(zhuǎn)換 while(ADGO) //等待A/D轉(zhuǎn)換完成 return(ADRES); //取結(jié)果返回 } 第一個(gè)問(wèn)題:網(wǎng)上經(jīng)常有人問(wèn)“會(huì)C語(yǔ)言后還要學(xué)匯編嗎?” 第二個(gè)問(wèn)題:這個(gè)程序是否還有問(wèn)題?要回答第一個(gè)問(wèn)題,先看一下編譯后的程序,特別是while(i--)這一句 14: unsigned char adc(void) //使用RA0,VREF=RA3 15: { unsigned char i; 0004ED 3005 MOVLW 0x5 16: ADCON1=0x05; 0004EE 1683 BSF 0x3, 0x5 0004EF 1303 BCF 0x3, 0x6 0004F0 09F MOVWF 0x1f 17: ADCON0=0x40; 0004F1 3040 MOVLW 0x40 0004F2 1283 BCF 0x3, 0x5 0004F3 09F MOVWF 0x1f 18: ADON=1; 0004F4 141F BSF 0x1f, 0 19: i=0x20; 0004F5 3020 MOVLW 0x20 0004F6 0A1 MOVWF 0x21 20: while(i--) //等待一段時(shí)間(A/D采樣) 0004F7 2CFB GOTO 0x4fb 0004FB 1283 BCF 0x3, 0x5 0004FC 1303 BCF 0x3, 0x6 0004FD 3A1 DECF 0x21, F 0004FE F21 INCFSZ 0x21, W 0004FF 2D01 GOTO 0x501 000500 2D02 GOTO 0x502 000501 2CF8 GOTO 0x4f8 21: ADGO=1; //啟動(dòng)A/D轉(zhuǎn)換 0004F8 1283 BCF 0x3, 0x5 0004F9 1303 BCF 0x3, 0x6 0004FA 151F BSF 0x1f, 0x2 22: while(ADGO) //等待A/D轉(zhuǎn)換完成 000502 2D07 GOTO 0x507 000507 1283 BCF 0x3, 0x5 000508 1303 BCF 0x3, 0x6 000509 191F BTFSC 0x1f, 0x2 00050A 2D0C GOTO 0x50c 00050B 2D0D GOTO 0x50d 00050C 2D03 GOTO 0x503 23: return(ADRES); //取結(jié)果返回 000503 1283 BCF 0x3, 0x5 000504 1303 BCF 0x3, 0x6 000505 81E MOVF 0x1e, W 000506 2D0D GOTO 0x50d 24: } 00050D 1303 BCF 0x3, 0x6

把while(i--)改成while(--i)后再編譯 20: while(--i) //等待一段時(shí)間(A/D采樣) 0004F8 2CFC GOTO 0x4fc 0004FC 1283 BCF 0x3, 0x5 0004FD 1303 BCF 0x3, 0x6 0004FE BA1 DECFSZ 0x21, F 0004FF 2D01 GOTO 0x501 000500 2D02 GOTO 0x502 000501 2CF9 GOTO 0x4f9 21: ADGO=1; //啟動(dòng)A/D轉(zhuǎn)換 0004F9 1283 BCF 0x3, 0x5 0004FA 1303 BCF 0x3, 0x6 0004FB 151F BSF 0x1f, 0x2 22: while(ADGO) //等待A/D轉(zhuǎn)換完成 000502 2D07 GOTO 0x507 編譯后程序更簡(jiǎn)單更易理解,從這個(gè)例子可看出熟悉匯編可以編出更高效的C

第二個(gè)問(wèn)題,其實(shí)本程序是有問(wèn)題的,最大問(wèn)題出在while(--i)和while(ADGO) 應(yīng)改成如下寫法: unsigned char adc(void) //使用RA0,VREF=RA3 { unsigned char i; ADCON1=0x05; ADCON0=0x40; ADON=1; i=0x20; while(--i){} //等待一段時(shí)間(A/D采樣) ADGO=1; //啟動(dòng)A/D轉(zhuǎn)換 while(ADGO){} //等待A/D轉(zhuǎn)換完成 return(ADRES); //取結(jié)果返回 }

20: while(--i){} //等待一段時(shí)間(A/D采樣) 0004F9 2CFA GOTO 0x4fa 0004FA 1283 BCF 0x3, 0x5 0004FB BA1 DECFSZ 0x21, F 0004FC 2CFE GOTO 0x4fe 0004FD 2CFF GOTO 0x4ff 0004FE 2CFA GOTO 0x4fa 21: ADGO=1; //啟動(dòng)A/D轉(zhuǎn)換 0004FF 1283 BCF 0x3, 0x5 000500 1303 BCF 0x3, 0x6 000501 151F BSF 0x1f, 0x2 22: while(ADGO){} //等待A/D轉(zhuǎn)換完成 000502 2D03 GOTO 0x503 000503 1283 BCF 0x3, 0x5 000504 

1303 BCF 0x3, 0x6 000505 191F BTFSC 0x1f, 0x2 000506 2D08 GOTO 0x508 000507 2D09 GOTO 0x509 000508 2D03 GOTO 0x503 23: return(ADRES); //取結(jié)果返回 000509 1283 BCF 0x3, 0x5 00050A 1303 BCF 0x3, 0x6 00050B 81E MOVF 0x1e, W 00050C 2D0D GOTO 0x50d 24: } 00050D 1303 BCF 0x3, 0x6

第三個(gè)問(wèn)題,為什么在判斷語(yǔ)句后連著有三個(gè)GOTO?而我們用匯編編寫時(shí)只一個(gè)GOTO就夠了。?

給你看看我編譯的結(jié)果

1: #include 2: 3: unsigned char adc(void) //使用RA0,VREF=RA3 4: { unsigned char i; 0007F0 3005 MOVLW 0x5 5: ADCON1=0x05; 0007F1 1683 BSF 0x3, 0x5 0007F2 1303 BCF 0x3, 0x6 0007F3 09F MOVWF 0x1f 6: ADCON0=0x40; 0007F4 3040 MOVLW 0x40 0007F5 1283 BCF 0x3, 0x5 0007F6 09F MOVWF 0x1f 7: ADON=1; 0007F7 141F BSF 0x1f, 0 8: i=0x20; 0007F8 3020 MOVLW 0x20 0007F9 0A0 MOVWF 0x20 9: while(--i); //等待一段時(shí)間(A/D采樣) 0007FA BA0 DECFSZ 0x20, F 0007FB 2FFA GOTO 0x7fa 10: ADGO=1; //啟動(dòng)A/D轉(zhuǎn)換 0007FC 151F BSF 0x1f, 0x2 11: while(ADGO); //等待A/D轉(zhuǎn)換完成 0007FC 191F BTFSC 0x1f, 0x2 0007FD 2FFC GOTO 0x7fc 12: return(ADRES); //取結(jié)果返回 0007FE 81E MOVF 0x1e, W 13: } 0007FF 008 RETURN

你把優(yōu)化關(guān)掉了,打開的步驟: Project -> Build Options -> Project 在Build Options窗口里點(diǎn)PICC Compiler 將Enable assembler optimization選中,然后再編譯。不要小看PICC哦!另,你程序里的明顯錯(cuò)誤,while(i--)后面要加分號(hào),while(ADGO)后面也要加分號(hào)。

優(yōu)化的結(jié)果居然與我寫的匯編一樣,一條都不多,一條都不少。為什么while(--i)后面未加分號(hào)時(shí)編譯,鏈接都通過(guò)?PICC應(yīng)該提示我呀, 1:while(--i)后面未加分號(hào)時(shí),編譯沒(méi)錯(cuò)誤,但程序的邏輯是錯(cuò)的。 2:改成while(--i){}時(shí),程序的邏輯是正確的 3:while(--i);表示什么?我遇到這種情況總寫成 while(--i){} 4:再次感謝

{} ;都可以的

沒(méi)有操作的時(shí)候全部是空操作,所以編譯后就兩條。很多說(shuō)c效率低的都是因?yàn)榻Y(jié)構(gòu)差,對(duì)自己寫的源碼優(yōu)化差導(dǎo)致容量變大。可以這么說(shuō),不熟練的使用者用兩種方式變出來(lái)的代碼差不多大小,c可能要略小一些,也就是對(duì)數(shù)據(jù)結(jié)構(gòu)和MCU特點(diǎn)一無(wú)所知。中等熟練的,也就是對(duì)數(shù)據(jù)結(jié)構(gòu)比較清楚,比較熟悉MCU特點(diǎn),代碼會(huì)很接近。只有真正的匯編高手,也就是說(shuō)用了多年匯編,非常熟悉MCU本身,對(duì)算法和數(shù)據(jù)結(jié)構(gòu)很清楚才可能做到小!不信大家可以比一比,當(dāng)然硬要摳那種三五個(gè)字節(jié)的沒(méi)辦法比。 10%以上誤差很難。

又,不要認(rèn)為c編譯器弱智, i=j/256;在c中一樣會(huì)編譯成直接被賦成高字節(jié)或者右移8位!類似的例子太多了,編譯了看看就知道。

404
返回首頁(yè) |  返回上一頁(yè)
禹城市| 新兴县| 青川县| 盈江县| 秦皇岛市| 宽城| 灵石县| 宜君县| 栾川县| 广平县| 航空| 南安市| 舞钢市| 中西区| 望都县| 东乡族自治县| 永泰县| 胶州市| 广灵县| 邻水| 德钦县| 肃北| 云林县| 云浮市| 英吉沙县| 江门市| 田东县| 越西县| 新巴尔虎左旗| 杭锦后旗| 丰台区| 剑河县| 花莲市| 清流县| 当雄县| 绍兴市| 武宁县| 都江堰市| 泸西县| 武功县| 开江县|