0

I am using MPLAB XC8 and I try to use the USART module. But I have abnormal problem. Here is my code, I explain after this.

#include <xc.h>
#include "conbits.h"

#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>

#define _XTAL_FREQ 8000000


void UART_RX_INIT(void);
void UART_TX(uint8_t *s);
void usart_send_str(uint8_t s[]);

uint8_t rx_buffer[];
uint8_t UART_Buffer = 0;
int rx_index=0;
bool rx_reg_ok = false;
uint8_t data;


void main(void) {

    OSCCONbits.IRCF = 0X07;
    OSCCONbits.SCS = 0X03;

    while(OSCCONbits.HFIOFS !=1);

    RCONbits.IPEN = 1;
    ei();

    UART_RX_INIT();

    TRISD = 0X00;
    LATD = 0X00;

    while(1)
    {
        
    }

  
}

void UART_RX_INIT(){
    TRISCbits.TRISC7 = 1;
    TRISCbits.TRISC6 = 0;
    
    SPBRG = 51;
    
    RCSTAbits.CREN = 1;
    RCSTAbits.SPEN = 1;
    BAUDCON1bits.BRG16 = 0;
    
    TXSTA1bits.SYNC = 0;
    TXSTA1bits.BRGH = 1;
    TXSTAbits.TXEN = 1;
    
    IPR1bits.RCIP = 1;
    PIE1bits.RCIE = 1;
    
    IPR1bits.TXIP = 0;
    PIE1bits.TXIE = 1;
}


void __interrupt(high_priority) ISR(void){
    if(PIR1bits.RC1IF==1){
        UART_Buffer = RCREG1;
     
        if(UART_Buffer == 36 && rx_index==0)
        {
            memset(rx_buffer, 0, strlen(rx_buffer));
            rx_buffer[0] = UART_Buffer;
            rx_index++;
            rx_reg_ok=true;
        }
        else if(rx_reg_ok && UART_Buffer != 36)
        {
            rx_buffer[rx_index] = UART_Buffer;
            usart_send_str(rx_buffer);
            usart_send_str("\r\n");
            rx_index++;
        }
        else
        {
            usart_send_str("\r\nNot Registered\r\n");
        }
        if(UART_Buffer == 45)
        {
            usart_send_str("\r\n-----");
            usart_send_str(rx_buffer);
            usart_send_str("-----\r\n");
        }
        
        
        PIR1bits.RC1IF = 0;
        
    }
}

void __interrupt(low_priority) low_isr(void){
    INTCONbits.GIEH = 0;
    if(PIR1bits.TXIF){
        PIR1bits.TXIF=0;
    }
    INTCONbits.GIEH = 1;
}

///////////////////////////TRANSMIT
void UART_TX(uint8_t *s){
    TXREG = *s;
    while(TXSTA1bits.TRMT==0);
    
}
void usart_send_str(uint8_t s[]){

    int i=0;
    while(s[i]!='\0')
    {
        UART_TX(&s[i]);
        i++;
    }
}

Focus on inside the High Interrupt function block First Unless I press '$' char send. PIC18 responses are just "Not Registered". After I press '$' char, It will add the next pressed chars to rx_buffer array.

My problem starts right there. Chars I pressed in order '1', '2' they send me 'Not Registered' and I press '$' they start adding to rx_buffer array and show me. Also for checking the buffer. If I send '-' char, It shows me rx_buffer. But If you look at the picture you can see. My problem after I press '$' second char is always 2 decimal higher. I press 'a' but it registered as 'c' to buffer. If I press '1' after '$', It register '3' this problem only happens after '$'. How can I fix this? Here is my simulation output.I press '1' - '2' - '$' - 'a' - 'b' - 'c' - '-'

I press '1' - '2' - '$' - 'a' - 'b' - 'c' - '-'

I press '1' - '2' - '$' - '1' - '2' - '3' - '-'

batgre
  • 1
  • 1
    rx_buffer is going to need some length e.g. uint8_t rx_buffer[20]; – Accidental Vegetarian Feb 09 '22 at 15:26
  • 1
    You do: `uint8_t rx_buffer[];` This causes UB. Try (e.g) `uint8_t rx_buffer[100];` Change `memset(rx_buffer, 0, strlen(rx_buffer));` into `memset(rx_buffer, 0, sizeof(rx_buffer));` Better yet: When storing, do: `rx_buffer[rx_index++] = UART_Buffer; rx_buffer[rx_index] = 0;` This ensures that you have a properly terminated string when you call `usart_send_str` – Craig Estey Feb 09 '22 at 15:28
  • 1
    But, your code is sort of a "one shot". That is [even if it were working], eventually the buffer fills up and overflows. You never reset `rx_index`. Nor do you check whether it has overflowed the buffer. – Craig Estey Feb 09 '22 at 15:30
  • @CraigEstey Thanks for the help adding array range 100 fix it – batgre Feb 10 '22 at 06:06

0 Answers0