打印
[51单片机]

c51里C调用汇编要传递参数,那位熟悉

[复制链接]
2563|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chuandaoxy|  楼主 | 2014-2-9 17:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 chuandaoxy 于 2014-2-9 17:43 编辑

我在编写一个驱动程序,汇编版十分成功,但是C语言版本老是不能顺利通过,于是产生了,用C调用汇编的办法,因为时序控制,用汇编更精准,由于CPU管脚少,很少使用液晶模块,我在网上发现用2根线,驱动8574再驱动1602,因为C调用汇编要传递参数,(就是要显示的字符串),下面是我的汇编代码,希望那位热心朋友改成C的版本,谢谢(晶振110592)




SDA         BIT P2.1        ; I2C DATA
SCL         BIT P2.0        ; I2C CLOCK

DATA_I2C    EQU 2FH         ;Bit addressing DATA buffer for I2C bus
ADDR_I2C    EQU 30H         ;Address buffer for I2C bus
ADDR_A3A0   EQU 34H         ;REAL ADDRESS FROM 0-7 OF I2C


I2C_ACK     BIT PSW.5       ;I2C Acknowledge Flag  0= Not acknowledge
I2C_ALL     BIT PSW.1       ;If send data complete this falg will be = 1


//EN_LCD      BIT DATA_I2C.3  ;BIT 3 of DATA_I2C
//RS_LCD      BIT DATA_I2C.2  ;BIT 2 OF DATA_I2C

EN_LCD      BIT DATA_I2C.1  ;BIT 3 of DATA_I2C
RS_LCD      BIT DATA_I2C.3  ;BIT 2 OF DATA_I2C


;******************************************************************************
;           MAIN PROGRAM
;******************************************************************************
            ; LCD is  CONNECT TO PCF8754 at address 7EHS
            ; 4 BIT INTERFACE

MAIN:       MOV SP,#128-24
            ACALL INIT_LCD
            MOV A,#01H    ;CLEAR LCD
            ACALL WR_INS_LCD
            MOV A,#00H    ;Start address at 00
            ACALL SET_DDRAM
            MOV DPTR,#MESSAGE
            ACALL WR_L_LCD
            MOV A,#40H
            ACALL SET_DDRAM
            MOV DPTR,#MESSAGE1
            ACALL WR_L_LCD


MESSAGE:    DB  'Test20lineLCDby..I2C',020H
MESSAGE1:   DB  'www.mcu.cz',020H
NUMBER_TAB: DB  030H,031H,032H,033H,034H,035H,036H,037H,038H,039H


;******************************************************************************
;           LCDC Routines
;******************************************************************************
            ; INITIAL LCD

INIT_LCD:   MOV A,#33H
            ACALL WR_INS_LCD
            MOV A,#32H
            ACALL WR_INS_LCD
            MOV A,#28H    ;FUNCTION SET
            ACALL WR_INS_LCD
            MOV A,#06H    ;ENTRY MODE
            ACALL WR_INS_LCD
            MOV A,#01H    ;CLEAR DISPLAY
            ACALL WR_INS_LCD
ACALL I2C_DELAY

                         MOV A,#01H    ;CLEAR DISPLAY

             ACALL WR_INS_LCD

                         ACALL I2C_DELAY

                         ACALL I2C_DELAY

            MOV A,#0CH    ;08H Display OFF ,no cursor and not blink (0Ch for ON)
            ACALL WR_INS_LCD  ;If 0fH then blink and show cursor
            RET


            ; SET ADDRESS OF DDRAM
            ; INPUT = A

SET_DDRAM:  SETB  ACC.7
            ACALL WR_INS_LCD
            RET


            ; SET ADDRESS OF CGRAM
            ; INPUT = A

SET_CGRAM:  CLR ACC.7
            SETB  ACC.6
            ACALL WR_INS_LCD
            RET


            ; WRITE LINE LCD  DIGIT=20
            ; INPUT = DPTR
            ; REG   = R5  A , DPTR

WR_L_LCD:   PUSH  05H     ;PUSH R5
            MOV R5,#00      ;NUMBER OF DIGIT
            CLR A     ;CLEAR A
WR_LINE_1:  MOVC  A,@A+DPTR
            ACALL WR_CH_LCD
            INC R5
            MOV A,R5
            CJNE  A,#20,WR_LINE_1   ;CHECK FOR  20 DIGIT COMPLETE
            POP 05H     ;POP  R5

                        MOV A,#01H    ;CLEAR DISPLAY
             ACALL WR_INS_LCD

                        ACALL I2C_DELAY
                        ACALL I2C_DELAY
                        ACALL I2C_DELAY

            RET


            ; write DATA to DDRAM
            ; REG = ACC
            ; INPUT = ACC

WR_CH_LCD:  PUSH  ACC
            ANL A,#0F0H
            MOV ADDR_A3A0,#07H
            MOV DATA_I2C,A
            SETB  RS_LCD
            ACALL WR_8574
            ACALL ENABLE_LCD
            POP ACC
            SWAP  A
            ANL A,#0F0H
            MOV DATA_I2C,A
            SETB  RS_LCD
            ACALL WR_8574
            ACALL ENABLE_LCD
            RET


            ; WRITE instruction to LCD USE PCF8574 at address 7EH
            ; REG   = A
            ; INPUT = A

WR_INS_LCD: PUSH  ACC   ;Keep A
            ANL A,#0F0H
            MOV ADDR_A3A0,#07H    ;Select address of PCF 8574 to LCD
            MOV DATA_I2C,A
            ACALL WR_8574
            ACALL ENABLE_LCD
            POP ACC
            SWAP  A
            ANL A,#0F0H
            MOV DATA_I2C,A
            ACALL WR_8574


            ; ENABLE PULSE FOR LCD INPUT = A

ENABLE_LCD: SETB  EN_LCD
            ACALL WR_8574
            CLR EN_LCD
            ACALL WR_8574
            RET

;******************************************************************************
;           I2C Routines
;******************************************************************************

            ; Write Data to PCF8574A,PCF8574AP
            ; I/P = DATA_I2C , ADDR_A3A0
            ; *ADDR_CH can has value 0-7

//WR_8574:    MOV ADDR_I2C,#70H
WR_8574:    MOV ADDR_I2C,#4EH

            ACALL ADJ_ADDR

START_WR:   ACALL I2C_CONN    ;START WRITE DATA TO I2C DEVICE
START_WR_1: ACALL I2C_D_WR
            ACALL I2C_STOP
            RET


            ; ADJUST ADDRESS OF I2C FOR 7 BIT ADDRESSING
            ; I/P = ADDR_A0A3
            ; O/P = ADDR_I2C
            ; REG = ACC
            ; Example:
            ;   ADDR_I2C:   0100 1110
            ;   ADDR_A3A0:  0000 0011

ADJ_ADDR:   PUSH  ACC
            ANL ADDR_I2C,#0F1H    ;YYYY 000Y
            MOV A,ADDR_A3A0
            ANL A,#07H      ;0000 0XXX
            RL  A     ;0000 XXX0
            ANL A,#0EH      ;0000 XXX0
            ADD A,ADDR_I2C
            MOV ADDR_I2C,A    ;YYYY XXXY
            POP ACC
            RET


            ; WRITE DATA TO I2C PHERIFERAL
            ; REG = R4 , ACC ,CARRY FLAG
            ; INPUT = DATA_I2C

I2C_D_WR:   PUSH  ACC
            MOV A,DATA_I2C
            SJMP  I2C_SEND


            ; Connect and Send data to I2C Device
            ; I/P = ADDR_I2C
            ; O/P = I2C_ACK
            ; REG = R5 ACC

I2C_CONN:   PUSH  ACC     ;Addressing to I2C Device
            MOV A,ADDR_I2C
            ACALL I2C_START   ;Start connect


            ;SEND Data to I2C

I2C_SEND:   PUSH  05H     ;PUSH R5
            MOV R5,#08
I2C_SEND_1: RLC A     ;MOV BIT to Carry FLAG
            MOV SDA,C
            ACALL I2C_CLK     ;CLOCK TO SEND ONE BIT
            DJNZ  R5,I2C_SEND_1   ;Decrease R5 BY ONE
            SETB  SDA     ;Complete Send Eight Bit
            ACALL I2C_DELAY
            SETB  SCL
            ACALL I2C_DELAY
            JB  SDA,I2C_SEND_2    ;Jump if Device not Acknowledge
            SETB  I2C_ACK     ;Device Acknowledge
I2C_SEND_2: CLR SCL
            POP 05H
            POP ACC
            RET


            ; I2C Start Condition
            ; O/P = I2C_ALL

I2C_START:  SETB  SDA
            SETB  SCL
            CLR I2C_ALL
            ACALL I2C_DELAY
            CLR SDA
            ACALL I2C_DELAY
            CLR SCL
            RET


            ; I2C Stop Condition
            ; O/P = I2C_ALL

I2C_STOP:   CLR SDA
            SETB  SCL
            ACALL I2C_DELAY
            SETB  SDA
            SETB  I2C_ALL
            RET


            ; Clock pulse for I2C

I2C_CLK:    SETB  SCL
            ACALL I2C_DELAY
            CLR SCL
            RET


            ; Delay time at system clock 12 MHz

I2C_DELAY:  PUSH  02H
            MOV R2,#0FFH
            DJNZ  R2,$
            POP 02H
            RET

END



相关帖子

沙发
wangch_sh| | 2014-2-9 17:42 | 只看该作者
在网上有C调用汇编的资料,自己查一下。

使用特权

评论回复
板凳
woshigeshuai| | 2020-3-6 13:47 | 只看该作者
楼上的资料非常有价值,玩了7 8年51了,看了还是受益颇多

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

855

主题

1044

帖子

4

粉丝