The alchmiste
Starting Member
- Total Posts : 70
- Reward points : 0
- Joined: 2018/03/14 02:55:48
- Location: France
- Status: offline
PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
Hi there, I'm locked on the code below writen in asm. The debugger get stucked on the ackknowledge transmission sub routine. I've tried to add a clr of the interupt regiter to see if it have any impact on the ACKEN bit but it Don't. Any one have an idea? Thanks Thealchimiste list p=16f15344 , r=dec #include <p16f15344.inc>
; CONFIG1 ; __config 0x3E8C __CONFIG _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_ON & _FCMEN_ON ; CONFIG2 ; __config 0x279C __CONFIG _CONFIG2, _MCLRE_ON & _PWRTE_ON & _LPBOREN_OFF & _BOREN_NSLEEP & _BORV_LO & _ZCD_OFF & _PPS1WAY_OFF & _STVREN_OFF ; CONFIG3 ; __config 0xFFFF __CONFIG _CONFIG3, _WDTCPS_WDTCPS_31 & _WDTE_OFF & _WDTCWS_WDTCWS_7 & _WDTCCS_SC ; CONFIG4 ; __config 0x1FE0 __CONFIG _CONFIG4, _BBSIZE_BB64K & _BBEN_OFF & _SAFEN_ON & _WRTAPP_OFF & _WRTB_OFF & _WRTC_OFF & _WRTSAF_OFF & _LVP_OFF ; CONFIG5 ; __config 0x3FFF __CONFIG _CONFIG5, _CP_OFF
; _RSTOSC_HFINT32 -> permet l'activation de l'oscillateur interne a une frequence de 32Mhz soit 31,25 nanoS/osccillation-> 25 interuption / seconde avec: postdiviseur=10, prediviseur=128, seuil timer2=249, ; _LVP_OFF -> permet la programmation a faible tenssion ; _CP_OFF -> Ne cache pas le code ; _WDT_OFF -> Desactive le Watch Dog ; Definition des differentes variable du programme à partir de l'adresse 0x20
cblock 0X20 ; // Variables utiles pour rtc Dataa : 1 ; Valeur de la data I2C envoyé secondes : 1 ; Valeur recupéré par l'I2C sur RTC en seconde
minutes : 1 ; Valeur recupéré par l'I2C sur RTC en minutes
heures : 1 ; Valeur recupéré par l'I2C sur RTC en heures
jourh : 1 ; Valeur recupéré par l'I2C sur RTC en jour hebdomadaire
jourm : 1 ; Valeur recupéré par l'I2C sur RTC en jour mensuel mois : 1
année : 1 ; Valeur recupéré par l'I2C sur RTC en année
problem : 1 ; Valeur recupéré en cas de problem d'acknowlede non recu par l'esclave
endc
;******************************************************************************* ; Reset Vector ;*******************************************************************************
org 00H ; processor reset vector goto RTCI2C ; go to beginning of program
; TODO INSERT ISR HERE
;******************************************************************************* ; Routine d'interuption ;******************************************************************************* org 0x004 ; interrupt vector location RETFIE ;******************************************************************************* ; Macro I2C ;******************************************************************************* ; Parametrage I2C ( reglage vitesse, reglage des ports associé au SCK et SDA, ; reglage du peripherique MSSP, reglage du nombre de bit par adresse, reglage ; reglage des port en entré ou sortie, verrifier s'il est necessaire d'activer ; les pull-up resitor pour l'I2C et desactiver les pull-up resistor pour les ; autres ports, verrifier la fin de chaque procedure apres chaque procedure lancé)
; Configuration I2C RTCI2C banksel Dataa CLRF Dataa ; Valeur de la data I2C envoyé CLRF secondes ; Valeur recupéré par l'I2C sur RTC en seconde CLRF minutes ; Valeur recupéré par l'I2C sur RTC en minutes CLRF heures ; Valeur recupéré par l'I2C sur RTC en heures CLRF jourh ; Valeur recupéré par l'I2C sur RTC en jour hebdomadaire CLRF jourm ; Valeur recupéré par l'I2C sur RTC en jour mensuel CLRF mois CLRF année ; Valeur recupéré par l'I2C sur RTC en année CLRF problem ; Valeur recupéré en cas de problem d'acknowlede non recu par l'esclave
banksel RB4PPS movlw 0x16 ;On associe SDA a RB4 ( les données transmises) movwf RB4PPS
banksel RB5PPS movlw 0x15 ;On associe SCL a RB5 (l'horloge) movwf RB5PPS
banksel TRISB movlw B'11111111' ;RB4, RB5 en entrée movwf TRISB banksel SSP1STAT movlw B'10000000' ;// On parametre SMP a 1 pour informer que l'horloge travaillera ; a 1Mhz ou 100Khz et CKE a 0 pour indiquer qu'on travail en mode I2C movwf SSP1STAT banksel SSP1ADD movlw B'01001111' ;// On charge la valeur 79 afin de faire fonctionner l'horloge SCL ; à 100Khz formule: (Fosc/4*Fscl)-1 movwf SSP1ADD
banksel SSP1CON1 movlw B'00101000' ;// On Active le module SSPM avec le bit 5 et on le paramettre ; avec les 4 premiers en mode I2C maitre movwf SSP1CON1 ; 1) configuration I2C -> OK
;// a) on parametre et fixe les valeurs des registres du RTC avant de lancer les aquisitions call i2cstart call adressebyteecriture call Acknowledge ; - les secondes a banksel problem bcf problem,0 movlw d'0' banksel Dataa movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto a c banksel problem bcf problem,0 banksel Dataa movlw d'0' movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto c ; - les minutes d banksel problem bcf problem,0 movlw d'1' banksel Dataa movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto d e banksel problem bcf problem,0 banksel Dataa movlw d'0' movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto e ; - les heures et le format f banksel problem bcf problem,0 movlw d'2' banksel Dataa movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto f g banksel problem bcf problem,0 banksel Dataa movlw d'4' movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto g ; - le jour de la semaine h banksel problem bcf problem,0 movlw d'3' banksel Dataa movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto h i banksel problem bcf problem,0 banksel Dataa movlw d'5' movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto i ; - le jour du mois k banksel problem bcf problem,0 banksel Dataa movlw d'4' movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto k l banksel problem bcf problem,0 banksel Dataa movlw d'1' movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto l ; - le mois m banksel problem bcf problem,0 banksel Dataa movlw d'5' movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto m n banksel problem bcf problem,0 movlw d'10' banksel Dataa movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto n ; - l'année o banksel problem bcf problem,0 banksel Dataa movlw d'6' movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto o p banksel problem bcf problem,0 banksel Dataa movlw d'32' movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto p call i2cstop ;// b) on interoge le rtc tout le temps quand on se situe dans le program principale ; - On interroge l'heure (sous routine heure) ; - On interroge la date (sous routine date)
heure call i2cstart ;// on fait un restart pour pointer sur l'adresse du premier registre call adressebyteecriture call Acknowledge movlw d'0' ;// on pointe sur l'adresse du premier registre banksel Dataa movwf Dataa call Databyte call Acknowledge call i2crestart ;// on fait un restart pour commencer la lecture des registre call adressebyte ;// les uns à la suite des autre et stockage dans les call Acknowledge ;// variables appropriés call lectureI2C banksel PIR3 bcf PIR3,SSP1IF banksel SSP1BUF movfw SSP1BUF call sendAcknowledge banksel secondes ;// aquisition des secondes movwf secondes call lectureI2C banksel PIR3 bcf PIR3,SSP1IF banksel SSP1BUF movfw SSP1BUF call sendAcknowledge banksel minutes ;// aquisition des minutes movwf minutes call lectureI2C banksel PIR3 bcf PIR3,SSP1IF banksel SSP1BUF movfw SSP1BUF call sendAcknowledge banksel heures ;// aquisition des heures movwf heures banksel heures btfss heures,5 goto heure banksel heures btfss heures,2 goto heure banksel heures btfss minutes,6 goto heure banksel heures btfss minutes,4 goto heure banksel heures btfss minutes,3 goto heure banksel heures btfss minutes,0 goto heure date call lectureI2C banksel PIR3 bcf PIR3,SSP1IF banksel SSP1BUF movfw SSP1BUF call sendAcknowledge banksel jourh ;// aquisition des jours hebdomadaire movwf jourh call lectureI2C banksel PIR3 bcf PIR3,SSP1IF banksel SSP1BUF movfw SSP1BUF call sendAcknowledge banksel jourm ;// aquisition des jours mensuels movwf jourm call lectureI2C banksel PIR3 bcf PIR3,SSP1IF banksel SSP1BUF movfw SSP1BUF call sendAcknowledge banksel mois ;// aquisition des mois movwf mois call lectureI2C banksel PIR3 bcf PIR3,SSP1IF banksel SSP1BUF movfw SSP1BUF call sendAcknowledge banksel année ;// aquisition des années movwf année call noAcknowledge ;// fin de la lecture call i2cstop ;// fin du bus
goto heure ; goto AffichageNOKIA ;// On arrete d'interroger uniquement lors d'une interruption liée à ; - timmer d'arrosage ; - interruption externe sur ADC: cellule photosensible ; 2) lancement aquisition -> OK ; Start condition bit i2cstart banksel SSP1CON2 bsf SSP1CON2,SEN attentefinstart btfsc SSP1CON2,SEN goto attentefinstart return ; reapeated Start condition bit i2crestart banksel SSP1CON2 bsf SSP1CON2,RSEN attentefinrestart btfsc SSP1CON2,RSEN goto attentefinrestart return ; Stop condition bit i2cstop banksel SSP1CON2 bsf SSP1CON2,PEN attentefinstop btfsc SSP1CON2,PEN goto attentefinstop return ; Adresse byte en mode ecriture adressebyteecriture banksel SSP1BUF movlw b'01101000'*2 ;// On decale vers la gauche pour mettre 0 au 1er bit ; indiquant que ce qui suit sera une ecriture movwf SSP1BUF testfinadresseecriture banksel SSP1STAT btfsc SSP1STAT,R_W goto testfinadresseecriture return ; Adresse byte en mode lecture adressebyte banksel SSP1BUF movlw b'01101000'|1 ;// On decale vers la gauche pour mettre 1 au 1er bit ; indiquant que ce qui suit sera une lecture par le maitre movwf SSP1BUF testfinadresse banksel SSP1STAT btfsc SSP1STAT,R_W goto testfinadresse return ; Lecture esclave lectureI2C banksel SSP1CON2 bsf SSP1CON2,RCEN veriflecture btfsc SSP1CON2,RCEN goto veriflecture return ; verification Acceptance bit received Acknowledge banksel SSP1CON2 btfss SSP1CON2,ACKSTAT return banksel problem bsf problem,0 ;// endroit ou reprendre la derniere adresse pour recomencer l'envoie return ; Envoie Acceptance bit sendAcknowledge banksel SSP1CON2 bsf SSP1CON2,ACKDT bsf SSP1CON2,ACKEN checkACK btfsc SSP1CON2,ACKEN goto checkACK ;// endroit ou reprendre la derniere adresse return ; Envoie No Acceptance bit noAcknowledge banksel SSP1CON2 bsf SSP1CON2,ACKDT bsf SSP1CON2,ACKEN checknoACK btfsc SSP1CON2,ACKEN goto checknoACK ;// endroit ou reprendre la derniere adresse return ; Data byte Databyte banksel Dataa movfw Dataa ;// On deverse la data dans w banksel SSP1BUF movwf SSP1BUF testfindata banksel SSP1STAT btfsc SSP1STAT,R_W goto testfindata return end
|
ric
Super Member
- Total Posts : 29435
- Reward points : 0
- Joined: 2003/11/07 12:41:26
- Location: Australia, Melbourne
- Status: online
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/05 16:56:39
(permalink)
I'm not sure about your ACKEN problem, but looking at the rest of your code, your handling of received ACK/NAK when you are sending data is totally wrong. If you ever get a NAK from the slave, you must abandon the current transaction, and start from scratch. i.e. send a STOP condition, and go back to before you sent the START. You can NOT simply try to re-send the byte that was NAKed.
To get a useful answer, always state which PIC you are using!
|
The alchmiste
Starting Member
- Total Posts : 70
- Reward points : 0
- Joined: 2018/03/14 02:55:48
- Location: France
- Status: offline
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/05 17:57:53
(permalink)
Thanks Ric for your feedback, As of now, I've not received any NACK. What is the issue of not going back to a start condition? For now the only issue is related to the acknowledgment who do not want to make the ACKEN bit trigered off, so I do not get the Reason of this issue, I've tried an other pic it'the same story... Thanks Thealchimiste
|
ric
Super Member
- Total Posts : 29435
- Reward points : 0
- Joined: 2003/11/07 12:41:26
- Location: Australia, Melbourne
- Status: online
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/05 18:06:30
(permalink)
The alchmiste As of now, I've not received any NACK. Just as well, as your code will get stuck in an endless loop, e.g. if the slave chip is not there. What is the issue of not going back to a start condition?
It simply won't work. In general, if you do get a NAK from a slave, it means the slave is not there at all, or you are trying to access it when it is busy (only happens on memory chips if you try to access them straight after doing a write). The only correct action is to abort the entire cycle. For now the only issue is related to the acknowledgment who do not want to make the ACKEN bit trigered off, so I do not get the Reason of this issue, I've tried an other pic it'the same story...
How exactly are you testing this? In a simulator? Debugging a real chip? Is it stopping the first time you call "sendAcknowledge" ?
To get a useful answer, always state which PIC you are using!
|
Mysil
Super Member
- Total Posts : 4062
- Reward points : 0
- Joined: 2012/07/01 04:19:50
- Location: Norway
- Status: offline
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/05 18:19:17
(permalink)
Hi, If the Slave have got into a state where SCL line is pulled Low, in clock stretch, and do not release the SCL line, then you may have to wait forever, or until the slave device is power cycled. When do this happen? in the first Read transfer? in the last Read transfer, any other time? Have Write transfer been successfully completed? When this happen, what are the state of I2C signal lines? Value in PORTB register? PIC16F15344 I2C signals: SDA output seem to be mapped to RB4 SCL output seem to be mapped to RB5 What about input mapping? From Datasheet DS40001889C-page 196, default selection for input pins on 20 pin device seem to be: SCK1/SCL1 SSP1CLKPPS RB6 0b01110 is 0x8 + 0x6 SDI1/SDA1 SSP1DATPPS RB4 0b01100 is 0x8 + 0x4 ; This do not match with output settings, you may try ; SSP1CLKPPS = 0x8 + 0x5 banksel SSP1CLKPPS movlw 0xD ; 8+5 movwf SSP1CLKPPS Regards, Mysil Edit: PORTB have Analog input properties, make sure that ANSELB bits for I2C signal pins are Cleared to enable digital input. Mysil
post edited by Mysil - 2020/11/05 18:31:34
|
The alchmiste
Starting Member
- Total Posts : 70
- Reward points : 0
- Joined: 2018/03/14 02:55:48
- Location: France
- Status: offline
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/06 02:08:45
(permalink)
Thanks ric Ok I got the point for the restart I’ll send the program back with a NACK and stop and start in case of problem bit 0 set. For the mode I´m testing the code, it is in real chip debugging mode. The issue do happât the first ack sent after first temp tentative et to read the RTC . Thanks Thealchimiste
post edited by The alchmiste - 2020/11/06 02:10:37
|
The alchmiste
Starting Member
- Total Posts : 70
- Reward points : 0
- Joined: 2018/03/14 02:55:48
- Location: France
- Status: offline
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/06 19:45:20
(permalink)
Hi Mysil, Thanks for your clr explaination. It seems that I've not configured the input pps mapping and that I2C need to be remaped only to RB1, RB2, RC3, RC4, therfore, I've used C Port, 3 FOR SCK and 4 for SDA. After making below adding : banksel SSP1DATPPS movlw 0x14 ;On associe SDA a RC4 ( les données transmises) movwf SSP1DATPPS banksel SSP1CLKPPS movlw 0x13 ;On associe SCL a RC3 (l'horloge) movwf SSP1CLKPPS I still have the program looping on the ACKEN check of the first reading from the slave: checkACK btfsc SSP1CON2,ACKEN goto checkACK I've cleared the ANSELC before to enter the reading section of the code this is what I see for the different registers during the looping in the picture below. For instance I still have the same issue of looping... Thanks Thealchimiste
Attached Image(s)
|
The alchmiste
Starting Member
- Total Posts : 70
- Reward points : 0
- Joined: 2018/03/14 02:55:48
- Location: France
- Status: offline
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/08 13:45:37
(permalink)
Hi Mysil,
Do you have any other tips to look at I’m not progressing and don’t know where to look at?
Thanks Thealchimiste
|
Mysil
Super Member
- Total Posts : 4062
- Reward points : 0
- Joined: 2012/07/01 04:19:50
- Location: Norway
- Status: offline
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/09 04:01:07
(permalink)
Hi, You may: A: Go thru all the nitty gritty details with a fine comb, and verify signal level and Input port register value, and SSP status and control register values, for every step. In this connection, a Logic Analyzer, or a two channel oscilloscope may be useful. See this thread: https://www.microchip.com/forums/FindPost/1156906 In pinch, two small LED may help, each with a suitable series resistor, connected in parallel with the pull-up resistors for SCL and SDA signal lines. LEDs must be connected between Vdd and signal, so as to act together with pull-up. B: Package a small, complete, compileable example, that may be run in debugger. Use 'Package' facility in MPLAB, it make a .zip file with all files needed to restore the project. and attach it to your next message. Use 'Open Full Version' in Forum editor to upload attachment. Regards, Mysil
|
The alchmiste
Starting Member
- Total Posts : 70
- Reward points : 0
- Joined: 2018/03/14 02:55:48
- Location: France
- Status: offline
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/13 01:01:37
(permalink)
Mysil Hi, You may: A: Go thru all the nitty gritty details with a fine comb, and verify signal level and Input port register value, and SSP status and control register values, for every step. In this connection, a Logic Analyzer, or a two channel oscilloscope may be useful. See this thread: https://www.microchip.com/forums/FindPost/1156906 In pinch, two small LED may help, each with a suitable series resistor, connected in parallel with the pull-up resistors for SCL and SDA signal lines. LEDs must be connected between Vdd and signal, so as to act together with pull-up. B: Package a small, complete, compileable example, that may be run in debugger. Use 'Package' facility in MPLAB, it make a .zip file with all files needed to restore the project. and attach it to your next message. Use 'Open Full Version' in Forum editor to upload attachment. Regards, Mysil
Hi Mysil, I have found what is causing the issue, it is the bus collision, is just earasing the 2nd bit of PIR3 and continuing the operation enough or should I restart the entire operations? below a print screen of the collision I'm getting during the start condition, sometimes it's happening during the sending of ackowledgment to the slave. Thanks Thealchimiste
Attached Image(s)
|
ric
Super Member
- Total Posts : 29435
- Reward points : 0
- Joined: 2003/11/07 12:41:26
- Location: Australia, Melbourne
- Status: online
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/13 01:33:59
(permalink)
If you get a bus collision you have to start again from scratch. However, why are you getting it? If there isn't another device driving the bus, it's more likely a pullup isn't working, or an I2C pin is in analog mode.
To get a useful answer, always state which PIC you are using!
|
The alchmiste
Starting Member
- Total Posts : 70
- Reward points : 0
- Joined: 2018/03/14 02:55:48
- Location: France
- Status: offline
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/13 01:50:32
(permalink)
Hi Ric, I've clred the ANSELC before to go through the program. Here is the updated code: list p=16f15344 , r=dec #include <p16f15344.inc>
; CONFIG1 ; __config 0x3E8C __CONFIG _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_ON & _FCMEN_ON ; CONFIG2 ; __config 0x279C __CONFIG _CONFIG2, _MCLRE_ON & _PWRTE_ON & _LPBOREN_OFF & _BOREN_NSLEEP & _BORV_LO & _ZCD_OFF & _PPS1WAY_OFF & _STVREN_OFF ; CONFIG3 ; __config 0xFFFF __CONFIG _CONFIG3, _WDTCPS_WDTCPS_31 & _WDTE_OFF & _WDTCWS_WDTCWS_7 & _WDTCCS_SC ; CONFIG4 ; __config 0x1FE0 __CONFIG _CONFIG4, _BBSIZE_BB64K & _BBEN_OFF & _SAFEN_ON & _WRTAPP_OFF & _WRTB_OFF & _WRTC_OFF & _WRTSAF_OFF & _LVP_OFF ; CONFIG5 ; __config 0x3FFF __CONFIG _CONFIG5, _CP_OFF
; _RSTOSC_HFINT32 -> permet l'activation de l'oscillateur interne a une frequence de 32Mhz soit 31,25 nanoS/osccillation-> 25 interuption / seconde avec: postdiviseur=10, prediviseur=128, seuil timer2=249, ; _LVP_OFF -> permet la programmation a faible tenssion ; _CP_OFF -> Ne cache pas le code ; _WDT_OFF -> Desactive le Watch Dog ; Definition des differentes variable du programme à partir de l'adresse 0x20
cblock 0X20 ; // Variables utiles pour rtc Dataa : 1 ; Valeur de la data I2C envoyé secondes : 1 ; Valeur recupéré par l'I2C sur RTC en seconde
minutes : 1 ; Valeur recupéré par l'I2C sur RTC en minutes
heures : 1 ; Valeur recupéré par l'I2C sur RTC en heures
jourh : 1 ; Valeur recupéré par l'I2C sur RTC en jour hebdomadaire
jourm : 1 ; Valeur recupéré par l'I2C sur RTC en jour mensuel mois : 1
année : 1 ; Valeur recupéré par l'I2C sur RTC en année
problem : 1 ; Valeur recupéré en cas de problem d'acknowlede non recu par l'esclave
endc
;******************************************************************************* ; Reset Vector ;*******************************************************************************
org 00H ; processor reset vector goto RTCI2C ; go to beginning of program
; TODO INSERT ISR HERE
;******************************************************************************* ; Routine d'interuption ;******************************************************************************* org 0x004 ; interrupt vector location RETFIE ;******************************************************************************* ; Macro I2C ;******************************************************************************* ; Parametrage I2C ( reglage vitesse, reglage des ports associé au SCK et SDA, ; reglage du peripherique MSSP, reglage du nombre de bit par adresse, reglage ; reglage des port en entré ou sortie, verrifier s'il est necessaire d'activer ; les pull-up resitor pour l'I2C et desactiver les pull-up resistor pour les ; autres ports, verrifier la fin de chaque procedure apres chaque procedure lancé)
; Configuration I2C RTCI2C banksel Dataa CLRF Dataa ; Valeur de la data I2C envoyé CLRF secondes ; Valeur recupéré par l'I2C sur RTC en seconde CLRF minutes ; Valeur recupéré par l'I2C sur RTC en minutes CLRF heures ; Valeur recupéré par l'I2C sur RTC en heures CLRF jourh ; Valeur recupéré par l'I2C sur RTC en jour hebdomadaire CLRF jourm ; Valeur recupéré par l'I2C sur RTC en jour mensuel CLRF mois CLRF année ; Valeur recupéré par l'I2C sur RTC en année CLRF problem ; Valeur recupéré en cas de problem d'acknowlede non recu par l'esclave banksel SSP1BUF clrf SSP1BUF
banksel RC4PPS movlw 0x16 ;On associe SDA a RC4 ( les données transmises) movwf RC4PPS
banksel RC3PPS movlw 0x15 ;On associe SCL a RC3 (l'horloge) movwf RC3PPS
banksel SSP1DATPPS movlw 0x14 ;On associe SDA a RC4 ( les données transmises) movwf SSP1DATPPS
banksel SSP1CLKPPS movlw 0x13 ;On associe SCL a RC3 (l'horloge) movwf SSP1CLKPPS banksel TRISC movlw B'11111111' ;RC4, RC3 en entrée movwf TRISC banksel SSP1STAT movlw B'10000000' ;// On parametre SMP a 1 pour informer que l'horloge travaillera ; a 1Mhz ou 100Khz et CKE a 0 pour indiquer qu'on travail en mode I2C movwf SSP1STAT banksel SSP1ADD movlw B'01001111' ;// On charge la valeur 79 afin de faire fonctionner l'horloge SCL ; à 100Khz formule: (Fosc/4*Fscl)-1 movwf SSP1ADD
banksel SSP1CON1 movlw B'00101000' ;// On Active le module SSPM avec le bit 5 et on le paramettre ; avec les 4 premiers en mode I2C maitre movwf SSP1CON1 banksel LATC clrf LATC BANKSEL ANSELC CLRF ANSELC ; 1) configuration I2C -> OK
;// a) on parametre et fixe les valeurs des registres du RTC avant de lancer les aquisitions call i2cstart call adressebyteecriture call Acknowledge ; - l'iniialisation du pointeur à l'adresse 0 a banksel problem bcf problem,0 movlw d'0' banksel Dataa movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto a ; - les secondes c banksel problem bcf problem,0 banksel Dataa movlw d'0' movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto c ; - les minutes d banksel problem bcf problem,0 movlw d'1' banksel Dataa movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto d ; - les heures et le format f banksel problem bcf problem,0 movlw 0x59 banksel Dataa movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto f ; - le jour de la semaine h banksel problem bcf problem,0 movlw d'4' banksel Dataa movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto h ; - le jour du mois k banksel problem bcf problem,0 banksel Dataa movlw 0x12 movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto k ; - le mois m banksel problem bcf problem,0 banksel Dataa movlw 0x11 movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto m ; - l'année o banksel problem bcf problem,0 banksel Dataa movlw 0x20 movwf Dataa call Databyte call Acknowledge banksel problem btfsc problem,0 goto o call i2cstop ;// b) on interoge le rtc tout le temps quand on se situe dans le program principale ; - On interroge l'heure (sous routine heure) ; - On interroge la date (sous routine date)
heure call i2cstart ;// on fait un restart pour pointer sur l'adresse du premier registre call adressebyteecriture call Acknowledge movlw d'0' ;// on pointe sur l'adresse du premier registre banksel Dataa movwf Dataa call Databyte call Acknowledge call i2crestart ;// on fait un restart pour commencer la lecture des registre call adressebyte ;// les uns à la suite des autre et stockage dans les call Acknowledge ;// variables appropriés call lectureI2C banksel SSP1BUF movfw SSP1BUF call sendAcknowledge banksel secondes ;// aquisition des secondes movwf secondes call lectureI2C banksel SSP1BUF movfw SSP1BUF call sendAcknowledge banksel minutes ;// aquisition des minutes movwf minutes call lectureI2C banksel SSP1BUF movfw SSP1BUF call sendAcknowledge banksel heures ;// aquisition des heures movwf heures banksel heures btfss heures,5 goto heure banksel heures btfss heures,2 goto heure banksel heures btfss heures,1 goto heure banksel heures btfss minutes,6 goto heure banksel heures btfss minutes,4 goto heure banksel heures btfss minutes,3 goto heure banksel heures btfss minutes,0 goto heure date call lectureI2C banksel SSP1BUF movfw SSP1BUF call sendAcknowledge banksel jourh ;// aquisition des jours hebdomadaire movwf jourh call lectureI2C banksel SSP1BUF movfw SSP1BUF call sendAcknowledge banksel jourm ;// aquisition des jours mensuels movwf jourm call lectureI2C banksel SSP1BUF movfw SSP1BUF call sendAcknowledge banksel mois ;// aquisition des mois movwf mois call lectureI2C banksel SSP1BUF movfw SSP1BUF call sendAcknowledge banksel année ;// aquisition des années movwf année call noAcknowledge ;// fin de la lecture call i2cstop ;// fin du bus
goto heure ; goto AffichageNOKIA ;// On arrete d'interroger uniquement lors d'une interruption liée à ; - timmer d'arrosage ; - interruption externe sur ADC: cellule photosensible ; 2) lancement aquisition -> OK ; Start condition bit i2cstart banksel PIR3 bcf PIR3,1 banksel SSP1CON2 bsf SSP1CON2,SEN interuptionflag banksel PIR3 BTFSC PIR3,1 GOTO i2cstart BANKSEL PIR3 btfss PIR3,0 goto interuptionflag bcf PIR3,0 attentefinstart btfsc SSP1CON2,SEN goto attentefinstart
return ; reapeated Start condition bit i2crestart banksel SSP1CON2 bsf SSP1CON2,RSEN attentefinrestart btfsc SSP1CON2,RSEN goto attentefinrestart BANKSEL PIR3 interuptionflag1 btfss PIR3,0 goto interuptionflag1 bcf PIR3,0 return ; Stop condition bit i2cstop banksel SSP1CON2 bsf SSP1CON2,PEN attentefinstop btfsc SSP1CON2,PEN goto attentefinstop BANKSEL PIR3 interuptionflag2 btfss PIR3,0 goto interuptionflag2 bcf PIR3,0 return ; Adresse byte en mode ecriture adressebyteecriture banksel SSP1STAT bcf SSP1STAT,R_W movlw b'11010000' ;// On decale vers la gauche pour mettre 0 au 1er bit banksel SSP1BUF ; indiquant que ce qui suit sera une ecriture movwf SSP1BUF interuptionflag3 banksel PIR3 btfss PIR3,0 goto interuptionflag3 bcf PIR3,0 banksel SSP1STAT testfinadresseecriture btfsc SSP1STAT,BF goto testfinadresseecriture
return ; Adresse byte en mode lecture adressebyte banksel SSP1STAT bsf SSP1STAT,R_W banksel SSP1BUF movlw b'11010000' ;// On decale vers la gauche pour mettre 1 au 1er bit ; indiquant que ce qui suit sera une lecture par le maitre movwf SSP1BUF banksel SSP1STAT interuptionflag4 banksel PIR3 btfss PIR3,0 goto interuptionflag4 bcf PIR3,0 testfinadresse btfsc SSP1STAT,BF goto testfinadresse
return ; Lecture esclave lectureI2C banksel SSP1CON2 bsf SSP1CON2,RCEN testfinlecture banksel SSP1STAT btfsc SSP1STAT,BF goto testfinlecture interuptionflag6 banksel PIR3 btfss PIR3,0 goto interuptionflag6 bcf PIR3,0 return ; verification Acceptance bit received Acknowledge banksel SSP1CON2 btfss SSP1CON2,ACKSTAT return banksel problem bsf problem,0 ;// endroit ou reprendre la derniere adresse pour recomencer l'envoie return ; Envoie Acceptance bit sendAcknowledge banksel PIR3 bcf PIR3,1 banksel SSP1CON2 bsf SSP1CON2,ACKDT bsf SSP1CON2,ACKEN banksel PIR3 BTFSC PIR3,1 GOTO sendAcknowledge interuptionflag7 banksel PIR3 btfss PIR3,0 goto interuptionflag7 bcf PIR3,0 ;// endroit ou reprendre la derniere adresse return ; Envoie No Acceptance bit noAcknowledge banksel SSP1CON2 bsf SSP1CON2,ACKDT bsf SSP1CON2,ACKEN checknoACK btfsc SSP1CON2,ACKEN goto checknoACK ;// endroit ou reprendre la derniere adresse return ; Data byte Databyte banksel Dataa movfw Dataa ;// On deverse la data dans w banksel SSP1BUF movwf SSP1BUF interuptionflag5 banksel PIR3 btfss PIR3,0 goto interuptionflag5 bcf PIR3,0 testfindata banksel SSP1STAT btfsc SSP1STAT,BF goto testfindata
return
end
|
The alchmiste
Starting Member
- Total Posts : 70
- Reward points : 0
- Joined: 2018/03/14 02:55:48
- Location: France
- Status: offline
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/13 14:43:01
(permalink)
Hi Ric,
Is a 1k resistor ok for each line ?
Thanks Thealchimiste
|
ric
Super Member
- Total Posts : 29435
- Reward points : 0
- Joined: 2003/11/07 12:41:26
- Location: Australia, Melbourne
- Status: online
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/13 15:51:56
(permalink)
Do you mean pullups on SDA and SCL? Yes, they should be fine. Just an aside, do NOT clear SSPBUF in your init code. Any write to SSPBUF will try to start a transfer in whatever mode the SSP peripheral happens to be in. That is not a good idea. Your "send start" function looks way too complicated. You have not commented it, so I don't know what you think you are doing, but try cutting it down to just: i2cstart: banksel SSP1CON2 bsf SSP1CON2,SEN ;start sending a START cycle i2cstart_wait: btfsc SSP1CON2,SEN ;has the cycle completed yet? goto i2cstart_wait ;no, keep waiting return
This code is not checking for a bus collision, but your version is not either.
To get a useful answer, always state which PIC you are using!
|
Mysil
Super Member
- Total Posts : 4062
- Reward points : 0
- Joined: 2012/07/01 04:19:50
- Location: Norway
- Status: offline
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/13 16:54:29
(permalink)
Hi, 1 kOhm resistor for pull-up to Vdd for each of SCL and and SDA lines will give a rather strong pull-up current, and is Not a reason for the problem experienced. You may do the following test: With Debugger, set a breakpoint before Start instruction. Measure with Multimeter or Oscilloscope the voltage on SDA and SCL pins: signal voltage on SCL and SDA should both be near Vdd power voltage. Then also observe PORT register bits for SCL and SDA pins, both should be 1. Then step the debugger past: bsf SSP1CON2,SEN and examine PIR3,BCL1IF ; If this bit have been set, then problem have already occurred. Run or step the program until SSP1CON2,SEN go back to 0. Measure voltage on SCL and SDA pins, if voltage is less than 0.4 V, then signal is good, and pull-up current is not too high. Again examine PORTx register in debugger, value shall be 0 for both SCL and SDA bits. If this is Not the case, then problem have already occurred. If all is correct at this point, then you may proceed with address transfer. If PORT bits react as expected to voltage on SCL and SDA pins, but BCL1IF bit still get 1, then problem may be in PPS settings. When trying to assemble the program shown in message #12, then there are a large number of warnings about instructions starting in column 1, and about labels not starting in column 1. Also, there are a lot of labels, that are not delimited with a colon: This seem sloppy to me, and make the code more difficult to understand. Some of the bad formatting may come from whitespace beeing garbled by forum editor, but not everything. Mysil
|
Mysil
Super Member
- Total Posts : 4062
- Reward points : 0
- Joined: 2012/07/01 04:19:50
- Location: Norway
- Status: offline
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/15 09:17:54
(permalink)
Hi, I have found a bug in code shown in message #12 Function to send Acknowledge from master to slave, set wrong value to ACKDT bit. ACK signal shall have ACKDT = 0; Bit value 1 is NACK ; Envoie Acceptance bit sendAcknowledge: banksel PIR3 bcf PIR3,1 banksel SSP1CON2 bsf SSP1CON2,ACKDT ; /* Should be bcf SSP1CON2, ACKDT */ bsf SSP1CON2,ACKEN ...
This cause a Read transfer to terminate after 1 data byte, see attached image. Also function to send Read address have a mistake, there is no 1 bit for Read address, address byte should be: b'11010001' ; Adresse byte en mode lecture adressebyte: banksel SSP1STAT bsf SSP1STAT,R_W banksel SSP1BUF movlw b'11010000' ;// On decale vers la gauche pour mettre 1 au 1er bit ; indiquant que ce qui suit sera une lecture par le maitre movwf SSP1BUF ... There may be other bugs, I have done a lot of changes to run the code with debugger on a different chip, PIC16F1718 and using a EEPROM as stand-in for the RTC. Mysil
post edited by Mysil - 2020/11/15 12:24:52
Attached Image(s)
|
Mysil
Super Member
- Total Posts : 4062
- Reward points : 0
- Joined: 2012/07/01 04:19:50
- Location: Norway
- Status: offline
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/15 12:23:02
(permalink)
Hi, There is another bug. After reading 3 data bytes, containing seconds, minutes and hours, there is something causing Read transfer to be stopped without a NACK issued from master code. Such a truncated transfer cause the Slave device to hold the SDA line, and cause following transfer to detect bus collision problem. This is caused by a big block of logic that try to decode the hours value, and jump away from the read sequence, without continue reading date and following values. Then there is this sequence that Read one data byte, and then try to send Two acknowledge signals, one ACK and one NACK. This cannot work, there must be exactly One acknowledge signal, either NACK or ACK. call lectureI2C banksel SSP1BUF movfw SSP1BUF call sendAcknowledge banksel année ;// aquisition des années movwf année call noAcknowledge ;// fin de la lecture call i2cstop ;// fin du bus
Mysil
|
Mysil
Super Member
- Total Posts : 4062
- Reward points : 0
- Joined: 2012/07/01 04:19:50
- Location: Norway
- Status: offline
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/16 05:00:10
(permalink)
Hi, Here is program project using your code with corrections and modifications to make it work. I do not have your RTC device, or the same PIC device, so have used a EEPROM device as stand-in. There are a number of differences since PIC16F1718 use PIR1 and PIR2 registers for interrupt flags, different from PIR3 in the PIC16f15344 device. Corrections and modifications are done in Experiment_PIC16F1718.asm. Experiment.asm have not been corrected, other than to make it possible to read. Mysil
post edited by Mysil - 2020/11/16 05:20:17
Attached Image(s)
|
The alchmiste
Starting Member
- Total Posts : 70
- Reward points : 0
- Joined: 2018/03/14 02:55:48
- Location: France
- Status: offline
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/16 13:21:29
(permalink)
Hi Mysil, Really apreciate your help. Just to explain you my logic on this big logic block. What I'm doing is to avoide going for a read the date since I've not past 23h59 to update the value of the date, this will save some machine time. So I test each relevant bits of the time intervening in the value of 23h59: banksel heures ; btfss heures,5 ; -> decimal value 2 goto heure ; -> If not set Don't bother with the other bits and continue updating the time banksel heures btfss heures,1 ; -> decimal value 2 goto heure ; banksel heures btfss heures,0 ; -> decimal value 1 goto heure banksel heures btfss minutes,6 -> decimal value 4 goto heure banksel heures btfss minutes,4 -> decimal value 1 goto heure banksel heures btfss minutes,3 -> decimal value 8 goto heure banksel heures btfss minutes,0 -> decimal value 1 goto heure I'll go through your comments in the code and make the test and provide a feedback. I see that you really took the time to go through my code I appreciate it a lot!! Thanks Thealchimiste
|
ric
Super Member
- Total Posts : 29435
- Reward points : 0
- Joined: 2003/11/07 12:41:26
- Location: Australia, Melbourne
- Status: online
Re: PIC 16F15344 I2C perpherial issue with acknowledgment assembly code
2020/11/16 13:57:51
(permalink)
why do it such a convoluted way, rather than just comparing with "23" and "59" ?
To get a useful answer, always state which PIC you are using!
|