I'm trying to realize the communication of the PC (linux) with a PIC18F4620 for rs232. The Transmition (PIC -> to PC is fine). However, when I try to pass somenthing from the PC to PIC the PIR1bits.RCIF flag is never set and the interrupt does NOT occurs.
That is my (PIC18f) code (one version):
/*
* sdcc --use-non-free -mpic16 -p18f4620 test_lcd_serial.c
* stty -F /dev/ttyUSB0 9600
*/
#include <pic18fregs.h>
#include <pic18f4620.h>
#include <delay.h>
#include <stdio.h>
#include <usart.h>
#include "lcd.c"
//__code char __at 0x300000 _conf0 = 0x00;
//~ __code char __at __CONFIG1H _conf1 = 0x06;// oscilador HS-PLL
__code char __at __CONFIG1H _conf1 = 0x02;// oscilador HS
__code char __at __CONFIG2L _conf2 = 0x1e;
__code char __at __CONFIG2H _conf3 = 0x1e;
__code char __at 0x300004 _conf4 = 0x00;
__code char __at __CONFIG3H _conf5 = 0x01;
__code char __at __CONFIG4L _conf6 = 0x81;
__code char __at 0x300007 _conf7 = 0x00;
__code char __at __CONFIG5L _conf8 = 0x0f;
__code char __at __CONFIG5H _conf9 = 0xc0;
__code char __at __CONFIG6L _confA = 0x0f;
__code char __at __CONFIG6H _confB = 0xe0;
__code char __at __CONFIG7L _confC = 0x0f;
__code char __at __CONFIG7H _confD = 0x40;
char buf[255];
void main(void)
{
unsigned char count;
unsigned char caracter;
lcd_init( FOURBIT_MODE );
lcd_home();lcd_puts("Start Test"); delay_s(1);
lcd_home();lcd_puts("Start Test."); delay_s(1);
lcd_home();lcd_puts("Start Test.."); delay_s(1);
lcd_home();lcd_puts("Start Test..."); delay_s(1);
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
usart_open(
USART_TX_INT_OFF & //0x7f
USART_RX_INT_ON & //0xff
USART_BRGH_HIGH & //0xff
USART_EIGHT_BIT & // 0xfd
USART_ASYNCH_MODE, //0xfe
129 // 9600 at 20MHz
);
stdout = STREAM_USART;
count = 1;
while(1){ //This works fine :)
printf("To PC: %i\r", count);
sprintf( buf, "Sent: %i", count );
//even if I print (in LCD) the PIR1bits.RCIF is always 0
// sprintf( buf, "Sent: %i,%i", count, PIR1bits.RCIF );
lcd_home();lcd_puts( " " );
lcd_home();lcd_puts( buf );
delay_ms(500);
count++;
}
}
void printrx(){
unsigned char pnt = 0;
while(PIR1bits.RCIF){
buf[ pnt++ ] = RCREG;
// clear CREN
// RCSTAbits.CREN = 0;
// RCSTAbits.CREN = 1;
}
if( pnt ){
sprintf( buf, "GOT1 %s", buf );
lcd_home();lcd_puts( " " );
lcd_home();lcd_puts( buf );
delay_ms(1000);
}
}
void receive_intr1() interrupt 1 { //this is never call
if( PIR1bits.RCIF ) // serial received
printrx();
}
void receive_intr2() interrupt 2 {
if( PIR1bits.RCIF ) // serial received
printrx();
}
In PC I did:
>cat /dev/ttyUSB
To PC: 1
To PC: 2
To PC: 3
To PC: 4
To PC: 5
To PC: 6
To PC: 7
To PC: 8
To PC: 9
To PC: 10
...
So, PIC to PC is OK. But when I try:
echo "something" > /dev/ttyUSB0
or
cat > /dev/ttyUSB0
something
or even if I write a code to open the /dev/ttyUSB0 as a file and write, use the python serial module, nothing happen.
I have locked at the SDCC usart implementation and it's look fine. However I notice that somethings had been changed recently. (SDCC usart source). So maybe the SDCC usart have errors and I decide implements by myself. So I change the usart code:
usart_open(
USART_TX_INT_OFF & //0x7f
USART_RX_INT_ON & //0xff
USART_BRGH_HIGH & //0xff
USART_EIGHT_BIT & // 0xfd
USART_ASYNCH_MODE, //0xfe
129 // 9600 at 20MHz
);
By a my specific code (8bits, RX with interrupt, no Parity):
// Serial Interrupts
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
PIE1bits.RCIE = 1;
IPR1bits.RCIP = 0;
PIE1bits.TXIE = 0;
IPR1bits.TXIP = 0;
TRISCbits.TRISC7 = 1; //RX (1:input)
TRISCbits.TRISC6 = 1; //TX (0:output)
//~ TXSTAbits.CSRC = 0; //Don't care
TXSTAbits.TX9 = 0;
TXSTAbits.TXEN = 1;
TXSTAbits.SYNC = 0;
TXSTAbits.SENDB = 0;
TXSTAbits.BRGH = 1;
//~ TXSTAbits.TRMT //Read Only
TXSTAbits.TX9D = 0;
RCSTAbits.SPEN = 1;
RCSTAbits.RX9 = 0;
//~ RCSTAbits.SREN = 0; //Don't care
RCSTAbits.CREN = 1;
//~ RCSTAbits.ADDEN = 0; //Don't care
//~ RCSTAbits.FERR //Read Only
//~ RCSTAbits.OERR //Read Only
//~ RCSTAbits.RX9D //Read Only
//~ BAUDCONbits.ABDOVF //Read
//~ BAUDCONbits.RCIDL //Read Only
BAUDCONbits.RXDTP = 0;
BAUDCONbits.TXCKP = 0;
BAUDCONbits.BRG16 = 0;
//~ Not implemented
BAUDCONbits.WUE = 0;
BAUDCONbits.ABDEN = 0;
SPBRG = 129;
stdout = STREAM_USART;
And all is fine. Can be useful for someone the stty command configure a lot of stuffs related to the device communication. For instance set baudrate to 9600 and disable echo
stty -echo -F /dev/ttyUSB0 9600
Show all configuration
stty -a -F /dev/ttyUSB0