hello everyone ! Recently i have started to work with assembly. I have school project on MC9S08QG8 with I2C.
i need to write code to control LCD.
What can i start with ?
已解决! 转到解答。
hi everone.I found my solution .Thanks anyway !
SDA equ !6 ;I2C SDA signal
SCL equ !5 ;I2C SCL signal
gSDA rmb 1 ;contains I2C data
ChipAdr rmb 1 ;contains slave I2C address
ChipReg rmb 1 ;contains MC9S08QG8 internal register address
SendI2C:
bset SDA,PTBDD ;set PORTB Bit6 as Output
lda ChipAdr ;get the I2C byte to send
jsr sendStart ;send the Chip Address
lda PORTD
lsra ;extract SDA
lsra ;extract SDA
lsra ;extract SDA
bcc sChipReg ;SDA = Low −> acknowledge OK
jmp ACKerror ;SDA = High −> no acknowledge, error
;send the MC9S08QG8 register address = $01
sChipReg bclr SDA,PTBD ;force I/O = L
bset SDA,PTBDD ;set PORTB Bit6 as Output to write
;to the NCP5602
bclr SCL,PTBD ;set CLOCK = L
lda ChipReg ;send the internal register address
jsr sendByte
lda PORTD
lsra ;extract bit2
lsra ;extract bit2
lsra ;extract bit2
bcc sDATA ;SDA = Low −> acknowledge OK
jmp ACKerror ;SDA = High −> no acknowledge, error
;send the MC9S08QG8 data byte
SDATA
bclr SDA,PTBD ;set PORTB Bit6 as Output to write to MC9S08QG8
bset SDA,PTBDD
bclr SCL,PTBD ;set CLOCK = L
lda gSDA
jsr sendByte
bclr SDA,PTBDD ;set PORTD Bit10 as Input to read
the ACKNOWLEDGE
lda PORTD
lsra ;extract bit10
lsra ;extract bit10
lsra ;extract bit10
bcc exitI2C ;SDA = Low −> acknowledge OK
jmp ACKerror ;SDA = High −> no acknowledge, error
exitI2C
bclr SDA,PTBD
bset SDA,PTBDD
bclr SCL,PTBD
jsr delay5
bset SCL,PTBD
jsr delay5
bset SDA,PTBD
rts ;I2C transmission completed
;
;
;
ACKerror ldhx #mes2 ;get I2C error message
Jmp finish ;error
rts
;
sendStart
pshx ;start the I2C link
bset SCL,PTBD ;preset Clock = H
ldx #$08 ;preset I2C clock bit count
bclr SDA,PTBD ;force DATA = L to Start the frame
nop
nextBit
bclr SCL,PTBD ;CLOCK = LOW
lsla ;rotate 8 bits into Carry
bcs sendHbit
bclr SDA,PTBD ;SDA = L
bra posCLK
sendHbit bset SDA,PTBD ;SDA = H
posCLK bset SCL,PTBD ;CLOCK = High
decx ;decrement clock count
bne nextBit
bclr SCL,PTBD ;CLOCK = L
bclr SDA,PTBDD ;set PORTD Bit2 as Input to read
;the ACKNOWLEDGE
jsr delay5 ; wait to make sure the signal
;is stable
bset SCL,PTBD ;CLOCK = H
jsr delay5
pulx
rts
;
;
sendByte
pshx ;send one byte to the I2C port
bset SCL,PTBD ;preset Clock = H
ldx #$05 ;preset I2C clock bit count
lsla
nop
nextBitD
bclr SCL,PTBD ;CLOCK = LOW
lsla ;rotate 8 bits into Carry
bcs sendHbitD
bclr SDA,PTBD ;SDA = L
bra posCLKD
sendHbitD bset SDA,PTBD ;SDA = H
posCLKD bset SCL,PTBD ;CLOCK = High
decx ;decrement clock count
bne nextBitD
bclr SCL,PTBD ;CLOCK = L
bclr SDA,PTBDD ;set I/O as Input
jsr delay5
bset SCL,PTBD ;CLOCK = H
jsr delay5
pulx
rts
nop finish ;finish not operating
;
;
mes2 db “I2C error : no ACK return@”
;
Hello, and welcome to the forum.
You will need to be more specific about the LCD display module that you are using. The majority of alphanumeric display modules do not use an IIC (I2C) interface.
Regards,
Mac
Hi, I am also using a QG8 for the first time and codewarrior 6.2 also. (for 1st time) I want to use IIC to communicate with a device and am having a lot of trouble with it. Understanding what to do with IIC mainly. Assembler only !
I want to send some bytes, then read back some data for a IIC device.
I have initialised IIC as follows: Not using interrupts
; ### Init_IIC init code
; IICA: ADDR7=1,ADDR6=1,ADDR5=1,ADDR4=1,ADDR3=1,ADDR2=1,ADDR1=1
MOV #$DE,IICA
; IICF: MULT1=0,MULT0=1,ICR5=0,ICR4=0,ICR3=0,ICR2=0,ICR1=0,ICR0=0
MOV #$40,IICF
; IICS: TCF=0,IAAS=0,BUSY=0,ARBL=1,SRW=0,IICIF=1,RXAK=0
MOV #$12,IICS ; Clear the interrupt flags
; IICC: IICEN=1,IICIE=0,MST=1,TX=1,TXAK=0,RSTA=0 NOTE no INT enabled
MOV #$B0,IICC
Initially at least, I just want to be able to get some IIC data out of the device without worrying about interrupts etc. I had thought the above code would set up the IIC port and all I had to do then was to write the data to the IIC data reg. Nothing happens. I write to the IICD data reg and then loop looking for data sent (bit 7 of IICS. It seems to pass that test as it keeps going past that point, suggesting the data has 'gone' ie Transfer complete
ie, I have:
I2CTxByte:
sta IICD
;and loop till sent ie check flag ?????????????
brclr 7,IICS,*
Apart from that, I am at loss to understand compeltely how to inititate the start sequence, send data and stop sequence.
Should I bset MST of the IICC to do a START condition on IIC? ie BSET MST,IICC (and have it cleared in the initialisation)
Then store the data to be sent into the IICD data reg.
Then keep storing data into the IICD reg while checking for Transfer complete.
Then send STOP condition but how ? bclr MST,IICC ?
Would someone be so kind as to offer some (assembler) code snippets to:
initialise the IIC port (I am using porta, the default)
show how to set start, data and stop condtions (for non interupt mode)
Glenn
[Melbourne, Australia]
Hello Glenn,
There are two application notes that pertain to the IIC module, AN3048 and AN3291. The latter is the more general note and includes a number of MCU device families for an EEPROM application. Unfortunately both provide code written in C.
However, the following old thread may be of interest, where an attempt was made to convert some of the C functions given in AN3291 into assembly code.
https://community.freescale.com/message/30569#30569
There was also a further old thread where some problems with AN3291 code were discussed, and a solution proposed. I am not sure whether the assembly code from above thread reflected the contents of this thread.
https://community.freescale.com/message/21354#21354
Regards,
Mac
Thanks for the reply, Mac,
There are many 'pleas' for help with IIC using assembler in this Forum. I eventually found (in the forum) a snippet of code to address an eeprom peripheral in slave mode. I managed to adapt this for my application which is to send a series of bytes to a slave, then read one byte back. Part of my problem was omitting the 'repeat start'
Below are my code (snippets), polling used, better with a timeout in each and will add later
;ADDRESS FOR SLAVE
IIC_SLAVE EQU $DE ; This is the address for TFT pcb
;called at Micro init. out of reset.
;to initialise IIC mode.
;
Init_I2C:
BSET IICC_IICEN,IICC ; Enable I2C
BSET IICC_TXAK,IICC ; No ACK generated by master
BCLR IICC_MST,IICC ; Select slave mode
MOV #$8B,IICF ; Set speed 50kHz for Bus = 8MHz
; 50k -> $8B, 100k -> $4B
BCLR IICS_SRW,IICS ; Set R/W bit = 0
RTS
;entry to send slave address to slave deive:
IIC_write_byte: ; NB uses polling
BCLR IICC_TXAK,IICC
LDA IICC
ORA #$30 ; Generate START condition
STA IICC
LDA #IIC_SLAVE ;get slave address
STA IICD ; Send byte
BRCLR IICS_IICIF,IICS,* ; Wait until flag is set
BSET IICS_IICIF,IICS ; Clear flag
BRSET IICS_RXAK,IICS,* ; Wait until RXAK clear - slave ACK
.........................
........................
;loop to send number of bytes required:- (loop code not shown):-
I2CTxByte:
STA IICD ;data out
BRCLR IICS_IICIF,IICS,* ; Wait until flag is set
BSET IICS_IICIF,IICS ; Clear flag
BRSET IICS_RXAK,IICS,* ; Wait until RXAK clear - slave ACK
.................
..............
Now, send slave address and READ coomand (bit 0 of slave address = 1)
;Then get data back in this case one byte required.
; send slave address and read back one byte, NB requires repeat start
BSET IICC_RSTA,IICC ; Setup << repeated start >>
LDA #IIC_SLAVE ; get slave's address
ORA #$01 ; Set RW bit
STA IICD ; Send byte
BRCLR IICS_IICIF,IICS,* ; Wait until flag is set
BSET IICS_IICIF,IICS ; Clear flag
BRSET IICS_RXAK,IICS,* ; Wait until RXAK clear - slave ACK
BCLR IICC_TX,IICC ; Setup to receive
BSET IICC_TXAK,IICC ; Acknowledge disable
LDA IICD ; Dummy read
BRCLR IICS_IICIF,IICS,* ; Wait until flag is set
BSET IICS_IICIF,IICS ; Clear flag
BCLR IICC_MST,IICC ; Generate STOP
LDA IICD ; Read data byte
;analyze /save data read back etc
Glenn
hi everone.I found my solution .Thanks anyway !
SDA equ !6 ;I2C SDA signal
SCL equ !5 ;I2C SCL signal
gSDA rmb 1 ;contains I2C data
ChipAdr rmb 1 ;contains slave I2C address
ChipReg rmb 1 ;contains MC9S08QG8 internal register address
SendI2C:
bset SDA,PTBDD ;set PORTB Bit6 as Output
lda ChipAdr ;get the I2C byte to send
jsr sendStart ;send the Chip Address
lda PORTD
lsra ;extract SDA
lsra ;extract SDA
lsra ;extract SDA
bcc sChipReg ;SDA = Low −> acknowledge OK
jmp ACKerror ;SDA = High −> no acknowledge, error
;send the MC9S08QG8 register address = $01
sChipReg bclr SDA,PTBD ;force I/O = L
bset SDA,PTBDD ;set PORTB Bit6 as Output to write
;to the NCP5602
bclr SCL,PTBD ;set CLOCK = L
lda ChipReg ;send the internal register address
jsr sendByte
lda PORTD
lsra ;extract bit2
lsra ;extract bit2
lsra ;extract bit2
bcc sDATA ;SDA = Low −> acknowledge OK
jmp ACKerror ;SDA = High −> no acknowledge, error
;send the MC9S08QG8 data byte
SDATA
bclr SDA,PTBD ;set PORTB Bit6 as Output to write to MC9S08QG8
bset SDA,PTBDD
bclr SCL,PTBD ;set CLOCK = L
lda gSDA
jsr sendByte
bclr SDA,PTBDD ;set PORTD Bit10 as Input to read
the ACKNOWLEDGE
lda PORTD
lsra ;extract bit10
lsra ;extract bit10
lsra ;extract bit10
bcc exitI2C ;SDA = Low −> acknowledge OK
jmp ACKerror ;SDA = High −> no acknowledge, error
exitI2C
bclr SDA,PTBD
bset SDA,PTBDD
bclr SCL,PTBD
jsr delay5
bset SCL,PTBD
jsr delay5
bset SDA,PTBD
rts ;I2C transmission completed
;
;
;
ACKerror ldhx #mes2 ;get I2C error message
Jmp finish ;error
rts
;
sendStart
pshx ;start the I2C link
bset SCL,PTBD ;preset Clock = H
ldx #$08 ;preset I2C clock bit count
bclr SDA,PTBD ;force DATA = L to Start the frame
nop
nextBit
bclr SCL,PTBD ;CLOCK = LOW
lsla ;rotate 8 bits into Carry
bcs sendHbit
bclr SDA,PTBD ;SDA = L
bra posCLK
sendHbit bset SDA,PTBD ;SDA = H
posCLK bset SCL,PTBD ;CLOCK = High
decx ;decrement clock count
bne nextBit
bclr SCL,PTBD ;CLOCK = L
bclr SDA,PTBDD ;set PORTD Bit2 as Input to read
;the ACKNOWLEDGE
jsr delay5 ; wait to make sure the signal
;is stable
bset SCL,PTBD ;CLOCK = H
jsr delay5
pulx
rts
;
;
sendByte
pshx ;send one byte to the I2C port
bset SCL,PTBD ;preset Clock = H
ldx #$05 ;preset I2C clock bit count
lsla
nop
nextBitD
bclr SCL,PTBD ;CLOCK = LOW
lsla ;rotate 8 bits into Carry
bcs sendHbitD
bclr SDA,PTBD ;SDA = L
bra posCLKD
sendHbitD bset SDA,PTBD ;SDA = H
posCLKD bset SCL,PTBD ;CLOCK = High
decx ;decrement clock count
bne nextBitD
bclr SCL,PTBD ;CLOCK = L
bclr SDA,PTBDD ;set I/O as Input
jsr delay5
bset SCL,PTBD ;CLOCK = H
jsr delay5
pulx
rts
nop finish ;finish not operating
;
;
mes2 db “I2C error : no ACK return@”
;
Hello,
The code that you are using is actually "bit banging" the IIC interface, normally utilized when IIC peripheral hardware is not available. Since the device you are using does have an IIC hardware module, the communications would be significantly faster if this were to be utilised.
The code posted by Glenn P. shows the use of the IIC module.
Regards,
Mac