C51問答
一、#pragma asm是什么意思? | |||||||||||||||||||||||||||
二、一個(gè) hex to bcd 的算法程序 HEX_BCD:CLR A MOV 30H,A MOV 31H,A MOV 32H,A MOV R2,#15 H_B0: MOV A,R1 RLC A MOV R1,A MOV A,R0 RLC A MOV R0,A MOV A,32H RLC A ACALL BCD_ADJ MOV 32H,A MOV A,31H RLC A ACALL BCD_ADJ MOV 31H,A MOV A,30H RLC A ACALL BCD_ADJ MOV 30H,A DJNZ R2,H_B0 MOV A,R0 RLC A MOV A,32H RLC A MOV 32H,A MOV A,31H RLC A MOV 31H,A MOV A,30H RLC A MOV 30H,A RET BCD_ADJ:PUSH PSW PUSH ACC CJNE A,#50H,$+2 JC B1 POP ACC ADD A,#30H PUSH ACC B1: ANL A,#0FH CJNE A,#5,$+2 JC B2 POP ACC ADD A,#3 PUSH ACC B2: POP ACC POP PSW RET | |||||||||||||||||||||||||||
三、有關(guān)單片機(jī)ALE引腳的問題 "單片機(jī)不訪問外部鎖存器時(shí)ALE端有正脈沖信號(hào)輸出,此頻率約為時(shí)鐘振蕩頻率的1/6.每當(dāng)訪問 外部數(shù)據(jù)存儲(chǔ)器是,在兩個(gè)機(jī)器周期中ALE只出現(xiàn)一次,即丟失一個(gè)ALE脈沖."這句話是不是有毛 病.我覺得按這種說法,應(yīng)該丟失3個(gè)ALE脈沖才對(duì),我一直想不通是怎么回事,希望大蝦們幫幫我. 小弟感激涕零. 答: 其他所有指令每6個(gè)機(jī)器周期發(fā)出一個(gè)ALE,而MOVX指令占用12個(gè)機(jī)器周期只發(fā)出一個(gè)ALE | |||||||||||||||||||||||||||
四、如何將一個(gè)INT型數(shù)據(jù)轉(zhuǎn)換成2個(gè)CHAR型數(shù)據(jù)? 經(jīng)keil優(yōu)化后,char1=int1/256,char2=int1%256或char1=int1>>8,char2=int10x00ff效率是一樣的。 | |||||||||||||||||||||||||||
五、在KEIL C51上仿真完了,怎樣生成HEX文件去燒寫?? 右鍵點(diǎn)項(xiàng)目中Target 1,選第二個(gè),在OUTPUT中選中CREAT HEX | |||||||||||||||||||||||||||
六、typedef 和 #define 有何不同?? typedef 和 #define 有何不同》》》 如 typedef unsigned char UCHAR ; #define unsigned char UCHAR ; typedef命名一個(gè)新的數(shù)據(jù)類型,但實(shí)際上這個(gè)新的數(shù)據(jù)類型是已經(jīng)存在的,只不過是定義了 一個(gè)新的名字. #define只是一個(gè)標(biāo)號(hào)的定義. 你舉的例子兩者沒有區(qū)別,但是#define還可以這樣用 #define MAX 100 #define FUN(x) 100-(x) #define LABEL 等等,這些情況下是不能用typedef定義的 | |||||||||||||||||||||||||||
七、請(qǐng)問如何設(shè)定KELC51的仿真工作頻(時(shí)鐘) 用右鍵點(diǎn)擊左邊的的target 1,然后在xtal一欄輸入 | |||||||||||||||||||||||||||
八、不同模塊怎樣共享sbit變量,extern不行? 把SBIT定義單獨(dú)放到一個(gè).H中,每個(gè)模塊都包含這個(gè).h文件 | |||||||||||||||||||||||||||
九、C51中對(duì)于Px.x的訪問必須自己定義嗎? 是的。 如sbit P17 =0x97;即可定義對(duì)P1.7的訪問 | |||||||||||||||||||||||||||
十、SWITCH( )語句中表達(dá)式不可以是位變量對(duì)嗎? 可以用位變量: #include #include void main() { bit flag; flag=0; switch(flag) { case '0':{printf("0n");break;} case '1':{printf("1n");break;} default:break; } } bit 變量只有兩種狀態(tài),if 語句足夠啦,!!! | |||||||||||||||||||||||||||
十一、const常數(shù)聲明占不占內(nèi)存??? const 只是用來定義“常量”,所占用空間與你的定義有關(guān),如: const code cstStr[] ={"abc"}; 占用代碼空間;而如: const char data cstStr[] ={"abc"}; 當(dāng)然占用內(nèi)存空間。 另外,#define 之定義似乎不占用空間。 | |||||||||||||||||||||||||||
十二、philips的單片機(jī)P89C51RD+的擴(kuò)展RAM在C51中如何使用? 試一試將auxr.1清0,然后在c語言中直接聲明xdata類型的變量 | |||||||||||||||||||||||||||
十三、BUG of Keil C51 程序中用如下語句: const unsigned char strArr[] ={"數(shù)學(xué)"}; 結(jié)果發(fā)現(xiàn)strArr[] 內(nèi)容為 {0xCA,0xD1,0xA7},真奇怪! 凡是有0xfd,則會(huì)通通不見了,所以只能手工輸入內(nèi)碼了,例如 uchar strArr[]= {0xCA,0xfd,0xd1,0xa7}(用Ultraedit會(huì)很方便)。 | |||||||||||||||||||||||||||
十四、Keil C51中如何實(shí)現(xiàn)代碼優(yōu)化? 菜單Project下Option for target "Simulator"的C51. 看到Code optimization了嗎? | |||||||||||||||||||||||||||
十五、請(qǐng)教c的!和 ~ 符號(hào)有甚區(qū)別?? !是邏輯取反,~是按位取反。 | |||||||||||||||||||||||||||
十六、c51編程,讀端口,還要不要先輸出1? 我怎么看到有的要,有的不要,請(qǐng)高手給講講,到底咋回事?謝了 要輸出1的,除非你能保證之前已經(jīng)是1,而中間沒有輸出過其他值。 | |||||||||||||||||||||||||||
十七、當(dāng)定時(shí)器1(T1)用于產(chǎn)生波特率時(shí),P3^5還是否可以用作正常的I/O口呢? p3.5完全可以當(dāng)普通的io使用 | |||||||||||||||||||||||||||
十八、C51中 INT 轉(zhuǎn)換為 2個(gè)CHAR? 各位高手: C51中 INT 轉(zhuǎn)換為 CHAR 如何轉(zhuǎn)換諸如: X =LOW(Z); Y =HIGH(Z); 答: x=(char)z; y=(char)(z>>8); | |||||||||||||||||||||||||||
十九、如果我想使2EH的第7位置1的話,用位操作可以嗎? 現(xiàn)在對(duì)位操作指令我一些不太明白請(qǐng)各位多多指教: 如 SETB 07H 表示的是20H.7置1,對(duì)嗎?(我在一本書上是這么看到的) 那么如果我想使2EH的第7位置1的話,象我舉的這個(gè)例子怎么表示呢?謝謝! SETB 77H setb (2eh-20h)*8+7 20h-2fh每字節(jié)有8個(gè)可位操作(00h-7fh),其它RAM不可位直接操作 | |||||||||||||||||||||||||||
二十、char *addr=0xc000 和char xdata *addr=0xc000有何區(qū)別? char *addr=0xc000; char xdata *addr=0xc000; 除了在內(nèi)存中占用的字節(jié)不同外,還有別的區(qū)別嗎? char *addr=0xc000; 是通用定義,指針變量 addr 可指向任何內(nèi)存空間的值; char xdata *addr=0xc000; 指定該指針變量只能指向 xdata 中的值; 后一種定義中該指針變量(addr)將少占用一個(gè)存儲(chǔ)字節(jié)。 uchar xdata *addr=0xc000;指針指向外ram; 如果:data uchar xdata *addr=0xc000;指針指向外ram但指針本身存在于內(nèi)ram(data) 中 以此類推可以idata uchar xdata *addr=0xc000;pdata uchar xdata *addr=0xc000; data uchar idata *addr=0xa0;..... .... | |||||||||||||||||||||||||||
二十一、while(p1_0)的執(zhí)行時(shí)間? 假設(shè),P1_0為單片機(jī)P1口的第一腳,請(qǐng)問, while(P1_0) { P1_0=0; } while(!P1_0) { P1_0=1; } 以上代碼,在KEIL C中,需要多長(zhǎng)時(shí)間,執(zhí)行完。能具體說明while(P1_0)的執(zhí)行時(shí)間嗎? 仿真運(yùn)行看看就知道了, 我仿真了試了一下,約14個(gè)周期 | |||||||||||||||||||||||||||
二十二、怎樣編寫C51的watchdog程序? 各位大蝦,我用KEIL C51 編寫了一個(gè)帶外部開門狗的程序,可程序無法運(yùn)行起來,經(jīng)過查 找,發(fā)現(xiàn)程序在經(jīng)過C51編譯后,在MAIN()函數(shù)的前部增加了一端初始化程序,等到進(jìn)入 主程序設(shè)置開門狗時(shí),開門狗已經(jīng)時(shí)間到,將我的程序復(fù)位了,請(qǐng)問我怎樣才能修改這一端 初始花程序,使他一運(yùn)行,就設(shè)置開門狗? 可以在startup.a51中加入看門狗刷新指令,當(dāng)然用匯編,然后重新編譯startup.a51 ,將他和你的程序連接即可。新的startup.a51會(huì)自動(dòng)代替系統(tǒng)默認(rèn)的啟動(dòng)模塊。 | |||||||||||||||||||||||||||
二十三、keil C51 怎樣把修改的startup.a51 加到工程文件中 直接加入即可 注意不要改動(dòng)?STACK,?C_START,?C_STARTUP等符號(hào)。startup.a51直接加入項(xiàng)目,不用修改也可??稍趦?nèi)面自己修改匯編的一些限制或堆棧指針。 | |||||||||||||||||||||||||||
二十四、關(guān)于波特率的設(shè)置 我在設(shè)定串口波特率時(shí)發(fā)現(xiàn)一個(gè)問題:在晶體震蕩器為11.0592MHz時(shí),若設(shè)9600BPS的話, TH1=0XFD,TL1=0XFD,而要設(shè)19200BPS的話,TH1、TL1有否變化,如果沒變,為什么? 如果變了,又為什么?(因?yàn)槲铱磿蟼z個(gè)是一樣的),希望大家點(diǎn)撥。 答: 當(dāng)電源控制寄存器(PCON)第BIT7(SMOD)為1時(shí)波特率加倍。 TH1和TL1的值不變. | |||||||||||||||||||||||||||
二十五、如何在C中聲明保留這部分RAM區(qū)不被C使用? 我不知道在C源程序中怎么控制這個(gè),但在匯編程序中加入下面一段就行: DSEG AT 20H AA: DS 10 這樣C51就不會(huì)占用20H--29H了 或者在c51里這樣定義: uchar data asm_buff[10] _at_ 0x20; | |||||||||||||||||||||||||||
二十六、問浮點(diǎn)運(yùn)算問題 我在用C51時(shí)發(fā)現(xiàn)它對(duì)傳遞浮點(diǎn)參數(shù)的個(gè)數(shù)有限制,請(qǐng)問: 1)參數(shù)是以全局變量的形式傳遞的,請(qǐng)問以全局變量的形式傳遞的參數(shù)也有限制嗎? 2)這種傳遞浮點(diǎn)參數(shù)的限制有多少呢? 3)float*float的結(jié)果是float類型還是double類型?能否直接賦值給float類型的變量? 答: 由于KEIL C51的參數(shù)傳遞是通過R0-R7來傳遞的,所以會(huì)有限制。 不過KEIL提供了一個(gè)編譯參數(shù),可以支持更多參數(shù)的傳遞。具體 的內(nèi)容見KEIL的PDF文檔。 我建議你把多個(gè)要傳遞的參數(shù)定義到指針或結(jié)構(gòu)體中去,傳遞參 數(shù)通過指針或結(jié)構(gòu)進(jìn)行,這樣好一些。 第3個(gè)問題回答是YES,你自己試試不就知道了。 | |||||||||||||||||||||||||||
二十七、如何在某一個(gè)地址定義ram 用_at_ 命令,這樣可以定位靈活一點(diǎn)的地址 uchar xdata dis_buff[16] _at_ 0x6020 ;//定位RAM 將dis_buff[16]定位在0x6020開始的16個(gè)字節(jié) | |||||||||||||||||||||||||||
二十八、keil c中,用什么函數(shù)可以得到奇偶校驗(yàn)位? 例如32位數(shù)據(jù),將四個(gè)字節(jié)相互異或后檢查P即可,若耽心P被改變,可用內(nèi)嵌匯編。 #include unsigned char parity(unsigned char x){ x^=x; if(P)return(1); else return(0); } unsigned char parity2(unsigned int x){ #pragma asm mov a,r7 xrl ar6,a #pragma endasm if(P)return(1); else return(0); } |
評(píng)論