Sorry to bother you, but I've been encountering an issue while trying to assign data from RCREG to a variable. In all the other PICs I've used (currently using 18F4550), it was quite straightforward. I would simply use something like:
new_variable = RCREG;
However, now when I do this, it seems to clear RCREG and doesn't transfer anything to the variable where I intend to store the value. Here's the code snippet for reference:
Edit 1:
Hey! Thanks for the tips. I'm new here, still learning how to post. I'll check @the_busybee's links. First, let me clarify my earlier point.
In v_aux2 = RCREG; line, it should transfer RCREG's value to v_aux2. While debugging, I set breakpoints in that line and NOP(); to pause, checking if the value written in RCREG via MPLAB X's SFR window is assigned to v_aux2. The issue: when the processor stops at NOP();, 0 is written to v_aux2. It's like the RCREG was read and cleared before its value been assigned to v_aux2.
And my question is: What could cause this?
What I want and expect is assign the hex value 0x55 to variable v_aux2 via RCREG.
I will post my configuration function here to:
void config_serial(void)
{
TRISCbits.RC7 = 1; // sets RC7 as RX
TRISCbits.RC6 = 1; // sets RC6 as TX
RCSTAbits.SPEN = 1; // configures TX/RX pins as serial pins
TXSTAbits.SYNC = 0; // selects asynchronous mode
TXSTAbits.TX9 = 1; // sets 9-bit transmission
TXSTAbits.BRGH = 0; // selects low-speed baud rate generator
// TXEN = 1; bit that enables serial transmission (brings TX pin to 5 Volts)
// TXSTAbits.SENDB = 1; sends 8 bits of 0 as a frame end detection
RCSTAbits.RX9 = 1; // enables 9-bit detection
RCSTAbits.CREN = 1; // disables continuous bit reception
RCSTAbits.ADDEN = 1; // enables address detection along with interruption
BAUDCONbits.RCIDL = 0; // ensures bit reception is active
BAUDCONbits.TXCKP = 0; // TX data is not inverted
BAUDCONbits.RXDTP = 0; // received data is not inverted
PIE1bits.TXIE = 0; // disables interrupt for data to be transmitted
PIE1bits.RCIE = 1; // enables interrupt for data reception
BAUDCONbits.WUE = 0; // wake up enable bit
BAUDCONbits.BRG16 = 0;
SPBRG = 0x1F; // selects baud rate generator for 19200 kilobaud
TXEN = 1;
OERR = 0;
FERR = 0;
}
edit 2:
Thank you once again for the tips, and let's dive into the details. Yes, I do observe the value 0x55 in RCREG before the compiler proceeds and executes the line. To inspect the machine code, I utilize the 'disassembly' window in MPLAB X. I'm unsure if this is the correct approach, so I appreciate your guidance.
To be honest, I don't have much experience in assembly coding, and I'm having difficulty understanding what the code is conveying. I'll share it here for your assistance. Your insights would be immensely helpful guys.
The code in Assembly:
!void recebe_serial(void)
!{
! //TMR0IE = 0;
! if(OERR)// overload error detected
0x354: BTFSS RCSTA, 1, ACCESS
0x356: BRA 0x362
! {
! OERR = 0;
0x358: BCF RCSTA, 1, ACCESS
! /*serial comunication reinicialized*/
!
! CREN = 0;
0x35A: BCF RCSTA, 4, ACCESS
! CREN = 1;
0x35C: BSF RCSTA, 4, ACCESS
!
! if (FERR)
0x35E: BTFSC RCSTA, 2, ACCESS
! {
! //in future implement timer 1 here
! FERR = 0;
0x360: BCF RCSTA, 2, ACCESS
! }
! }
! static ui8b index = INICIAL_VALUE_PROG;
!
! ui8b v_aux2 = RCREG;
0x362: MOVFF RCREG, v_aux2
0x364: NOP
! NOP();
0x366: NOP
! //transmite_serial(v_aux);
! if (v_aux2 == 0x55)
0x368: MOVLW 0x55
0x36A: XORWF v_aux2, W, ACCESS
0x36C: BTFSS STATUS, 2, ACCESS
0x36E: RETURN 0
! {
! recebe[endereco] = (RCREG ^ BYTE_MASK_PROG);
0x370: MOVF RCREG, W, ACCESS
0x372: XORLW 0x55
0x374: MOVWF recebe, ACCESS
! ADEN = 0;
0x376: BCF RCSTA, 3, ACCESS
! RCIF = 0;
0x378: BCF PIR1, 5, ACCESS
! //liga_desliga_cargas(1, idc);
! while(index < QTD_DATA_PROG)
0x37A: BRA 0x398
0x398: MOVLW 0x5
0x39A: CPFSGT index, ACCESS
0x39C: BRA 0x37C
! {
! if(RCIF)
0x37C: BTFSS PIR1, 5, ACCESS
0x37E: BRA 0x398
! {
! recebe[index] = RCREG ^ BYTE_MASK_PROG;
0x380: MOVF index, W, ACCESS
0x382: MULLW 0x1
0x384: MOVLW 0x1
0x386: ADDWF PROD, W, ACCESS
0x388: MOVWF FSR2, ACCESS
0x38A: MOVLW 0x0
0x38C: ADDWFC PRODH, W, ACCESS
0x38E: MOVWF FSR2H, ACCESS
0x390: MOVF RCREG, W, ACCESS
0x392: XORLW 0x55
0x394: MOVWF INDF2, ACCESS
! index++;
0x396: INCF index, F, ACCESS
! }
! }
! if (index == QTD_DATA_PROG)
0x39E: MOVLW 0x6
0x3A0: XORWF index, W, ACCESS
0x3A2: BTFSS STATUS, 2, ACCESS
0x3A4: BRA 0x3AC
! {
! index = INICIAL_VALUE_PROG;
0x3A6: MOVLW 0x1
0x3A8: MOVWF index, ACCESS
! ADEN = 1;
0x3AA: BSF RCSTA, 3, ACCESS
! }
! menu_fct_slaves();
0x3AC: CALL 0x100, 0
0x3AE: NOP
0x3B0: RETURN 0
edit 3 Hey, I've been testing this code in MPLAB again. This time, I observed a change in the assembly code that seems a bit confusing to me. What caught my attention is the line I marked with '**', which reads: 0x2B2: MOVFF RCREG, qtd_int_ext. However, when I hover my mouse over 'qtd_int_ext', it indicates that the variable is out of scope. If my basic knowlege in assembly is right it should be like: 0x2B2: MOVFF RCREG, v_aux2. Right?
Here's the snippet:
!void recebe_serial(void)
!{
! //TMR0IE = 0;
! if(OERR)// erro de sobre carga detectado
0x2A4: BTFSS RCSTA, 1, ACCESS
0x2A6: BRA 0x2B2
! {
! OERR = 0;//zerado flag em software
0x2A8: BCF RCSTA, 1, ACCESS
! /*serial comunication reinicialized*/
!
! CREN = 0;
0x2AA: BCF RCSTA, 4, ACCESS
! CREN = 1;
0x2AC: BSF RCSTA, 4, ACCESS
!
! if (FERR)
0x2AE: BTFSC RCSTA, 2, ACCESS
! {
! FERR = 0;
0x2B0: BCF RCSTA, 2, ACCESS
! }
! }
! static ui8b index = INICIAL_VALUE_PROG;
!
! ui8b v_aux2 = RCREG;
**0x2B2: MOVFF RCREG, qtd_int_ext**//strange assembly line.
0x2B4: NOP
! NOP();
0x2B6: NOP
! //transmite_serial(v_aux);
! if (v_aux2 == 0x55)
0x2B8: MOVLW 0x55
0x2BA: XORWF v_aux2, W, ACCESS
0x2BC: BTFSS STATUS, 2, ACCESS
0x2BE: RETURN 0
! {
! recebe[endereco] = (RCREG ^ BYTE_MASK_PROG);
0x2C0: MOVF RCREG, W, ACCESS
0x2C2: XORLW 0x55
0x2C4: MOVWF recebe, ACCESS
! ADEN = 0;
0x2C6: BCF RCSTA, 3, ACCESS
! RCIF = 0;
0x2C8: BCF PIR1, 5, ACCESS
! //liga_desliga_cargas(1, idc);
! while(index < QTD_DATA_PROG)
0x2CA: BRA 0x2E8
0x2E8: MOVLW 0x5
0x2EA: CPFSGT index, ACCESS
0x2EC: BRA 0x2CC
! {
! if(RCIF)
0x2CC: BTFSS PIR1, 5, ACCESS
0x2CE: BRA 0x2E8
! {
! recebe[index] = RCREG ^ BYTE_MASK_PROG;
0x2D0: MOVF index, W, ACCESS
0x2D2: MULLW 0x1
0x2D4: MOVLW 0x1
0x2D6: ADDWF PROD, W, ACCESS
0x2D8: MOVWF FSR2, ACCESS
0x2DA: MOVLW 0x0
0x2DC: ADDWFC PRODH, W, ACCESS
0x2DE: MOVWF FSR2H, ACCESS
0x2E0: MOVF RCREG, W, ACCESS
0x2E2: XORLW 0x55
0x2E4: MOVWF INDF2, ACCESS
! index++;
0x2E6: INCF index, F, ACCESS
! }
! }
! if (index == QTD_DATA_PROG)
0x2EE: MOVLW 0x6
0x2F0: XORWF index, W, ACCESS
0x2F2: BTFSS STATUS, 2, ACCESS
0x2F4: BRA 0x2FC
! {
! index = INICIAL_VALUE_PROG
0x2F6: MOVLW 0x1
0x2F8: MOVWF index, ACCESS
! ADEN = 1;
0x2FA: BSF RCSTA, 3, ACCESS
! }
! menu_fct_slaves();
0x2FC: CALL 0x100, 0
void recebe_serial(void)
{
//TMR0IE = 0;
if (OERR) // over load error detected
{
OERR = 0; //flag cleared
/*serial comunication reinicialized*/
CREN = 0;
CREN = 1;
if (FERR)
{
//in future set timer 1 to watch for this flag
FERR = 0;
}
}
static ui8b index = 0x00;
ui8b v_aux2 = 0x00;
v_aux2 = RCREG;
NOP();
//transmite_serial(v_aux);
if (v_aux2 == 0x55) //faz um byte mask para saber se o endereço sendo chamdo é o mesmo
{
recebe[endereco] = (RCREG ^ BYTE_MASK_PROG);
ADEN = 0;
RCIF = 0;
while (index < QTD_DATA_PROG)
{
if (RCIF)
{
recebe[index] = RCREG ^ BYTE_MASK_PROG;
index++;
}
}
if (index == QTD_DATA_PROG)
{
index = INICIAL_VALUE_PROG;
ADEN = 1;
}
//TMR0IE = 1;
}
}
The preceding code is a function that initially receives a value from RCREG. Utilizing the RX9D for address detection, it compares the received value to check if the device has been addressed. Following that, it proceeds to populate another variable with data, which I utilize in other sections of my program.
I apologize for bothering you with such a straightforward question, but I can't believe I've spent an entire day on this and still haven't been able to solve the problem.
I would like to add that I tested this program in MPLAB X v3.65 debugger, and my compiler is XC8 v1.40.