USART crashes on PIC18F2550, What can I do? - c

I'm working in the communication of a PIC18F4550 and the PC with a pair of xBEE S2C. And
I am using xc8 to compile the code.
I send some characters to the PIC from the PC with an Xbee then I send a '/r', and the PIC has to return me the characters that I sent.
It works for 9 iterations, then it crashes. The image shows the
Serial Console (red characters are the response of the PIC).
I´ve tried resetting the EUSART but this doesn´t seem to work. Always fails at the 9th iteration. I´ve read some posts of OERR and I tried a lot of things but nothing has solved my problem.
EDIT: ***NOTE: This Error presents if the transmit interval of the package is
less than 1500 ms. And I need to transmit at least every 300ms.
Someone has an idea of what could it be?
Thanks
#define _XTAL_FREQ 8000000
volatile char bufferRx[60];
volatile char bufferTx[60];
volatile char dum;
int RxFlag,ContRx, ContTx;
void interrupt isr()
{
if(RCSTAbits.OERR)
{
RCSTAbits.CREN = 0;
RCSTAbits.CREN = 1;
}
x = RCREG;
if(x== 13)
{
bufferRx[ContRx] = x;
RxFlag=1;
}
else
{
bufferRx[ContRx] = x;
}
ContRx++;
}
void main(void)
{
//////////////////////////////////////////////////////////////////
//CONFIGURACIONES
//OSCILLATOR
OSCCONbits.IRCF= 0b111;
OSCCONbits.SCS=0b10;
//PORTS
PORTB = 0;
TRISB=1;
TRISC=0b10000000;
//INTERRUPTIONS
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
PIE1bits.RCIE=1;
PIE1bits.TXIE=0;
PIR1bits.RCIF=0;
//RCSTA TXSTA
RCSTAbits.SPEN=1;
RCSTAbits.RX9=0;
RCSTAbits.CREN=1;
TXSTAbits.BRGH=0;
TXSTAbits.SYNC=0;
TXSTAbits.TXEN = 1;
TXSTAbits.TX9=0;
//BAUDRATE BAUDCON
BAUDCONbits.ABDEN = 0;
BAUDCONbits.WUE = 0;
BAUDCONbits.TXCKP = 0;
BAUDCONbits.RXCKP = 0;
BAUDCONbits.BRG16=0;
SPBRG=51;
//////////////////////////////////////////////////////////////////
while(1)
{
while(RCSTAbits.FERR)
{
dum = RCREG;
}
if(RCSTAbits.OERR)
{
RCSTAbits.CREN = 0;
RCSTAbits.CREN = 1;
}
ContTx=0;
if(RxFlag==1)
{
for(int x=0;x<ContRx;x++)
{
bufferTx[x] = bufferRx[x];
TXREG=bufferTx[x];
while(TXSTAbits.TRMT==0);
{
__delay_ms(1);
bufferTx[x]= 00;
bufferRx[x]= 00;
}
ContTx++;
}
RxFlag=0;
ContRx=0;
}
}
}

You are not using the "volatile" keyword anywhere although you are modifying some globals inside the ISR and using them outside.

Related

The ISR executed once even when the event not happened

I am using PIC24FJ128GA204 microcontroller in PIC24F Curiosity Development Board.
The ISR is executed at least once even when the event not happened.
Here is the code:
#include <xc.h>
int Random_mode_condition=0;
void __attribute__((__interrupt__, __shadow__)) _INT1Interrupt(void) {
Random_mode_condition = 44;
_INT1IF = 0;
}
void RC9_Switch_Config() {
_TRISC9 = 1; // Switch input
RPINR0bits.INT1R = 25;
IFS1bits.INT1IF=0;//Clear the interrupt flag
IPC5bits.INT1IP1=1;//Choose a priority
INTCON2bits.INT1EP=0;//rising edge
IEC1bits.INT1IE=1;//enable INT1 interrupt
}
int main() {
LATC=0x0000;
RC9_Switch_Config();
while(1){
if(Random_mode_condition==44){ TRISC=0x0000; LATC=0xffff;}
}
return 0;
}
Random_mode_condition will equal 44 then the if statement will be executed.
Please help

No output for Embedded application with PIC12, MPLAB and UART

I am working on RGB LED project and that's controlled by a PIC12F1572. The software that I am using is MPLAB IDE with the HiTech C compiler. The plan is to use serial communication to send LED RGB combination data commands to the PIC to be stored in a variable that will make it perform the LED blink and glowing I have been able to establish UART communication.Every function or step I code is right by syntax and works on linux command line terminal if I compile..
And it fails if I try to simulate using register injection in MPLAB.I wanted to run it in simulation also (anyone knows how register injection actuallly works in MPLAB?)
The problem I face together when I try to debug . it compiles but doesn't work
here is my code :
Any idea or hint about the problem will be highly appreciated.
I personally fee that placing the code [hierarchical way] may be wrong
Thanks!
#include <xc.h>
#include "mcc.h"
#include "LED.h"
#include "tmr0.h"
#include "interrupt_manager.h"
void SetLedColor(uint16_t R_color, uint16_t G_color, uint16_t B_color);
void main(void)
{
uint8_t data, i, j;
uint16_t R_value, G_value, B_value;
uint8_t value;
uint8_t RX_Buffer[FRAMESIZE] ,RGB_data[6] ,HEX_data[6];
// initialize the device
SYSTEM_Initialize();
INTERRUPT_GlobalInterruptEnable(); // Enable the Global Interrupts
INTERRUPT_PeripheralInterruptEnable(); // Enable the Peripheral Interrupts
while (1)
{
// EUSART_Write(0x61);
while (!RCIF)
{
data = EUSART_Read(); // Read received character
for (i = 0; i < FRAMESIZE; i++)
{
RX_Buffer[i] = data;
}
EUSART_Write(data);
}
//check if any data is received
for (j = 0; j = 5; j++) // get the RGB value in the separate array
{
RGB_data[j] = RX_Buffer[j + 3];
HEX_data[value] = RGB_data[j] / 16;
}
if (RX_Buffer[0] == 'R' && RX_Buffer[FRAMESIZE - 1] == '\n')
{
//ASCII to HEX separate values
// uint32_t number = (uint32_t)strtol(HEX_data, NULL, 16);
// R_value = number >>16;
// G_value = (number & 0xffff) >> 8;
// B_value = (number & 0x0000FF);
R_value = (uint16_t) atoh(HEX_data[0], HEX_data[1]);
G_value = (uint16_t) atoh(HEX_data[2], HEX_data[3]);
B_value = (uint16_t) atoh(HEX_data[4], HEX_data[5]);
}
SetLedColor(R_value, G_value, B_value);
}
}
void SetLedColor(uint16_t R_color, uint16_t G_color, uint16_t B_color)
{
if (R_color == 0xFF)
{
LATAbits.LATA2 = 1;
}
else
{
LATAbits.LATA2 = 0;
}
if (G_color == 0xFF)
{
LATAbits.LATA4 = 1;
}
else
{
LATAbits.LATA4 = 0;
}
if (B_color == 0xFF)
{
LATAbits.LATA5 = 1;
}
else
{
LATAbits.LATA5 = 0;
}
}
So till the receiving the UART frame and echoed back and from the storing data make LED blink , I am able to succeed and this is what I wanted for primary step here by hierarchical way
#include "mcc_generated_files/mcc.h"
#include <stdlib.h>
#include <stdio.h>
#include "atoh.h"
#include "LED.h"
#define _XTAL_FREQ 16000000
#define FRAMESIZE 19
void main(void)
{
uint8_t data,i,j,got_char;
uint8_t R_value, G_value ,B_value;
uint8_t value;
uint8_t RX_Buffer[FRAMESIZE];
uint8_t RGB_data[6] ,HEX_data[6];
// initialize the device
SYSTEM_Initialize();
INTERRUPT_GlobalInterruptEnable(); // Enable the Global Interrupts
INTERRUPT_PeripheralInterruptEnable(); // Enable the Peripheral Interrupts
while (1)
{
if (EUSART_DataReady)
{
for (i = 0; i<FRAMESIZE; i++)
{
RX_Buffer[i] = EUSART_Read();
if (RX_Buffer[i] == '\n')
break;
}
RX_Buffer[i] = '\n'; //append '\n' at the end of stoaring array for detection of frame
RX_Buffer[i+1] = '\0'; // End of an array
EUSART_WriteAnArrayOfBytes(RX_Buffer);
if(RX_Buffer[0]=='R' && RX_Buffer[FRAMESIZE-2] == '\n') //check for correct frame
{
LATAbits.LATA2 = 1;
__delay_ms(2000);
LATAbits.LATA2 = 0;
__delay_ms(1000);
}
}
}

Atmel studio with Xmega Timer/USART

I'm new in embedded systems developing also in Atmel studio Environment,
I'm using Atxmega128a1 with 32MHz system clk.
I'm trying to send some characters to the PC thought RS232 module at every timer interrupt overflow (0.05s),
so I defined (tc)Timers,USART Drivers on ASF and wrote the below code in main.c file, finally I debugged it without any error but not succeeded to transmit any thing through serial port.
anyone can help me or give me some advices.
#include <asf.h>
volatile int flag=0;
uint8_t received_byte;
uint8_t tx_buf[] = "\n\rHello AVR world ! : ";
uint8_t tx_length = 22;
uint8_t i;
static void my_callback(void)
{
flag =1;
}
int main (void)
{
/* Insert system clock initialization code here (sysclk_init()). */
board_init();
sysclk_init();
static usart_rs232_options_t USART_SERIAL_OPTIONS = {
.baudrate = 9600,
.charlength = 8,
.paritytype = USART_PMODE_DISABLED_gc,
.stopbits = false
};
usart_init_rs232(& USARTF0, &USART_SERIAL_OPTIONS);
//usart_set_baudrate_precalculated(& USARTF0,0x00017700,0x01E84800);
/* Insert application code here, after the board has been initialized. */
if (flag==1)
{
//received_byte = usart_getchar(& USARTF0);
//if (received_byte == '\r') {
for (i = 0; i < tx_length; i++)
{
usart_putchar(& USARTF0, tx_buf[i]);
}
}
else
usart_putchar(& USARTF0, received_byte);
flag=0;
}
I believe you are missing the initialization of the related system clock module:
sysclk_enable_module(SYSCLK_PORT_F, PR_USART0_bm);

PIC endless loop

I am trying to program PIC16F887 and having this interesting problem. I expect from LED to blink one-time and stop forever, however it starts back and never stops although watchdog is disabled. Here is the code. Thanks in advance.
I wrote this in MPLAB v8.84 and programmed using PICkit2 and Hi-Tech C compiler.
#include <htc.h>
#include <pic.h>
#define _XTAL_FREQ 800000
//__CONFIG(0x3FF5);
//functions
void INITgeneral(void);
void ledshow (void);
void main(void) {
INITgeneral();
ledshow();
return;
}
void INITgeneral(void)
{
TRISA = 0;
TRISB = 0;
TRISC = 0;
TRISD = 0;
TRISE = 0;
PORTA = 0;
PORTB = 0;
PORTC = 0;
PORTD = 0;
PORTE = 0;
}
void ledshow(void)
{
__delay_ms(400);
RD0 = 1;
__delay_ms(400);
RD0 = 0;
}
The built-in simulator is very helpful in finding issues such as this one, well worth learning about.
Under the ‘View’ tab select ‘Disassembly Listing’. Notice that the next instruction after returning from the call to ledshow() is the instruction GOTO 0 which loads the program counter with zero, the reset vector. This is why you are endlessly executing the program.
To stop this behavior replace return in main() with an endless loop while(1){};

Receiving OK response for AT command via PIC Microcontroller

char rcv[10];
void main()
{
UART1_Init(9600);
Delay_ms(2000);
TRISB=0x00;
UART1_Write_Text("at");
UART1_Write(13); //Enter key = CF + LF
UART1_Write(10);
delay_ms(500);
while (1)
{ PORTB.RB0=1; // Endless loop
while(!UART1_Data_Ready()); // If data is received,
rcv[0]=UART1_Read();
rcv[1]=UART1_Read();
rcv[2]='\0';
UART1_Write_Text(rcv);
PORTB.RB0=0;
}
}
Compiler used : MikroC
I get the rcv output as ATTTTTTTTT. Pls help me out here to receive OK response from GSM Modem as this works with Hyperterminal.
Using PIC 18F4520 in PICPLC16v6 development board from Mikroelectronika.
It seems that you have the modem echo set on, so you'll receive each caracter you send it.
I would rewrite your code to something like :
void main(void)
{
uint8_t cmd[10];
uint8_t answer[20];
uint16_t timeout = 500; //max miliseconds to wait for an answer
UART1_Init(9600);
Delay_ms(1000);
TRISB=0;
cmd[0]='A';
cmd[1]='T';
cmd[2]=13;
cmd[3]=10;
cmd[4]=0;//marks end of CMD string
while(1)
{
uint8_t answer_len = SendModemCMD(cmd,answer,timeout);
UART1_Write_Text(answer);
Delay_ms(500);//not really needed ...
}
}
uint8_t SendModemCMD(uint8_t *cmd,uint8_t* answer,uint16_t timeout)
{
uint16_t local_timeout;
uint8_t answer_len=0;
while(*cmd!=0)
{
UART1_Write(*cmd++);
local_timeout=timeout;
while(local_timeout>0 && !UART1_Data_Ready())
{
Delay_ms(1);
local_timeout--;
}
if(UART1_Data_Ready())
{
UART1_Read();//discard echoed character
}
}
uint8_t finished=0;
while(finished==0)
{
local_timeout=timeout;
while(local_timeout>0 && !UART1_Data_Ready())
{
Delay_ms(1);
local_timeout--;
}
if(UART1_Data_Ready())
{
*answer++=UART1_Read();
answer_len++;
}
else
{
finished=1;
}
}
*answer=0;
return answer_len;
}

Resources