新聞中心

        C51問答

        作者: 時間:2011-02-27 來源:網絡 收藏

        一、#pragma asm是什么意思?
        #pragma asm
        MOV P1,R7
        NOP
        NOP
        MOV P1,#0
        #pragma endasm
        實際上就是一個在C51中內嵌匯編語言的開關

        二、一個 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

        三、有關ALE引腳的問題
        "不訪問外部鎖存器時ALE端有正脈沖信號輸出,此頻率約為時鐘振蕩頻率的1/6.每當訪問
        外部數據存儲器是,在兩個機器周期中ALE只出現一次,即丟失一個ALE脈沖."這句話是不是有毛
        病.我覺得按這種說法,應該丟失3個ALE脈沖才對,我一直想不通是怎么回事,希望大蝦們幫幫我.
        小弟感激涕零.
        答:
        其他所有指令每6個機器周期發出一個ALE,而MOVX指令占用12個機器周期只發出一個ALE

        四、如何將一個INT型數據轉換成2個CHAR型數據?
        經keil優化后,char1=int1/256,char2=int1%256或char1=int1>>8,char2=int10x00ff效率是一樣的。

        五、在KEIL C51上仿真完了,怎樣生成HEX文件去燒寫??
        右鍵點項目中Target 1,選第二個,在OUTPUT中選中CREAT HEX

        六、typedef 和 #define 有何不同??
        typedef 和 #define 有何不同》》》 如
        typedef unsigned char UCHAR ;
        #define unsigned char UCHAR ;

        typedef命名一個新的數據類型,但實際上這個新的數據類型是已經存在的,只不過是定義了
        一個新的名字.
        #define只是一個標號的定義.
        你舉的例子兩者沒有區別,但是#define還可以這樣用
        #define MAX 100
        #define FUN(x) 100-(x)
        #define LABEL
        等等,這些情況下是不能用typedef定義的

        七、請問如何設定KELC51的仿真工作頻(時鐘)
        用右鍵點擊左邊的的target 1,然后在xtal一欄輸入

        八、不同模塊怎樣共享sbit變量,extern不行?
        把SBIT定義單獨放到一個.H中,每個模塊都包含這個.h文件

        九、C51中對于Px.x的訪問必須自己定義嗎?
        是的。
        如sbit P17 =0x97;即可定義對P1.7的訪問

        十、SWITCH( )語句中表達式不可以是位變量對嗎?
        可以用位變量:
        #include
        #include

        void main()
        {
        bit flag;
        flag=0;
        switch(flag)
        {
        case '0':{printf("0n");break;}
        case '1':{printf("1n");break;}
        default:break;
        }
        }

        bit 變量只有兩種狀態,if 語句足夠啦,!!!

        十一、const常數聲明占不占內存???
        const 只是用來定義“常量”,所占用空間與你的定義有關,如:
        const code cstStr[] ={"abc"};
        占用代碼空間;而如:
        const char data cstStr[] ={"abc"};
        當然占用內存空間。
        另外,#define 之定義似乎不占用空間。

        十二、philips的P89C51RD+的擴展RAM在C51中如何使用?
        試一試將auxr.1清0,然后在c語言中直接聲明xdata類型的變量

        十三、BUG of Keil C51
        程序中用如下語句:
        const unsigned char strArr[] ={"數學"};
        結果發現strArr[] 內容為 {0xCA,0xD1,0xA7},真奇怪!

        凡是有0xfd,則會通通不見了,所以只能手工輸入內碼了,例如 uchar strArr[]=
        {0xCA,0xfd,0xd1,0xa7}(用Ultraedit會很方便)。

        十四、Keil C51中如何實現代碼優化?
        菜單Project下Option for target "Simulator"的C51.
        看到Code optimization了嗎?

        十五、請教c的!和 ~ 符號有甚區別??
        !是邏輯取反,~是按位取反。

        十六、c51編程,讀端口,還要不要先輸出1?
        我怎么看到有的要,有的不要,請高手給講講,到底咋回事?謝了
        要輸出1的,除非你能保證之前已經是1,而中間沒有輸出過其他值。

        十七、當定時器1(T1)用于產生波特率時,P3^5還是否可以用作正常的I/O口呢?
        p3.5完全可以當普通的io使用

        十八、C51中 INT 轉換為 2個CHAR?
        各位高手:
        C51中 INT 轉換為 CHAR 如何轉換諸如:
        X =LOW(Z);
        Y =HIGH(Z);
        答:
        x=(char)z;
        y=(char)(z>>8);

        十九、如果我想使2EH的第7位置1的話,用位操作可以嗎?
        現在對位操作指令我一些不太明白請各位多多指教:
        如 SETB 07H 表示的是20H.7置1,對嗎?(我在一本書上是這么看到的)
        那么如果我想使2EH的第7位置1的話,象我舉的這個例子怎么表示呢?謝謝!
        SETB 77H
        setb (2eh-20h)*8+7
        20h-2fh每字節有8個可位操作(00h-7fh),其它RAM不可位直接操作

        二十、char *addr=0xc000 和char xdata *addr=0xc000有何區別?
        char *addr=0xc000;
        char xdata *addr=0xc000;
        除了在內存中占用的字節不同外,還有別的區別嗎?

        char *addr=0xc000; 是通用定義,指針變量 addr 可指向任何內存空間的值;
        char xdata *addr=0xc000; 指定該指針變量只能指向 xdata 中的值;
        后一種定義中該指針變量(addr)將少占用一個存儲字節。


        uchar xdata *addr=0xc000;指針指向外ram;
        如果:data uchar xdata *addr=0xc000;指針指向外ram但指針本身存在于內ram(data)

        以此類推可以idata uchar xdata *addr=0xc000;pdata uchar xdata *addr=0xc000;
        data uchar idata *addr=0xa0;.....

        ....

        二十一、while(p1_0)的執行時間?
        假設,P1_0為單片機P1口的第一腳,請問,
        while(P1_0)
        {
        P1_0=0;
        }
        while(!P1_0)
        {
        P1_0=1;
        }
        以上代碼,在KEIL C中,需要多長時間,執行完。能具體說明while(P1_0)的執行時間嗎?

        仿真運行看看就知道了,
        我仿真了試了一下,約14個周期

        二十二、怎樣編寫C51的watchdog程序?
        各位大蝦,我用KEIL C51 編寫了一個帶外部開門狗的程序,可程序無法運行起來,經過查
        找,發現程序在經過C51編譯后,在MAIN()函數的前部增加了一端初始化程序,等到進入
        主程序設置開門狗時,開門狗已經時間到,將我的程序復位了,請問我怎樣才能修改這一端
        初始花程序,使他一運行,就設置開門狗?

        可以在startup.a51中加入看門狗刷新指令,當然用匯編,然后重新編譯startup.a51
        ,將他和你的程序連接即可。新的startup.a51會自動代替系統默認的啟動模塊。

        二十三、keil C51 怎樣把修改的startup.a51 加到工程文件中
        直接加入即可
        注意不要改動?STACK,?C_START,?C_STARTUP等符號。startup.a51直接加入項目,不用修改也可。可在內面自己修改匯編的一些限制或堆棧指針。

        二十四、關于波特率的設置
        我在設定串口波特率時發現一個問題:在晶體震蕩器為11.0592MHz時,若設9600BPS的話,
        TH1=0XFD,TL1=0XFD,而要設19200BPS的話,TH1、TL1有否變化,如果沒變,為什么?
        如果變了,又為什么?(因為我看書上倆個是一樣的),希望大家點撥。
        答:
        當電源控制寄存器(PCON)第BIT7(SMOD)為1時波特率加倍。
        TH1和TL1的值不變.

        二十五、如何在C中聲明保留這部分RAM區不被C使用?
        我不知道在C源程序中怎么控制這個,但在匯編程序中加入下面一段就行:
        DSEG AT 20H
        AA: DS 10
        這樣C51就不會占用20H--29H了
        或者在c51里這樣定義:

        uchar data asm_buff[10] _at_ 0x20;

        二十六、問浮點運算問題
        我在用C51時發現它對傳遞浮點參數的個數有限制,請問:
        1)參數是以全局變量的形式傳遞的,請問以全局變量的形式傳遞的參數也有限制嗎?
        2)這種傳遞浮點參數的限制有多少呢?
        3)float*float的結果是float類型還是double類型?能否直接賦值給float類型的變量?
        答:
        由于KEIL C51的參數傳遞是通過R0-R7來傳遞的,所以會有限制。
        不過KEIL提供了一個編譯參數,可以支持更多參數的傳遞。具體
        的內容見KEIL的PDF文檔。
        我建議你把多個要傳遞的參數定義到指針或結構體中去,傳遞參
        數通過指針或結構進行,這樣好一些。

        第3個問題回答是YES,你自己試試不就知道了。

        二十七、如何在某一個地址定義ram
        用_at_ 命令,這樣可以定位靈活一點的地址
        uchar xdata dis_buff[16] _at_ 0x6020 ;//定位RAM
        將dis_buff[16]定位在0x6020開始的16個字節

        二十八、keil c中,用什么函數可以得到奇偶校驗位?
        例如32位數據,將四個字節相互異或后檢查P即可,若耽心P被改變,可用內嵌匯編。
        #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);
        }


        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 大英县| 林芝县| 杭锦后旗| 高台县| 加查县| 沭阳县| 民勤县| 诏安县| 道真| 桦川县| 苍山县| 武功县| 通道| 合水县| 凉城县| 容城县| 香港| 辉南县| 岑溪市| 新野县| 新余市| 道孚县| 临沧市| 洪湖市| 抚顺县| 鲁甸县| 莆田市| 同德县| 平度市| 久治县| 颍上县| 华池县| 三门县| 毕节市| 双鸭山市| 宜宾市| 将乐县| 古丈县| 白水县| 新平| 柏乡县|