mariuszoll
Member level 5
- Joined
- Aug 28, 2012
- Messages
- 82
- Helped
- 1
- Reputation
- 2
- Reaction score
- 0
- Trophy points
- 1,286
- Activity points
- 2,147
Hi,
I have to implement a serial communication via USART interface between 2 PICs(18F2620 and 18F4550). The transmitter has implemented a card reader application and a LCD. First, it reads the information from the card, and it sends it to the receiver. Depends on this information the receiver turns on some LEDs, and the receiver responds back with a message. I measured with the oscilloscope the signal on both the transmitter and the receiver sides and they are identical, but nothing is displayed on the LCD. I thought that there is a problem with the receiving part, and I tried to implement an ISR for EUSART receive part. The code is written in C, I use MPLAB, MCC18 compiler. Please find attached my code:
//Program
Thank you in advance.
I have to implement a serial communication via USART interface between 2 PICs(18F2620 and 18F4550). The transmitter has implemented a card reader application and a LCD. First, it reads the information from the card, and it sends it to the receiver. Depends on this information the receiver turns on some LEDs, and the receiver responds back with a message. I measured with the oscilloscope the signal on both the transmitter and the receiver sides and they are identical, but nothing is displayed on the LCD. I thought that there is a problem with the receiving part, and I tried to implement an ISR for EUSART receive part. The code is written in C, I use MPLAB, MCC18 compiler. Please find attached my code:
//Program
Code:
/* LCD 16x2
4 bit mode
RA7--> RS
RA6-->Enable
RW-->GND
RC0..RC3 --> DB4 to DB7
LCD: PC1602-H from PowerTip
ST7066U_lcd_driver
PIC18F2620
4MHz
*/
#include <p18f2620.h>
#include <delays.h>
#include <string.h>
#include <usart.h>
// Pragma
#pragma config WDT = OFF // watch dog disabled
#pragma config OSC = INTIO67
#pragma config IESO = OFF //Oscillator Switchover mode disabled
#pragma config XINST = OFF
#pragma config BOREN = OFF //Brown-out Reset disabled in hardware and software
#pragma config PBADEN=OFF //PORTB<4:0> pins are configured as digital I/O on Reset
#pragma config STVREN=OFF //Stack full/underflow will not cause Reset
#pragma config LVP=OFF //Single-Supply ICSP disabled
#pragma config MCLRE=ON //MCLR pin enabled
//*****************************************************************************
// CONSTANT DEFINITION
//*****************************************************************************
# define databits LATC // LCD 4 bit data PORT
# define data0 PORTBbits.RB4 // data0(green wire) of RFID tag
# define data1 PORTBbits.RB3 // data1(white wire) of RFID tag
# define btn1 PORTCbits.RC4 // button for save mode (active low)
//*****************************************************************************
// Variables
char string[15]="Place your tag";
char string1[15]="on the reader";
char string2[10]="Save mode";
char string3[7]="Id no:";
char string4[16]="User identified";
char string5[15]="User ID saved";
char string6[20]="User not found";
char txarray[9]="";
char rxarray[23]="";
char receive[22]="";
int i=0,q,m=0;
unsigned char rxchar,r=0,flag=0, icount=0,check=0;
void high_isr(void);
/****** High priority interrupt vector ******/
#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
_asm GOTO high_isr _endasm
}
#pragma code
/********** High priority ISR **************/
#pragma interrupt high_isr
void high_isr(void)
{
if(PIR1bits.RCIF)
{
if(RCSTAbits.FERR==1)
{
rxchar=RCREG;
RCSTAbits.CREN=0;
RCSTAbits.CREN=1;
}
if(RCSTAbits.OERR==1)
{
rxchar=RCREG;
RCSTAbits.CREN=0;
RCSTAbits.CREN=1;
}
rxchar=RCREG;
rxarray[r]=rxchar;
r++;
if(rxchar=='\r') // if the character is Enter flag is put on 1
{
flag=1;
}
check=1;
}
PIR1bits.RCIF=0;
}
/** L O C A L F U N C T I O N S *******************************************/
void set_hi_nibble(unsigned char data) // output hi nibble data on port lines
{
unsigned char temp=LATC;
temp= temp & 0xF0;
temp= temp | (data>>4);
LATC=temp;
}
void set_lo_nibble(unsigned char data) // output low nibble data on port lines
{
unsigned char temp=LATC;
temp= temp & 0xF0;
temp= temp | (data & 0x0F);
LATC=temp;
}
void en_set(void) //function used to set Enable signal properly
{
PORTAbits.RA6 = 1; // Set EN on 1
Delay1KTCYx(1);
PORTAbits.RA6 = 0; // Set EN on 0
}
void send_char(unsigned char c)
{
LATAbits.LATA7=1; // set RS on 1
set_hi_nibble(c);
en_set();
Delay1KTCYx(5); // delay 50ms
set_lo_nibble(c);
en_set();
Delay1KTCYx(5); // delay 5ms
}
void cmd(unsigned char c)
{
LATAbits.LATA7=0; // set RS on 0
set_hi_nibble(c);
en_set();
Delay1KTCYx(5); // delay 50ms
set_lo_nibble(c);
en_set();
Delay1KTCYx(5); // delay 5ms
}
void InitUART(void)
{
TXSTAbits.TX9=0;
TXSTAbits.TXEN=1;
TXSTAbits.SYNC=0;
TXSTAbits.BRGH=1;
TXSTAbits.TX9D=0;
RCSTAbits.SPEN=1;
BAUDCONbits.BRG16=0;
SPBRG=25; // 9600KBaud
// receive config
RCSTAbits.RX9=0;
RCSTAbits.CREN=1;
RCSTAbits.RX9D=0;
}
void LCDInit(void)
{
Delay10KTCYx(20); //Delay 200ms
LATA=0;
LATC=0;
//Outputs
TRISAbits.TRISA7=0; //RS signal
TRISAbits.TRISA6=0; //EN signal
TRISCbits.TRISC0=0; // RC0 output, DB4
TRISCbits.TRISC1=0; // RC1 output, DB5
TRISCbits.TRISC2=0; // RC2 output, DB6
TRISCbits.TRISC3=0; // RC3 output, DB7
TRISCbits.TRISC5=0; // STATUS LED
TRISCbits.TRISC6=0; // UART_TX
//Inputs
TRISBbits.TRISB4=1; //data0
TRISBbits.TRISB3=1; //data1
TRISCbits.TRISC4=1; // button
TRISCbits.TRISC7=1; //UART_RX
// Oscillator frequency
OSCCON=0b01100111; // 4MHz
// pins configurred as digital
ADCON1=0b00001111;
// Interrupt config
INTCON=0x40; // PEIE high
IPR1bits.RCIP=1; // EUSART Receive Interrupt High Priority
RCONbits.IPEN=1; // enable priority levels
PIE1bits.RCIE=1; // Enable EUSART receive interrupt
LATAbits.LATA6=0; // Set En on 0
Delay1KTCYx(100); //Delay 100ms
LATAbits.LATA7=0; // Set RS on 0
Delay1KTCYx(15); //Delay 15ms
LATC=0x3;
en_set();
Delay1KTCYx(5); // delay 5ms
LATC=0x3;
en_set();
Delay100TCYx(1); // delay 100us
LATC=0x3;
en_set();
Delay10TCYx(4); // delay 40us
LATC=0x2;
en_set();
Delay10TCYx(4); // delay 40us
//Function set
cmd(0x28); // 4 bits, 2 lines, 5x7 dots format display mode
Delay10TCYx(4); // delay 40us
//Display ON control
cmd(0x0E); // display on, cursor on, blinking cursor position off
Delay10TCYx(4); // delay 40us
//Clear Display
cmd(0x01); // dispaly clear
Delay1KTCYx(2); // delay 2ms
//Entry set increment
cmd(0x06); // increment, shift right
Delay100TCYx(10); // delay 1ms
}
void putch(unsigned char byte)
{
while(!TXSTAbits.TRMT);
TXREG=byte;
}
void send_dec_lcd(unsigned long data,unsigned char num_dig) //convert binary number and display number in decimal
{
if(num_dig>=10)
{
data=data%10000000000;
send_char(data/1000000000+0x30);
txarray[i]=data/1000000000+0x30;
i++;
}
if(num_dig>=9)
{
data=data%1000000000;
send_char(data/100000000+0x30);
txarray[i]=data/100000000+0x30;
i++;
}
if(num_dig>=8)
{
data=data%100000000;
send_char(data/10000000+0x30);
txarray[i]=data/10000000+0x30;
i++;
}
if(num_dig>=7)
{
data=data%10000000;
send_char(data/1000000+0x30);
txarray[i]=data/1000000+0x30;
i++;
}
if(num_dig>=6)
{
data=data%1000000;
send_char(data/100000+0x30);
txarray[i]=data/100000+0x30;
i++;
}
if(num_dig>=5)
{
data=data%100000;
send_char(data/10000+0x30);
txarray[i]=data/10000+0x30;
i++;
}
if(num_dig>=4)
{
data=data%10000;
send_char(data/1000+0x30);
txarray[i]=data/1000+0x30;
i++;
}
if(num_dig>=3)
{
data=data%1000;
send_char(data/100+0x30);
txarray[i]=data/100+0x30;
i++;
}
if(num_dig>=2)
{
data=data%100;
send_char(data/10+0x30);
txarray[i]=data/10+0x30;
i++;
}
if(num_dig>=1)
{
data=data%10;
send_char(data+0x30);
txarray[i]=data+0x30;
i++;
}
}
void send_dec_usart(void) //convert binary number and display number in decimal
{
txarray[8]='\r';
q=0;
while(q<=8)
{
putch(txarray[q]);
q++;
}
}
void lcd_goto(unsigned char data) //set the location of the lcd cursor
{
if(data<16) //if the given value is (0-15) the
{ //cursor will be at the upper line
cmd(0x80+data);
}
else //if the given value is (20-35) the
{ //cursor will be at the lower line
data=data-20; //location of the lcd cursor(2X16):
cmd(0xC0+data); // -----------------------------------------------------
} // | |00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15| |
} // | |20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35| |
// -----------------------------------------------------
void lcd_string(const char *s)
{
while(*s)
{
// Delay1KTCYx(10); //Delay 10ms
send_char(*s++);
}
}
void writeString(const char *s)
{
while(*s)
{
while(!TXSTAbits.TRMT);
TXREG=*s;
s++;
}
}
/********************************************************************/
/* Read the string from the USART interface */
/********************************************************************/
void interrupt(void)
{
if(PIR1bits.RCIF)
{
if(RCSTAbits.FERR==1)
{
rxchar=RCREG;
RCSTAbits.CREN=0;
RCSTAbits.CREN=1;
}
if(RCSTAbits.OERR==1)
{
rxchar=RCREG;
RCSTAbits.CREN=0;
RCSTAbits.CREN=1;
}
rxchar=RCREG;
rxarray[r]=rxchar;
r++;
if(rxchar=='\r') // if the character is Enter flag is put on 1
{
flag=1;
}
}
PIR1bits.RCIF=0;
}
///////////////////functia main///////////////////////////////////////////
void main()
{
unsigned char i,repeat,a,b,database;
unsigned char data[26];
unsigned char convert1=0;
unsigned int convert2=0;
unsigned mode=0;
unsigned char id1[2]={127,0};
unsigned int id2[2]={22449,0};
//Initializations
PORTC=0x00;
LCDInit();
InitUART();
id1[1]=0;
id2[1]=0;
i=0;
database=0;
check=0;
jump:;
convert1=0; // clear convert1
convert2=0; // clear convert2
cmd(0x01); // clear lcd
lcd_goto(0); // 1st row, set cursor at location 0
lcd_string(string);
lcd_goto(20); // 2nd row
lcd_string(string1); // "on the reader"
while(mode==0) // no RFID tag is placed on RFID reader
{
if((data0==0)||(data1==0)) mode=1; // RFID tag is placed on the reader (receive data stream from RFID tag)
else if (btn1==0) mode=2; // push button is pressed, enter to save mode
}
// RFID tag is placed on the reader (RFID reader receive data stream from RFID tag)
while(mode==1)
{
if((data0==0)&&(data1==1)) // if data0 changes(data0 active low)
{
data[i]=0; // save the bit received as 0
while((data0==0)&&(data1==1)); // wait until data0 changes to high logic
}
else if((data0==1)&&(data1==0)) // if data1 changes(data1 active low)
{
data[i]=1; // save the bit received as 1
while((data0==1)&&(data1==0)); // wait until data1 changes to high logic
}
i++;
while(i<26) // repeat the loop until all 26 bit data are sent(start from 0 to 25)
{
while((data0==1)&&(data1==1)); // wait for data
if((data0==0)&&(data1==1))
{
data[i]=0; // save the bit received as 0
while((data0==0)&&(data1==1)); // wait until data0 changes to high logic
}
else if((data0==1)&&(data1==0)) // if data1 changes(data1 active low)
{
data[i]=1; // save the bit received as 1
while((data0==1)&&(data1==0)); // wait until data1 changes to high logic
}
i++;
}
mode=0; // after all data are sent, reset as no RFID tag is placed on RFID reader
i=0; // clear i
cmd(0x01); // lcd clear
for(i=0; i<8; i++) // loop for data[0]-data[7]
{
convert1=(convert1<<1) | data[i+1]; // shift current data and combine with previous datra, store in convert1
}
for(i=0; i<16; i++) // loop for data[8]-data[25]
{
convert2=(convert2<<1) | data[i+9]; // shift current data and combine with previous datra, store in convert2
}
for(b=0; b<2; b++) // compare with id[0] and id[1]
{
if((convert1==id1[b])&&(convert2==id2[b])) database=1; // id match, set database to 1
}
cmd(0x01); // clear lcd
}
// push button is pressed, enter to save mode
while(mode==2)
{
cmd(0x01); // clear lcd
lcd_goto(0); // 1st row, set cursor to location 0
lcd_string(string2); // display "Save mode"
Delay1KTCYx(2);
lcd_goto(20); // 2nd row
lcd_string(string); // display " Place your tag"
while(i<26)
{
while((data0==1)&&(data1==1)); // wait for data
if((data0==0)&&(data1==1))
{
data[i]=0; // save the bit received as 0
while((data0==0)&&(data1==1)); // wait until data0 changes to high logic
}
else if((data0==1)&&(data1==0)) // if data1 changes(data1 active low)
{
data[i]=1; // save the bit received as 1
while((data0==1)&&(data1==0)); // wait until data1 changes to high logic
}
i++;
}
mode=0; // after all data are sent, reset as no RFID tag is placed on RFID reader
i=0; // clear i
cmd(0x01); // lcd clear
for(i=0; i<8; i++) // loop for data[0]-data[7]
{
convert1=(convert1<<1) | data[i+1]; // shift current data and combine with previous datra, store in convert1
}
for(i=0; i<16; i++) // loop for data[8]-data[25]
{
convert2=(convert2<<1) | data[i+9]; // shift current data and combine with previous datra, store in convert2
}
id1[1]=convert1;
id2[1]=convert2;
database=2; // display id no. and "User ID saved"
cmd(0x01); // clear lcd
}
switch(database)
{
case 1: // id1 match
PORTCbits.RC5=0; // STATUS LED OFF
lcd_goto(0); // 1st row, set cursor to location 0
lcd_string(string3); // display "Id no:"
lcd_goto(7); // 1st row, set cursor to location 7
send_dec_lcd(convert1,3); // display convert1 in 3 decimal number
lcd_goto(10); // 1st row, set cursor to location 10
send_dec_lcd(convert2,5); // display convert2 in 5 decimal number
send_dec_usart();
lcd_goto(20); // 2nd row, set cursor to location 20
lcd_string(string4); // display "User identified"
Delay10KTCYx(100); // delay 1s
break;
case 2: // save id
lcd_goto(0); // 1st row, set cursor to location 0
lcd_string(string3); // display "Id no:"
lcd_goto(7); // 1st row, set cursor to location 7
send_dec_lcd(convert1,3); // display convert1 in 3 decimal number
lcd_goto(10); // 1st row, set cursor to location 10
send_dec_lcd(convert2,5); // display convert2 in 5 decimal number
lcd_goto(20); // 2nd row, set cursor to location 20
lcd_string(string5); // display "User ID saved"
Delay10KTCYx(100); // delay 1s
goto jump;
break;
default: // id doesn't match
PORTCbits.RC5=1; // STATUS LED ON
lcd_goto(0); // 1st row, set cursor to location 0
lcd_string(string3); // display "Id no:"
lcd_goto(7); // 1st row, set cursor to location 7
send_dec_lcd(convert1,3); // display convert1 in 3 decimal number
lcd_goto(10); // 1st row, set cursor to location 10
send_dec_lcd(convert2,5); // display convert2 in 5 decimal number
lcd_goto(20); // 2nd row, set cursor to location 20
lcd_string(string6); // display "User not found"
Delay10KTCYx(100); // delay 1s
goto jump;
break;
}
Delay10KTCYx(100); // delay 1s
i=0;
database=0;
convert1=0;
convert2=0;
check=0;
while(1)
{
if(flag==1)
{
flag=0;
r=0;
}
if(check==1)
{
if(strncmppgm2ram(rxarray,"ok",2)==0)
{
cmd(0x01); // clear the display
lcd_goto(0); // 1st row, set cursor to location 0
for(i=0;i<2;i++)
{
send_char(rxarray[i]);
Delay10TCYx(5);
}
}
else
{
if (strncmppgm2ram(rxarray,"previous box",12)==0)
{
cmd(0x01); // clear the display
lcd_goto(0); // 1st row, set cursor to location 0
for(i=0;i<12;i++)
{
send_char(rxarray[i]);
Delay10TCYx(5);
}
}
}
check=0;
}
}// while(1)
}//main
Thank you in advance.
Last edited by a moderator: