Je réalise un bus I2C en assembleur avec un microcntroôleur 80C552 vers une mémoire EEPROM 8582.
J'ai déjà codé l'emission desdonnées, mais le programme n'entre en interruption et donc n'envoie les données qu'aléatoirement. Il met parfois plusieures minutes pour cela.
include reg552.inc
;Positionner des bits utiles a la routine
FIN_TR equ 07fh
;Donnees immediates a ecrire dans le registre S1CON
;(cas du 80C552 version 12Mhz, l'I2C fonctionnant a 100kbit/s)
ENS1_NOTSTA_STO_NOTSI_AA_CR0 equ 0d5h ;genere un stop (CR0 equ 100khz)
ENS1_NOTSTA_NOTSTO_NOTSI_AA_CR0 equ 0c5h ;relache le BUS et envoie acquittement
ENS1_NOTSTA_STO_NOTSI_NOTAA_CR0 equ 0c1h ;relache le bus et n'envoie pas l'acquittement
ENS1_STA_NOTSTO_NOTSI_AA_CR0 equ 0e5h ;relache le bus et le reprends avec un STA
;Donnees immediates generales
OWNSLA equ 031h ;adresse personnelle
ENSIO1 equ 0a0h ; EA+ES1 autorise l'interrupion SIO1 doit etre ecrit dans ENI0
OFFSET equ 050h ;adresse de base des routines de traitement d'interruption liees
ADRESC_W equ 0a0h ;ex. adresse esclave + bit ecriture
ADRESC_R equ 0a1h ;ex. adresse esclace + bit lecture
FIN equ 080h ;indic de fin de message
FIN1 equ 040h
;Emplacements de registres particuliers en RAM internes
MTD equ 030h ;adresse de base MST/TRX/DATA
MRD equ 038h ;adresse de base MST/REC/DATA
SRD equ 040h ;adresse de base SLV/REC/DATA
STD equ 048h ;adresse de base SLV/TRX/DATA
BACKUP equ 053h ;retour de backup de NOMBOCT
;pour faire revenir de sauvegarde NUMBYTMST en cas de perte d'arbritage
NOMBOCT equ 052h ;nombre d'octets a transmettre ou recevoir
SLA equ 0a0h ;contient l'adresse de l'esclave et le sens de transfert (R/W) a transmettre
HADD equ 050h ;octet d'adresse haute des differents traitements dont l'adresse basse
;est fournie par la valeur du registre de status S1STA
DAT equ 70h
;Routine d'utilisation
Code at 4100h
INIT:
mov p4,#00h ;!!! TEST !!!
mov S1ADR,#OWNSLA ;chargement adr perso + autorisation
mov sp,#0a0h ;positionnement du pointeur de pile
setb p1.6 ;p1.6 niveau haut (SCL)
setb p1.7 ;p1.7 niveau haut (SDA)
mov HADD,#OFFSET
orl IEN0,#ENSIO1 ;autorisation interruption SIO1
mov S1CON,#ENS1_NOTSTA_NOTSTO_NOTSI_AA_CR0 ;initialisation mode maitre
;caracteres a envoyer
mov r1,#DAT
mov @r1,#0000h
inc r1
mov @r1,#0041h
inc r1
mov @r1,#0042h
mov p4,#03h ;!!! TEST !!!
ever :
mov SLA,#ADRESC_W ;W=ecriture
mov NOMBOCT,#3
acall trans
acall boucle
ici:
mov p4,#00h
lcall 1212h
;routine de départ de transmission "maitre"
trans:
mov FIN_TR,#000h ;mise a zero indic fin de message
mov S1CON,#ENS1_STA_NOTSTO_NOTSI_AA_CR0
ret
boucle:
mov a,FIN_TR
jbc acc.6,etia
jbc acc.7,fini
mov p4,S1STA
sjmp boucle
etia:
acall trans
sjmp boucle
fini:
ret
code at 402bh
push psw
push S1STA
push HADD
ret
code at 5000h
acall fct_00
pop psw
reti
code at 5008h
acall fct_08
pop psw
reti
code at 5018h
acall fct_18
pop psw
reti
code at 5020h
acall fct_20
pop psw
reti
code at 5028h
acall fct_28
pop psw
reti
fct_00:
mov S1CON,#ENS1_NOTSTA_STO_NOTSI_AA_CR0 ;raz SI mise a 1 de STO et AA
mov FIN_TR,#FIN1
mov p4,#0aah
ret
fct_08: ;1ere
lcall 1212h
mov p4,#1Fh;!!! TEST !!!
mov S1DAT,SLA ;chargement de SLA+R/W ds tampon
mov S1CON,#ENS1_NOTSTA_NOTSTO_NOTSI_AA_CR0 ;raz SI
mov r1,#DAT ; adresse puis data 2 octets
mov BACKUP,NOMBOCT ;sauvegarde valeur initiale
ret
fct_18: ;2eme
mov S1DAT,@r1
mov S1CON,#ENS1_NOTSTA_NOTSTO_NOTSI_AA_CR0 ;raz SI et AA
mov p4,#00110111b;!!! TEST !!!
ret
fct_20: ;Si Ack=0
mov S1CON,#ENS1_NOTSTA_STO_NOTSI_AA_CR0 ;mise a 1 STO, raz SI
mov NOMBOCT, BACKUP
mov FIN_TR,#FIN1
mov p4,#01h;!!! TEST !!!
ret
fct_28: ;3eme
djnz NOMBOCT,CONTINU
mov S1CON,#ENS1_NOTSTA_STO_NOTSI_AA_CR0 ;raz SI et mise a 1 de AA
mov FIN_TR,#FIN ;positionnement indicateur de fin de transmission
mov p4,#11101110b;!!! TEST !!!
sjmp fin_28
CONTINU:
inc r1
mov S1DAT,@r1
mov S1CON,#ENS1_NOTSTA_NOTSTO_NOTSI_AA_CR0 ;raz SI et AA
mov p4,#11001100b;!!! TEST !!!
fin_28:
ret
end