PIC Development Board with PK3

JohnInTX

Joined Jun 26, 2012
4,787
Are you using the PK3 as a debugger or just a programmer? Because if you use it as a debugger, you can set breakpoints and step the code to see where this is happening.
 
Last edited:

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
Are you using the PK3 as a debugger or just a programmer? Because if you use it as a debugger, you can set breakpoints and step the code to see where this is happening.
What's this warning

warning: incompatible integer to pointer conversion passing 'char' to parameter of type 'char *'; take the address with & [-Wint-conversion]
String(Receive);
^~~~~~~
I want to implement receive function whatever i type in terminal i should get back

I'll try to debug below code

C:
#define _XTAL_FREQ 8000000
// Configuration bits: selected in the GUI
// CONFIG1L
#pragma config RETEN = OFF    // VREG Sleep Enable bit->Ultra low-power regulator is Disabled (Controlled by REGSLP bit)
#pragma config INTOSCSEL = HIGH    // LF-INTOSC Low-power Enable bit->LF-INTOSC in High-power mode during Sleep
#pragma config SOSCSEL = DIG    // SOSC Power Selection and mode Configuration bits->Digital (SCLKI) mode
#pragma config XINST = OFF    // Extended Instruction Set->Disabled
// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator->Internal RC oscillator
#pragma config PLLCFG = OFF    // PLL x4 Enable bit->Disabled
#pragma config FCMEN = OFF    // Fail-Safe Clock Monitor->Disabled
#pragma config IESO = OFF    // Internal External Oscillator Switch Over Mode->Disabled
// CONFIG2L
#pragma config PWRTEN = OFF    // Power Up Timer->Disabled
#pragma config BOREN = SBORDIS    // Brown Out Detect->Enabled in hardware, SBOREN disabled
#pragma config BORV = 3    // Brown-out Reset Voltage bits->1.8V
#pragma config BORPWR = ZPBORMV    // BORMV Power level->ZPBORMV instead of BORMV is selected
// CONFIG2H
#pragma config WDTEN = OFF    // Watchdog Timer->WDT disabled in hardware; SWDTEN bit disabled
#pragma config WDTPS = 1048576    // Watchdog Postscaler->1:1048576
// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit->ECAN TX and RX pins are located on RB2 and RB3, respectively
#pragma config MSSPMSK = MSK7    // MSSP address masking->7 Bit address masking mode
#pragma config MCLRE = ON    // Master Clear Enable->MCLR Enabled, RE3 Disabled
// CONFIG4L
#pragma config STVREN = ON    // Stack Overflow Reset->Enabled
#pragma config BBSIZ = BB2K    // Boot Block Size->2K word Boot Block size
// CONFIG5L
#pragma config CP0 = OFF    // Code Protect 00800-01FFF->Disabled
#pragma config CP1 = OFF    // Code Protect 02000-03FFF->Disabled
#pragma config CP2 = OFF    // Code Protect 04000-05FFF->Disabled
#pragma config CP3 = OFF    // Code Protect 06000-07FFF->Disabled
// CONFIG5H
#pragma config CPB = OFF    // Code Protect Boot->Disabled
#pragma config CPD = OFF    // Data EE Read Protect->Disabled
// CONFIG6L
#pragma config WRT0 = OFF    // Table Write Protect 00800-01FFF->Disabled
#pragma config WRT1 = OFF    // Table Write Protect 02000-03FFF->Disabled
#pragma config WRT2 = OFF    // Table Write Protect 04000-05FFF->Disabled
#pragma config WRT3 = OFF    // Table Write Protect 06000-07FFF->Disabled
// CONFIG6H
#pragma config WRTC = OFF    // Config. Write Protect->Disabled
#pragma config WRTB = OFF    // Table Write Protect Boot->Disabled
#pragma config WRTD = OFF    // Data EE Write Protect->Disabled
// CONFIG7L
#pragma config EBTR0 = OFF    // Table Read Protect 00800-01FFF->Disabled
#pragma config EBTR1 = OFF    // Table Read Protect 02000-03FFF->Disabled
#pragma config EBTR2 = OFF    // Table Read Protect 04000-05FFF->Disabled
#pragma config EBTR3 = OFF    // Table Read Protect 06000-07FFF->Disabled
// CONFIG7H
#pragma config EBTRB = OFF    // Table Read Protect Boot->Disabled

#include <xc.h>

#define BUTTON    PORTBbits.RB0

void PIN_MANAGER_Initialize(void)
{
    /**
    LATx registers
    */
    LATE = 0x00;
    LATD = 0x00;
    LATA = 0x00;
    LATB = 0x00;
    LATC = 0x00;
    /**
    TRISx registers
    */
    TRISE = 0x07;
    TRISA = 0xEF;
    TRISB = 0x01;
    TRISC = 0xBF;
    TRISD = 0xFF;
    /**
    ANSELx registers
    */
    ANCON0 = 0x00;
    ANCON1 = 0x00;

    CM1CON = 0; // Comparator off
    CM2CON = 0; // Comparator off
    ADCON0 = 0; // A/D conversion Disabled
}

void OSCILLATOR_Initialize(void)
{
    // SCS FOSC; HFIOFS not stable; IDLEN disabled; IRCF 8MHz_HF;
    OSCCON = 0x60;
    // SOSCGO disabled; MFIOSEL disabled; SOSCDRV Low Power;
    OSCCON2 = 0x00;
    // INTSRC INTRC; PLLEN disabled; TUN 0;
    OSCTUNE = 0x00;
    // ROSEL System Clock(FOSC); ROON disabled; ROSSLP Disabled in Sleep mode; RODIV Fosc;
    REFOCON = 0x00;
}
void EUSART1_Initialize(void)
{
    // Set the EUSART1 module to the options selected in the user interface.
    // ABDOVF no_overflow; TXCKP async_noninverted_sync_fallingedge; BRG16 16bit_generator; WUE disabled; ABDEN disabled; RXDTP not_inverted;
    BAUDCON1 = 0x08;
    // SPEN enabled; RX9 8-bit; RX9D 0; CREN enabled; ADDEN disabled; SREN disabled;
    RCSTA1 = 0x90;
    // TX9 8-bit; TX9D 0; SENDB sync_break_complete; TXEN enabled; SYNC asynchronous; BRGH hi_speed; CSRC slave_mode;
    TXSTA1 = 0x24;
    //
    SPBRG1 = 0xCF;
    //
    SPBRGH1 = 0x00;

}

void SYSTEM_Initialize(void)
{
    PIN_MANAGER_Initialize();
    OSCILLATOR_Initialize();
    EUSART1_Initialize();
}

char Receive_Byte(void)
{
    while(RC1IF == 0 );               // Wait till the rx register becomes empty
    return RCREG1;
}

void Send_Byte(char message)
{
    while(TXIF == 0 );  // Wait till the transmitter register becomes empty
    TXREG1 = message;
}

void String(char *p)
{
   while(*p != '\0') {
       __delay_ms(1);
     Send_Byte(*p);
     p++;
   }
}
void main(void)
{
    char Receive ;
    char message[]= {"Hello"};
    SYSTEM_Initialize();
    __delay_ms(10);
    String(message);

    while (1)
    {
        if(RC1IF == 1)
        {
           Receive =  Receive_Byte(); // receive  byte
     
           RC1IF = 0; // Clear Flag
     
           String(Receive);  // send byte
        }
       
    }

    return;
}
 
Last edited:

trebla

Joined Jun 29, 2019
599
What's this warning
The Send() function requires a pointer as argument, so you can't put integer value there. You can put addres of this byte to Send() function argument:

String(&Receive); //but this function checks string ending zero

so better is use the Send_Byte() function for sending one byte back:

Send_Byte(Receive);

Try to read and understand what is written in your code ;)
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
Send_Byte(Receive);
Try to read and understand what is written in your code ;)
code stuck at line 150 What's wrong in line 150


1622701772237.png


C:
#define _XTAL_FREQ 8000000
// Configuration bits: selected in the GUI
// CONFIG1L
#pragma config RETEN = OFF    // VREG Sleep Enable bit->Ultra low-power regulator is Disabled (Controlled by REGSLP bit)
#pragma config INTOSCSEL = HIGH    // LF-INTOSC Low-power Enable bit->LF-INTOSC in High-power mode during Sleep
#pragma config SOSCSEL = DIG    // SOSC Power Selection and mode Configuration bits->Digital (SCLKI) mode
#pragma config XINST = OFF    // Extended Instruction Set->Disabled
// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator->Internal RC oscillator
#pragma config PLLCFG = OFF    // PLL x4 Enable bit->Disabled
#pragma config FCMEN = OFF    // Fail-Safe Clock Monitor->Disabled
#pragma config IESO = OFF    // Internal External Oscillator Switch Over Mode->Disabled
// CONFIG2L
#pragma config PWRTEN = OFF    // Power Up Timer->Disabled
#pragma config BOREN = SBORDIS    // Brown Out Detect->Enabled in hardware, SBOREN disabled
#pragma config BORV = 3    // Brown-out Reset Voltage bits->1.8V
#pragma config BORPWR = ZPBORMV    // BORMV Power level->ZPBORMV instead of BORMV is selected
// CONFIG2H
#pragma config WDTEN = OFF    // Watchdog Timer->WDT disabled in hardware; SWDTEN bit disabled
#pragma config WDTPS = 1048576    // Watchdog Postscaler->1:1048576
// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit->ECAN TX and RX pins are located on RB2 and RB3, respectively
#pragma config MSSPMSK = MSK7    // MSSP address masking->7 Bit address masking mode
#pragma config MCLRE = ON    // Master Clear Enable->MCLR Enabled, RE3 Disabled
// CONFIG4L
#pragma config STVREN = ON    // Stack Overflow Reset->Enabled
#pragma config BBSIZ = BB2K    // Boot Block Size->2K word Boot Block size
// CONFIG5L
#pragma config CP0 = OFF    // Code Protect 00800-01FFF->Disabled
#pragma config CP1 = OFF    // Code Protect 02000-03FFF->Disabled
#pragma config CP2 = OFF    // Code Protect 04000-05FFF->Disabled
#pragma config CP3 = OFF    // Code Protect 06000-07FFF->Disabled
// CONFIG5H
#pragma config CPB = OFF    // Code Protect Boot->Disabled
#pragma config CPD = OFF    // Data EE Read Protect->Disabled
// CONFIG6L
#pragma config WRT0 = OFF    // Table Write Protect 00800-01FFF->Disabled
#pragma config WRT1 = OFF    // Table Write Protect 02000-03FFF->Disabled
#pragma config WRT2 = OFF    // Table Write Protect 04000-05FFF->Disabled
#pragma config WRT3 = OFF    // Table Write Protect 06000-07FFF->Disabled
// CONFIG6H
#pragma config WRTC = OFF    // Config. Write Protect->Disabled
#pragma config WRTB = OFF    // Table Write Protect Boot->Disabled
#pragma config WRTD = OFF    // Data EE Write Protect->Disabled
// CONFIG7L
#pragma config EBTR0 = OFF    // Table Read Protect 00800-01FFF->Disabled
#pragma config EBTR1 = OFF    // Table Read Protect 02000-03FFF->Disabled
#pragma config EBTR2 = OFF    // Table Read Protect 04000-05FFF->Disabled
#pragma config EBTR3 = OFF    // Table Read Protect 06000-07FFF->Disabled
// CONFIG7H
#pragma config EBTRB = OFF    // Table Read Protect Boot->Disabled

#include <xc.h>

#define BUTTON    PORTBbits.RB0

void PIN_MANAGER_Initialize(void)
{
    /**
    LATx registers
    */
    LATE = 0x00;
    LATD = 0x00;
    LATA = 0x00;
    LATB = 0x00;
    LATC = 0x00;
    /**
    TRISx registers
    */
    TRISE = 0x07;
    TRISA = 0xEF;
    TRISB = 0x01;
    TRISC = 0xBF;
    TRISD = 0xFF;
    /**
    ANSELx registers
    */
    ANCON0 = 0x00;
    ANCON1 = 0x00;

    CM1CON = 0; // Comparator off
    CM2CON = 0; // Comparator off
    ADCON0 = 0; // A/D conversion Disabled
}

void OSCILLATOR_Initialize(void)
{
    // SCS FOSC; HFIOFS not stable; IDLEN disabled; IRCF 8MHz_HF;
    OSCCON = 0x60;
    // SOSCGO disabled; MFIOSEL disabled; SOSCDRV Low Power;
    OSCCON2 = 0x00;
    // INTSRC INTRC; PLLEN disabled; TUN 0;
    OSCTUNE = 0x00;
    // ROSEL System Clock(FOSC); ROON disabled; ROSSLP Disabled in Sleep mode; RODIV Fosc;
    REFOCON = 0x00;
}
void EUSART1_Initialize(void)
{
    // Set the EUSART1 module to the options selected in the user interface.
    // ABDOVF no_overflow; TXCKP async_noninverted_sync_fallingedge; BRG16 16bit_generator; WUE disabled; ABDEN disabled; RXDTP not_inverted;
    BAUDCON1 = 0x08;
    // SPEN enabled; RX9 8-bit; RX9D 0; CREN enabled; ADDEN disabled; SREN disabled;
    RCSTA1 = 0x90;
    // TX9 8-bit; TX9D 0; SENDB sync_break_complete; TXEN enabled; SYNC asynchronous; BRGH hi_speed; CSRC slave_mode;
    TXSTA1 = 0x24;
    //
    SPBRG1 = 0xCF;
    //
    SPBRGH1 = 0x00;

}

void SYSTEM_Initialize(void)
{
    PIN_MANAGER_Initialize();
    OSCILLATOR_Initialize();
    EUSART1_Initialize();
}

char Receive_Byte(void)
{
    while(RC1IF == 0 );               // Wait till the rx register becomes empty
    return RCREG1;
}

void Send_Byte(char message)
{
    while(TXIF == 0 );  // Wait till the transmitter register becomes empty
    TXREG1 = message;
}

void String(char *p)
{
   while(*p != '\0') {
       __delay_ms(1);
     Send_Byte(*p);
     p++;
   }
}
void main(void)
{
    char Receive ;
    char message[]= {"Hello"};
    SYSTEM_Initialize();
    __delay_ms(10);
    String(message);

    while (1)
    {
        if(RC1IF == 1)
        {
           Receive =  Receive_Byte(); // receive  byte
         
           RC1IF = 0; // Clear Flag
         
           Send_Byte(Receive);  // send byte
        }
           
    }

    return;
}
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
code stuck at line 150 What's wrong in line 150
It is waiting for a character to be received from the terminal.

You should be checking the error flags, especially OERR, to make sure that the USART has not shut down because of an overrun error i.e. the terminal sent a character before you read the previous one. That is a very common problem in a polled program. Once OERR is set, the USART will not generate any more RC1IF flags until OERR is cleared by toggling the CREN bit.

The little light bulb at line 154 is an advisory. Hover your mouse over it for information about it. In this case, the editor is telling you that RC1IF is not a valid name. But in this case, the message is wrong, RC1IF is valid and it compiles without error. That happens and it may clear up after a successful build. Same problem on line 128. The confusion happens as a result of uCHIP trying to maintain compatibility across chips with 1 USART and 2 USARTS. TXIF, RCIF are legacy identifiers for chips with 1 USART. Chips using 2 USARTS have to number them i.e. TX1IF, RC1IF, TX2IF, RC2IF etc. To help maintain code compatibility, TXIF is frequently equated with TX1IF since the reference the same register and bit on either 1 or 2 USART PICs. Sometimes it takes the editor awhile to sort it out.

If it compiles and links with no errors, you should be good to go but you should select one naming convention and stick with it.
 
Last edited:

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
It is waiting for a character to be received from the terminal.

You should be checking the error flags, especially OERR, to make sure that the USART has not shut down because of an overrun error i.e. the terminal sent a character before you read the previous one. That is a very common problem in a polled program. Once OERR is set, the USART will not generate any more RC1IF flags until OERR is cleared by toggling the CREN bit.
This is my attempt so I get "Hello" and when I type "A" I don't get back "A" on hyper terminal

1622735629961.png

C:
#define _XTAL_FREQ 8000000

// Configuration bits: selected in the GUI
// CONFIG1L
#pragma config RETEN = OFF    // VREG Sleep Enable bit->Ultra low-power regulator is Disabled (Controlled by REGSLP bit)
#pragma config INTOSCSEL = HIGH    // LF-INTOSC Low-power Enable bit->LF-INTOSC in High-power mode during Sleep
#pragma config SOSCSEL = DIG    // SOSC Power Selection and mode Configuration bits->Digital (SCLKI) mode
#pragma config XINST = OFF    // Extended Instruction Set->Disabled
// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator->Internal RC oscillator
#pragma config PLLCFG = OFF    // PLL x4 Enable bit->Disabled
#pragma config FCMEN = OFF    // Fail-Safe Clock Monitor->Disabled
#pragma config IESO = OFF    // Internal External Oscillator Switch Over Mode->Disabled
// CONFIG2L
#pragma config PWRTEN = OFF    // Power Up Timer->Disabled
#pragma config BOREN = SBORDIS    // Brown Out Detect->Enabled in hardware, SBOREN disabled
#pragma config BORV = 3    // Brown-out Reset Voltage bits->1.8V
#pragma config BORPWR = ZPBORMV    // BORMV Power level->ZPBORMV instead of BORMV is selected
// CONFIG2H
#pragma config WDTEN = OFF    // Watchdog Timer->WDT disabled in hardware; SWDTEN bit disabled
#pragma config WDTPS = 1048576    // Watchdog Postscaler->1:1048576
// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit->ECAN TX and RX pins are located on RB2 and RB3, respectively
#pragma config MSSPMSK = MSK7    // MSSP address masking->7 Bit address masking mode
#pragma config MCLRE = ON    // Master Clear Enable->MCLR Enabled, RE3 Disabled
// CONFIG4L
#pragma config STVREN = ON    // Stack Overflow Reset->Enabled
#pragma config BBSIZ = BB2K    // Boot Block Size->2K word Boot Block size
// CONFIG5L
#pragma config CP0 = OFF    // Code Protect 00800-01FFF->Disabled
#pragma config CP1 = OFF    // Code Protect 02000-03FFF->Disabled
#pragma config CP2 = OFF    // Code Protect 04000-05FFF->Disabled
#pragma config CP3 = OFF    // Code Protect 06000-07FFF->Disabled
// CONFIG5H
#pragma config CPB = OFF    // Code Protect Boot->Disabled
#pragma config CPD = OFF    // Data EE Read Protect->Disabled
// CONFIG6L
#pragma config WRT0 = OFF    // Table Write Protect 00800-01FFF->Disabled
#pragma config WRT1 = OFF    // Table Write Protect 02000-03FFF->Disabled
#pragma config WRT2 = OFF    // Table Write Protect 04000-05FFF->Disabled
#pragma config WRT3 = OFF    // Table Write Protect 06000-07FFF->Disabled
// CONFIG6H
#pragma config WRTC = OFF    // Config. Write Protect->Disabled
#pragma config WRTB = OFF    // Table Write Protect Boot->Disabled
#pragma config WRTD = OFF    // Data EE Write Protect->Disabled
// CONFIG7L
#pragma config EBTR0 = OFF    // Table Read Protect 00800-01FFF->Disabled
#pragma config EBTR1 = OFF    // Table Read Protect 02000-03FFF->Disabled
#pragma config EBTR2 = OFF    // Table Read Protect 04000-05FFF->Disabled
#pragma config EBTR3 = OFF    // Table Read Protect 06000-07FFF->Disabled
// CONFIG7H
#pragma config EBTRB = OFF    // Table Read Protect Boot->Disabled

#include <xc.h>

void PIN_MANAGER_Initialize(void)
{
    /**
    LATx registers
    */
    LATE = 0x00;
    LATD = 0x00;
    LATA = 0x00;
    LATB = 0x00;
    LATC = 0x00;
    /**
    TRISx registers
    */
    TRISE = 0x07;
    TRISA = 0xEF;
    TRISB = 0x01;
    TRISC = 0xBF;
    TRISD = 0xFF;
    /**
    ANSELx registers
    */
    ANCON0 = 0x00;
    ANCON1 = 0x00;

    CM1CON = 0; // Comparator off
    CM2CON = 0; // Comparator off
    ADCON0 = 0; // A/D conversion Disabled
}

void OSCILLATOR_Initialize(void)
{
    // SCS FOSC; HFIOFS not stable; IDLEN disabled; IRCF 8MHz_HF;
    OSCCON = 0x60;
    // SOSCGO disabled; MFIOSEL disabled; SOSCDRV Low Power;
    OSCCON2 = 0x00;
    // INTSRC INTRC; PLLEN disabled; TUN 0;
    OSCTUNE = 0x00;
    // ROSEL System Clock(FOSC); ROON disabled; ROSSLP Disabled in Sleep mode; RODIV Fosc;
    REFOCON = 0x00;
}
void EUSART1_Initialize(void)
{
    // Set the EUSART1 module to the options selected in the user interface.
    // ABDOVF no_overflow; TXCKP async_noninverted_sync_fallingedge; BRG16 16bit_generator; WUE disabled; ABDEN disabled; RXDTP not_inverted;
    BAUDCON1 = 0x08;
    // SPEN enabled; RX9 8-bit; RX9D 0; CREN enabled; ADDEN disabled; SREN disabled;
    RCSTA1 = 0x90;
    // TX9 8-bit; TX9D 0; SENDB sync_break_complete; TXEN enabled; SYNC asynchronous; BRGH hi_speed; CSRC slave_mode;
    TXSTA1 = 0x24;
    //
    SPBRG1 = 0xCF;
    //
    SPBRGH1 = 0x00;

}

void SYSTEM_Initialize(void)
{
    PIN_MANAGER_Initialize();
    OSCILLATOR_Initialize();
    EUSART1_Initialize();
}

//Receive Byte
char Receive_Byte(void)
{
    if(RCSTAbits.OERR == 1)
    {
       RCSTAbits.CREN = 0;
       NOP();
       RCSTAbits.CREN = 1;
    }
    while(RCIF == 0 );               // Wait till the rx register becomes empty
   
    return RCREG;
}

//Send a byte
void Send_Byte(char message)
{
    while(TXIF == 0 );               // Wait till the transmitter register becomes empty
    TXREG1 = message;
}

void String(char *p)
{
   while(*p != '\0') {
       __delay_ms(1);
     Send_Byte(*p);
     p++;
   }
}

void main(void)
{
    char Receive ;
    char message[]= {"Hello"};
   
    SYSTEM_Initialize();
   
    __delay_ms(10);  // Wait for 10 ms
   
    String(message); // Send one byte to hyper terminal
 
    while (1)
    {
      Receive = Receive_Byte(); //  Receive a byte from hyper terminal
      Send_Byte(Receive);       // send received byte back to hyper terminal          
    }

    return;
}
 

JohnInTX

Joined Jun 26, 2012
4,787
Make sure the terminal is set for FULL DUPLEX so that it only shows characters it actually receives (not the ones you type). To be sure, disconnect the terminal and hit a few keys. You should get NO characters on the screen if you are in full duplex. Poke around in the options if you have to to get this right.
Set a breakpoint at line 163 and see if it gets there.
With the terminal connected put your meter on the RX pin. It should be 5V or so. Then hit a few keys. The voltage will fluctuate if you are getting signal to the RX pin.
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
@hexreader I've attached hyper terminal application that I'm using for serial communication. Can you check the code with this hyper terminal ?

if you can do this please share the screenshot
 

Attachments

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
That is the worst terminal software I have ever tried.

Complete garbage. - Worse than useless.

No wonder you are having trouble!
Thank you hex

can you share the link of hyper terminal which you have for serial communication?

I had one free version of Hyper terminal but its trial period is over now

obviously there are many available on online But I would like to work with what you have now
 

JohnInTX

Joined Jun 26, 2012
4,787
I don't know if this is your problem but after looking at the board photos I see that:

The square PIN 1 on the DB9 footprint is actually pin 5. The board is wired OK from there.
The RX and TX labels on CN3 are wrong with respect to the PIC RX and TX lines. They actually refer to the PC direction i.e. TX means data transmitted from the PC. That pin should be connected to the RX pin on the PIC.

Note that CN3 forms a WRAP PLUG i.e. it connects the PC TX and RX lines together. With CN3 installed and the PIC disconnected, you can test the serial link from the PC through the MAX 232 - whatever you type should come right back, even with the PIC disconnected.

When that is working REMOVE the jumper at CN3 and connect CN3-RX to the PIC TX and CN3-TX to the PIC RX.

The attached PDF shows the correct hookup - at least how I read things.

All of this assumes that you are using a normal hookup (PC end has male pins) with no gender benders or null modem plugs. To be sure, pull the MAX232 from its socket and measure the voltage on pin 3 (center pin of the longer row) of the DB9-F and pin 13 of the MAX232 socket. Both should be some negative voltage e.g. -5V to -15V indicating that the PC is transmitting RS232 levels on that pin. Hit a few keys. The voltage should move around a bit while the data is being transmitted.
Pin 2 of the DB9 should float around a bit indicating you are on the PC's RX input. Reinstall the MAX232 and proceed.

Good luck!
 

Attachments

Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
Note also that you cannot have the CN3 jumper installed and the PIC USART pins connected at the same time. That would cause some output contention between the PIC and MAX232.
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
@JohnInTX one problem has been fixed. There was the problem with the hyper terminal application. I've installed latest version tera term

as @hexreader claim in post #220 for two way communication. My program in post #249 get exact result if I add one line Receive++;

when I type 'a' I see a 'b' returned and when I type "hello" it show "ifmmp"

complete code
C:
#define _XTAL_FREQ 8000000

// Configuration bits: selected in the GUI
// CONFIG1L
#pragma config RETEN = OFF    // VREG Sleep Enable bit->Ultra low-power regulator is Disabled (Controlled by REGSLP bit)
#pragma config INTOSCSEL = HIGH    // LF-INTOSC Low-power Enable bit->LF-INTOSC in High-power mode during Sleep
#pragma config SOSCSEL = DIG    // SOSC Power Selection and mode Configuration bits->Digital (SCLKI) mode
#pragma config XINST = OFF    // Extended Instruction Set->Disabled
// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator->Internal RC oscillator
#pragma config PLLCFG = OFF    // PLL x4 Enable bit->Disabled
#pragma config FCMEN = OFF    // Fail-Safe Clock Monitor->Disabled
#pragma config IESO = OFF    // Internal External Oscillator Switch Over Mode->Disabled
// CONFIG2L
#pragma config PWRTEN = OFF    // Power Up Timer->Disabled
#pragma config BOREN = SBORDIS    // Brown Out Detect->Enabled in hardware, SBOREN disabled
#pragma config BORV = 3    // Brown-out Reset Voltage bits->1.8V
#pragma config BORPWR = ZPBORMV    // BORMV Power level->ZPBORMV instead of BORMV is selected
// CONFIG2H
#pragma config WDTEN = OFF    // Watchdog Timer->WDT disabled in hardware; SWDTEN bit disabled
#pragma config WDTPS = 1048576    // Watchdog Postscaler->1:1048576
// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit->ECAN TX and RX pins are located on RB2 and RB3, respectively
#pragma config MSSPMSK = MSK7    // MSSP address masking->7 Bit address masking mode
#pragma config MCLRE = ON    // Master Clear Enable->MCLR Enabled, RE3 Disabled
// CONFIG4L
#pragma config STVREN = ON    // Stack Overflow Reset->Enabled
#pragma config BBSIZ = BB2K    // Boot Block Size->2K word Boot Block size
// CONFIG5L
#pragma config CP0 = OFF    // Code Protect 00800-01FFF->Disabled
#pragma config CP1 = OFF    // Code Protect 02000-03FFF->Disabled
#pragma config CP2 = OFF    // Code Protect 04000-05FFF->Disabled
#pragma config CP3 = OFF    // Code Protect 06000-07FFF->Disabled
// CONFIG5H
#pragma config CPB = OFF    // Code Protect Boot->Disabled
#pragma config CPD = OFF    // Data EE Read Protect->Disabled
// CONFIG6L
#pragma config WRT0 = OFF    // Table Write Protect 00800-01FFF->Disabled
#pragma config WRT1 = OFF    // Table Write Protect 02000-03FFF->Disabled
#pragma config WRT2 = OFF    // Table Write Protect 04000-05FFF->Disabled
#pragma config WRT3 = OFF    // Table Write Protect 06000-07FFF->Disabled
// CONFIG6H
#pragma config WRTC = OFF    // Config. Write Protect->Disabled
#pragma config WRTB = OFF    // Table Write Protect Boot->Disabled
#pragma config WRTD = OFF    // Data EE Write Protect->Disabled
// CONFIG7L
#pragma config EBTR0 = OFF    // Table Read Protect 00800-01FFF->Disabled
#pragma config EBTR1 = OFF    // Table Read Protect 02000-03FFF->Disabled
#pragma config EBTR2 = OFF    // Table Read Protect 04000-05FFF->Disabled
#pragma config EBTR3 = OFF    // Table Read Protect 06000-07FFF->Disabled
// CONFIG7H
#pragma config EBTRB = OFF    // Table Read Protect Boot->Disabled

#include <xc.h>

void PIN_MANAGER_Initialize(void)
{
    /**
    LATx registers
    */
    LATE = 0x00;
    LATD = 0x00;
    LATA = 0x00;
    LATB = 0x00;
    LATC = 0x00;
    /**
    TRISx registers
    */
    TRISE = 0x07;
    TRISA = 0xEF;
    TRISB = 0x01;
    TRISC = 0xBF;
    TRISD = 0xFF;
    /**
    ANSELx registers
    */
    ANCON0 = 0x00;
    ANCON1 = 0x00;

    CM1CON = 0; // Comparator off
    CM2CON = 0; // Comparator off
    ADCON0 = 0; // A/D conversion Disabled
}

void OSCILLATOR_Initialize(void)
{
    // SCS FOSC; HFIOFS not stable; IDLEN disabled; IRCF 8MHz_HF;
    OSCCON = 0x60;
    // SOSCGO disabled; MFIOSEL disabled; SOSCDRV Low Power;
    OSCCON2 = 0x00;
    // INTSRC INTRC; PLLEN disabled; TUN 0;
    OSCTUNE = 0x00;
    // ROSEL System Clock(FOSC); ROON disabled; ROSSLP Disabled in Sleep mode; RODIV Fosc;
    REFOCON = 0x00;
}
void EUSART1_Initialize(void)
{
    // Set the EUSART1 module to the options selected in the user interface.
    // ABDOVF no_overflow; TXCKP async_noninverted_sync_fallingedge; BRG16 16bit_generator; WUE disabled; ABDEN disabled; RXDTP not_inverted;
    BAUDCON1 = 0x08;
    // SPEN enabled; RX9 8-bit; RX9D 0; CREN enabled; ADDEN disabled; SREN disabled;
    RCSTA1 = 0x90;
    // TX9 8-bit; TX9D 0; SENDB sync_break_complete; TXEN enabled; SYNC asynchronous; BRGH hi_speed; CSRC slave_mode;
    TXSTA1 = 0x24;
    //
    SPBRG1 = 0xCF;
    //
    SPBRGH1 = 0x00;

}

void SYSTEM_Initialize(void)
{
    PIN_MANAGER_Initialize();
    OSCILLATOR_Initialize();
    EUSART1_Initialize();
}

//Receive Byte
char Receive_Byte(void)
{
    if(RCSTAbits.OERR == 1)
    {
       RCSTAbits.CREN = 0;
       NOP();
       RCSTAbits.CREN = 1;
    }
    while(RCIF == 0 );               // Wait till the rx register becomes empty
 
    return RCREG;
}

//Send a byte
void Send_Byte(char message)
{
    while(TXIF == 0 );               // Wait till the transmitter register becomes empty
    TXREG1 = message;
}

void String(char *p)
{
   while(*p != '\0') {
       __delay_ms(1);
     Send_Byte(*p);
     p++;
   }
}

void main(void)
{
    char Receive ;
    char message[]= {"Hello\n"};
 
    SYSTEM_Initialize();
 
    __delay_ms(10);  // Wait for 10 ms
 
    String(message); // Send one byte to hyper terminal

    while (1)
    {
      Receive = Receive_Byte(); //  Receive a byte from hyper terminal
      Receive++;
      Send_Byte(Receive);       // send received byte back to hyper terminal        
    }

    return;
}
Edit : If the two way communication is happening then what's the wrong in my code #249
 

hexreader

Joined Apr 16, 2011
619
Great stuff.
Serial is now working.

Time to try out a monitor program.
It looks complicated, and it is, but you can just accept that it works and just add your own new commands.

As a very simple example, you could add a new LED flash function called void cmdl(void)
1) add a prototype at the top void cmdl(void);
2) add a new test for letter 'L' by copy and paste check for 'E'. Change E to L and change cmde for cmdl
3) add an extra line of help text if you want - optional
4) write your own function void cmdl(void){ // your code here }
5) program and enjoy.

- or even simpler, just put code into the 'a' command that I created for you.

Hexadecimal input is automatically available for any new command, and hexadecimal output functions are available
I find a monitor program really helpful when developing, and sometimes as the basis for a final project.

EDIT 6 June: Minor improvements made to code below
Code:
// Important Note: some of the code below  is based on example code that is copyright of  mikroE

// original code is copyright Djsarkar - updated by amateur author who makes no claim to any copyright

// bad port of 1307 RTC and EEPROM test programs mixed in with other random code found on forum
//   - this has resulted in Frankenstein's Monster - I am not proud of the result :{
// messy and probably buggy code due to minimal effort made on port
// amateur code - use at your own risk - author accepts no responsibility for anything, anywhere, ever

//  Simple monitor program for PIC18F45K80 EasyPIC v7
//     - Put RX and TX UART switches Tx on RC6, Rx on RC7 (turn on SW1.1 and SW2.1)
//     - use terminal program on PC set to 9600,8,n,1
//     - turn on switches SW4.7 and SW4.8 to enable on-board EEPROM

//  SPECIAL NOTE:-  Code assumes EEPROM Write-Protect pin is connected to RC0, but not true of EasyPic 7 on-board EEPROM
//                  Ignore RC0 operation for on-board EEPROM - only EEPROM Click fitted to microBUS 1 socket uses WP

// status as of 6 June 2021....
//    - much tidying desperately needed
//    - otherwise - seems to work

// PIC18F45K80 Configuration Bit Settings

// CONFIG1L
#pragma config RETEN = ON       // VREG Sleep Enable bit (Ultra low-power regulator is Enabled (Controlled by SRETEN bit))
#pragma config INTOSCSEL = LOW  // LF-INTOSC Low-power Enable bit (LF-INTOSC in Low-power mode during Sleep)
#pragma config SOSCSEL = HIGH   // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF      // Extended Instruction Set (Disabled)

// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator (Internal RC oscillator)
#pragma config PLLCFG = OFF     // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF       // Internal External Oscillator Switch Over Mode (Disabled)

// CONFIG2L
#pragma config PWRTEN = ON      // Power Up Timer (Enabled)
#pragma config BOREN = OFF      // Brown Out Detect (Disabled in hardware, SBOREN disabled)
#pragma config BORV = 0         // Brown-out Reset Voltage bits (3.0V)
#pragma config BORPWR = LOW     // BORMV Power level (BORMV set to low power level)

// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1        // Watchdog Postscaler (1:1)

// CONFIG3H
#pragma config CANMX = PORTC    // ECAN Mux bit (ECAN TX and RX pins are located on RC6 and RC7, respectively)
#pragma config MSSPMSK = MSK5   // MSSP address masking (5 bit address masking mode)
#pragma config MCLRE = ON       // Master Clear Enable (MCLR Enabled, RE3 Disabled)

// CONFIG4L
#pragma config STVREN = OFF     // Stack Overflow Reset (Disabled)
#pragma config BBSIZ = BB1K     // Boot Block Size (1K word Boot Block size)

// CONFIG5L
#pragma config CP0 = OFF        // Code Protect 00800-01FFF (Disabled)
#pragma config CP1 = OFF        // Code Protect 02000-03FFF (Disabled)
#pragma config CP2 = OFF        // Code Protect 04000-05FFF (Disabled)
#pragma config CP3 = OFF        // Code Protect 06000-07FFF (Disabled)

// CONFIG5H
#pragma config CPB = OFF        // Code Protect Boot (Disabled)
#pragma config CPD = OFF        // Data EE Read Protect (Disabled)

// CONFIG6L
#pragma config WRT0 = OFF       // Table Write Protect 00800-01FFF (Disabled)
#pragma config WRT1 = OFF       // Table Write Protect 02000-03FFF (Disabled)
#pragma config WRT2 = OFF       // Table Write Protect 04000-05FFF (Disabled)
#pragma config WRT3 = OFF       // Table Write Protect 06000-07FFF (Disabled)

// CONFIG6H
#pragma config WRTC = OFF       // Config. Write Protect (Disabled)
#pragma config WRTB = OFF       // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF       // Data EE Write Protect (Disabled)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protect 00800-01FFF (Disabled)
#pragma config EBTR1 = OFF      // Table Read Protect 02000-03FFF (Disabled)
#pragma config EBTR2 = OFF      // Table Read Protect 04000-05FFF (Disabled)
#pragma config EBTR3 = OFF      // Table Read Protect 06000-07FFF (Disabled)

// CONFIG7H
#pragma config EBTRB = OFF      // Table Read Protect Boot (Disabled)

#include <xc.h>

#define  _XTAL_FREQ 8000000

#define i2cEEPROM_WP LATCbits.LATC0                                             // connect EEPROM to RC0 or to ground

// function prototypes - for descriptions, see function code
void linein(char* pstring);
char getparams(char* tempstring);
void PrintHex(unsigned char i);
void PrintHexSp(unsigned char i);
void UART1_Init(unsigned long baud_rate);
char UART1_Read(void);
void UART1_Write(unsigned char message);
void UART1_Write_Text(char *p);
void cmda(void);
void cmdd(void);
void cmdf(void);
void cmdp(void);
void cmdr(void);
void cmdt(void);
void cmdw(void);
void cmdz(void);
void I2C1_Init(const unsigned long clock);
unsigned short I2C1_Start(void);
void I2C1_Repeated_Start(void);
void I2C1_Stop(void);
unsigned short I2C1_Wr(unsigned short data_);
unsigned char I2C1_Rd(unsigned char ackflag);
void i2cEEPROM_WrSingle(unsigned int wAddr, unsigned char wData);
unsigned char i2cEEPROM_RdSingle(unsigned int rAddr);
void PrintHex(unsigned char ihex);
void PrintHexSp(unsigned char ihex);
void PrintHexInt(unsigned int ihex);
char getparams(char* tempstring);
void linein(char* pstring);

// global variables
unsigned char newcmd;                                                           // save most recent command letter
char cmd;                                                                       // first letter of input line
char linebuff[257];                                                             // allow up to this many characters in input line
unsigned char param[8][20];                                                     // up to 8 parameters
unsigned int upar[8];                                                           // parameters as word
unsigned char nparams;                                                          // number of parameters
unsigned char EC_hdr;
unsigned char EC_tmp;
unsigned int EC_adr;                                                            // memory address
unsigned char EC_data;                                                          // memory data
unsigned int ee_addr;                                                           // EEPROM address
char ascii_string[18];                                                          // store ASCII string for "r" command
char sec, min1, hr, week_day, day, mn, year;                                    // store information read from 1307 RTC
char *txt, tnum[4];                                                             // buffers for 1307 RTC

//--------------------- Reads time and date information from RTC (DS1307)
void Read_Time(char *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {

    I2C1_Start();
    I2C1_Wr(0xD0);                                                              // RTC address 0x38 shifted left, r/w cleared for write
    I2C1_Wr(0);                                                                 // start from register 0
    I2C1_Repeated_Start();
    I2C1_Wr(0xD1);                                                              // RTC address 0x38, shifted left, r/w set for read
    *sec = I2C1_Rd(1);                                                          // register 0
    *min = I2C1_Rd(1);                                                          // register 1
    *hr = I2C1_Rd(1);                                                           // register 2
    *week_day = I2C1_Rd(1);                                                     // register 3
    *day = I2C1_Rd(1);                                                          // register 4
    *mn = I2C1_Rd(1);                                                           // register 5
    *year = I2C1_Rd(0);                                                         // register 6
    I2C1_Stop();
}

//-------------------- Formats date and time
void Transform_Time(char  *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {
    *sec  =  ((*sec & 0x70) >> 4)*10 + (*sec & 0x0F);
    *min  =  ((*min & 0xF0) >> 4)*10 + (*min & 0x0F);
    *hr   =  ((*hr & 0x30) >> 4)*10 + (*hr & 0x0F);
    *week_day =(*week_day & 0x07);
    *day  =  ((*day & 0xF0) >> 4)*10 + (*day & 0x0F);
    *mn   =  ((*mn & 0x10) >> 4)*10 + (*mn & 0x0F);
    *year =  ((*year & 0xF0)>>4)*10+(*year & 0x0F);
}

//-------------------- Output values to UART
void Display_Time(char sec, char min, char hr, char week_day, char day, char mn, char year) {

    UART1_Write_Text("\r");
    switch(week_day){
        case 1:
            txt = "Sun";
            break;
        case 2:
            txt = "Mon";
            break;
        case 3:
            txt = "Tue";
            break;
        case 4:
            txt = "Wed";
            break;
        case 5:
            txt = "Thu";
            break;
        case 6:
            txt = "Fri";
            break;
        case 7:
            txt = "Sat";
            break;
        default:
            txt = "Inv";
            break;
   }
   UART1_Write_Text(txt);

   UART1_Write(' ');
   UART1_Write((day / 10) + 48);                                                // Print tens digit of day variable
   UART1_Write((day % 10)   + 48);                                              // Print ones digit of day variable
   UART1_Write('-');
   UART1_Write((mn / 10) + 48);
   UART1_Write((mn % 10) + 48);
   UART1_Write_Text("-202");
   UART1_Write( year  + 48);                                                    // Print year

   UART1_Write(' ');
   UART1_Write((hr / 10)   + 48);
   UART1_Write((hr % 10)   + 48);
   UART1_Write(':');
   UART1_Write((min / 10) + 48);
   UART1_Write((min % 10) + 48);
   UART1_Write(':');
   UART1_Write((sec / 10) + 48);
   UART1_Write((sec % 10) + 48);
   if((sec > 59 ) || (min > 59 ) || (hr > 23 ) || (day > 31 ) || (mn > 12 )){
       UART1_Write_Text("  * Invalid ! *"); 
       UART1_Write_Text("\r\n  check 1307 RTC connections\r\n"); 
   }
}

// initialise UART 1 for 9600,8,n,1
// note that baud rate argument is currently completely ignored
void UART1_Init(unsigned long baud_rate){
    //TXSTAx TRANSMIT STATUS AND CONTROL REGISTER
    TXSTA1bits.CSRC = 0;                                                        // : Don?t care.
    TXSTA1bits.TX9 = 0;                                                         // Selects 8-bit transmission
    TXSTA1bits.TXEN = 1;                                                        // Transmit Enable
    TXSTA1bits.SYNC  = 0;                                                       // Asynchronous mode
    TXSTA1bits.SENDB = 0;
    TXSTA1bits.BRGH =  1;                                                       //  High speed mode
    TXSTA1bits.TX9D = 0;
    //RCSTAx: RECEIVE STATUS AND CONTROL REGISTER
    RCSTA1bits.SPEN  = 1 ;                                                      // Serial port enabled
    RCSTA1bits.RX9 = 0;                                                         // Selects 8-bit reception
    RCSTA1bits.SREN  = 1 ;                                                      // Don?t care.
    RCSTA1bits.CREN  = 1 ;                                                      // Enables receiver
    RCSTA1bits.ADDEN = 0;                                                       //
    RCSTA1bits.FERR  = 0 ;                                                      // No framing error
    RCSTA1bits.OERR  = 1 ;                                                      // Overrun error
    RCSTA1bits.RX9D   = 0 ;                                                     // Selects 8-bit reception

    SPBRGH1 = 0;
    SPBRG1 = 51;                                                                // 129 for 20MHz Fosc, 51 for 8 MHz intosc
}

// write a single character to UART 1 - blocking
void UART1_Write(unsigned char message){
    while(PIR1bits.TX1IF == 0 );                                                // Wait till the transmitter register becomes empty
    TXREG1 = message;
}

// write a string to UART 1
void UART1_Write_Text(char *p){
    while(*p != '\0') {
        //__delay_ms(1);
        UART1_Write(*p); 
        p++;
    }
}

// read a single charater from UART1
char UART1_Read(void){
  char temp;

    while(!PIR1bits.RC1IF);                                                     // blocking wait for character to arrive from terminal
    temp = RCREG1;                                                              // get the character
    return temp;
}

// Initialise I2C in master mode - clock frequency is ignored - 100KHz only
void I2C1_Init(const unsigned long clock){
  
    SSPSTAT = 0x80;                                                             // Slew rate control is disabled for Standard Speed mode (100 kHz and 1 MHz)
    SSPCON1 = 0x28;                                                             // I2C Master mode, clock = FOSC/(4 * (SSPADD + 1))
    SSPCON2 = 0x00;
    SSPADD = 49;                                                                // 100kHz clock @ 20MHz Fosc SSPADD = ( (Fosc/4) / BiteRate )-1
                                                                                // SSPADD = ( 20MHz / 100KHz ) - 1 = 49 //
}

// Send an I2C START
// Return 0 if all ok, 1 if bus collision
unsigned short I2C1_Start(void){
    PIR2bits.BCLIF = 0;  //Clear 'Bus collision" flag
    SSPCON2bits.SEN = 1;                                                        // initiate a START cycle
    while (SSPCON2bits.SEN);                                                    // wait until it has been sent
    return PIR2bits.BCLIF;                                                      // return value of BCLIF flag
}

// Send an I2C STOP
void I2C1_Stop(void){
    SSPCON2bits.PEN = 1;                                                        // initiate a STOP cycle
    while (SSPCON2bits.PEN);                                                    // wait until it has been sent
}

// Send an I2C REPEATED START
void I2C1_Repeated_Start(void){
    SSPCON2bits.RSEN = 1;                                                       // initiate a REPEATED START cycle
    while (SSPCON2bits.RSEN);                                                   // wait until it has been sent
}

// Receive one byte. ackflag=0 to send ACK, or 1 to send NAK in reply
// Send one byte. Return 0 if ACK received, or 1 if NAK received
unsigned short I2C1_Wr(unsigned short data_){
    SSPBUF = (unsigned char)data_;
    asm ("nop");                                                                // <<<--- wait a little for R_W to be set
    while (SSPSTATbits.R_W);                                                    // wait until byte sent and ACK/NAK received
    return SSPCON2bits.ACKSTAT;
}

unsigned char I2C1_Rd(unsigned char ackflag){
    SSPCON2bits.RCEN = 1;                                                       // initiate a RECEIVE cycle
    SSPCON2bits.ACKDT = !(ackflag & 0x01);                                      // specify if we should send ACK or NAK after receiving
    while (SSPCON2bits.RCEN);                                                   // wait until RECEIVE has completed
    SSPCON2bits.ACKEN = 1;                                                      // initiate an ACK cycle
    while (SSPCON2bits.ACKEN);                                                  // wait until it has completed
    return SSPBUF;
}


void main() {
    ADCON0 = 0;                                                                 // Configure PORT pins as digital
    TRISA = 0;                                                                  // all output
    TRISB = 0;                                                                  // all output
    TRISC = 0x98;                                                               // UART1 Rx, I2C SDA, SCL input, rest output
    TRISD = 0;                                                                  // all output
    TRISE = 0;                                                                  // all output
    LATA = 0;                                                                   // all low
    LATB = 0x00;                                                                // clear all to Low
    LATC = 0x00;                                                                // clear all to Low
    LATD = 0x00;                                                                // clear all to Low
    LATE = 1;                                                                   // CS# high
    
    __delay_ms(1000);                                                           // prevent double start when programming
    UART1_Init(9600);                                                           // Initialise UART 1
    __delay_ms(100);                                                            // Wait for UART modules to stabilise
    newcmd = '?';                                                               // default to help
    cmd = newcmd;

    UART1_Write_Text("\r\n\ni2cEEPROM Monitor 6 June 2021\r\n");                // introduction text
    UART1_Write_Text("? for help\r\n\n");                                         // introduction text

    i2cEEPROM_WP = 1;                                                           // start with EEPROM write protected
    I2C1_Init(100000);                                                          // initialise I2C communication
    __delay_ms(100);                                                            // allow I2C to settle

    while(1){
        linein(linebuff);                                                       // fetch a line of text
        newcmd = getparams(linebuff);                                           // read hex parameters
        switch(newcmd){                                                         // act upon command letter
            case 'A':
                cmda();
                break;

            case 'D':
                cmdd();
                break;

            case 'F':
                cmdf();
                break;

            case 'R':
                cmdr();
                break;

            case 'P':
                cmdp();
                break;

            case 'T':
                cmdt();
                break;

            case 'W':
                cmdw();
                break;

            case 'Z':
                cmdz();
                break;

            case '?':
                UART1_Write_Text("\r\n");
                UART1_Write_Text("?                 List Commands\r\n");
                UART1_Write_Text("a                 spare command for Dj\r\n");
                UART1_Write_Text("d mm hh w dd mm y write Date/time to 1307 RTC\r\n");
                UART1_Write_Text("f dd              Fill with dd i2cEEPROM\r\n");
                UART1_Write_Text("p                 spare command for Dj\r\n");
                UART1_Write_Text("r                 Read i2cEEPROM\r\n");
                UART1_Write_Text("t                 read Time from 1307 RTC\r\n");
                UART1_Write_Text("w aaa dd          Write i2cEEPROM\r\n");
                UART1_Write_Text("z                 set fixed date/time to 1307 RTC\r\n");
                UART1_Write_Text("\r\n");
                break;
            default:{
                UART1_Write_Text("\r\ncommand not recognised\r\n");
                break;
            }
        }
    }
}

// spare command for Dj
void cmda(void){
    UART1_Write_Text("\r\nspare 'a' command for Dj\r\n");

    // put your clever new code here
    
    UART1_Write_Text("\r\n - all done - \r\n\n");
    
}

// write date to 1307 RTC
void cmdd(void){
    if(nparams < 2){                                                            // warn if wrong number of parameters, but allow anyway to default to old values
        UART1_Write_Text("\r\nneed at least 1 parameter...\r\nd mm hh w dd mm y\r\n");
        UART1_Write_Text("minute, hour, weekday 1=Sun, day, month, year 0-9\r\n\n");
    }
    else{
        I2C1_Start();                                                           // issue start signal
        I2C1_Wr(0xD0);                                                          // address DS1307  (0x68 shifted left by one)
        I2C1_Wr(0);                                                             // start from word at address (REG0)
        I2C1_Wr(0x80);                                                          // write $80 to REG0. (pause counter + 0 sec)
        I2C1_Wr(upar[1] & 0xff);                                                // write to minutes word to (REG1)
        if(nparams > 2){
            I2C1_Wr(upar[2] & 0xff);                                            // write to hours word (24-hours mode)(REG2)
            if(nparams > 3){
                I2C1_Wr(upar[3] & 0xff);                                        // write day (1 = Sunday) (REG3)
                if(nparams > 4){
                    I2C1_Wr(upar[4] & 0xff);                                    // write to date word (REG4)
                    if(nparams > 5){
                        I2C1_Wr(upar[5] & 0xff);                                // write to month word (REG5)
                        if(nparams > 6){
                            I2C1_Wr(upar[6] & 0xff);                            // write to year word (REG6)     
                        }
                    }
                }
            }
        }
        I2C1_Stop();                                                            // issue stop signal

        I2C1_Start();                                                           // issue start signal
        I2C1_Wr(0xD0);                                                          // address DS1307  (0x68 shifted left by one)
        I2C1_Wr(0);                                                             // start from word at address 0
        I2C1_Wr(0);                                                             // write 0 to REG0 (enable counting + 0 sec)
        I2C1_Stop();                                                            // issue stop signal
        UART1_Write_Text("new date/time set\r\n\n");
    }
}
  
// fill with dd EEPROM Click
// f dd      write data dd (hex) to address aaa (hex)
void cmdf(void){

    EC_data = upar[1] & 0xff;                                                   // parameter 1 is byte value to fill with
    i2cEEPROM_WP = 0;                                                           // WP write enable when low
    UART1_Write_Text("\r\nEEPROM Fill");

    if(nparams == 2){
        for(ee_addr = 0; ee_addr < 1024; ee_addr++){
            i2cEEPROM_WrSingle(ee_addr, EC_data);                               // write byte
            if((ee_addr & 0x1f) == 0){                                          // only print a dot every 32 bytes -
                UART1_Write_Text(".");                                          //    - to show that fill is still in progress
            }
        }
    }
    else{
        UART1_Write_Text("\r\nsyntax error - need...\r\nf dd\r\n");
    }
    i2cEEPROM_WP = 1;                                                           // WP write protect when high
    UART1_Write_Text("\r\ndone\r\n");
}

// PIXI click test mikroBus 1
void cmdp(void){
    
    UART1_Write_Text("\r\nSpare function p\r\n\n");
}

// read I2C EEPROM
void cmdr(void){

    i2cEEPROM_WP = 1;                                                           // WP write protect when high
    UART1_Write_Text("\r\nEEPROM Contents...");
    ascii_string[16] = 0;                                                       // null terminate ASCII string
    ascii_string[0] = 0;                                                        // no ASCII string for first line

    for(EC_adr = 0; EC_adr < 256; EC_adr++){                                    // 1k bytes in 24C08 I2C EEPROM, 256 bytes in 24C02 I2C EEPROM
        if(! (EC_adr & 0x0f)){                                                  // show address every 16th byte
            UART1_Write_Text(ascii_string);                                     // print ASCII string at end of line
            UART1_Write_Text("\r\n");
            PrintHexInt(EC_adr);                                                // print address byte as hex
            UART1_Write_Text(" = ");
        }
        else{
            if(! (EC_adr & 0x03)){                                              // show '-' after every fourth byte
                UART1_Write_Text("- ");
            }
        }
        EC_tmp = (EC_adr >> 8) & 0x03;                                          // get top 2 address bits
        EC_hdr = 0x50 + EC_tmp;                                                 // bare EEPROM i2c address + hi 2 bits EEPROM aggress
        EC_data = i2cEEPROM_RdSingle(EC_adr);                                   // read single byte (data address)
        PrintHexSp(EC_data);                                                    // print the data byte as hex
        if((EC_data > 31) && (EC_data < 128)){                                  // printable characters only
            ascii_string[EC_adr & 0x0f] = EC_data;                              // store ASCII for later print - limit pointer 0 to 0x0f
        }
        else{                                                                   // change non-printable character to dot
            ascii_string[EC_adr & 0x0f] = '.';                                  // store dot for later print - limit pointer 0 to 0x0f
        }
        __delay_ms(1);                                                          // slow down the display rate
    }
    UART1_Write_Text(ascii_string);                                             // print final ASCII string
    UART1_Write_Text("\r\n");
}

// read time from 1307 I2C RTC
void cmdt(void){
    UART1_Write_Text("time from 1307 RTC\r\n");
    Read_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year);                         // read time from RTC(DS1307)
    Transform_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year);                    // format date and time     
    Display_Time(sec, min1, hr, week_day, day, mn, year);                       // prepare and display on LCD
    UART1_Write_Text("\r\n");
}

// write to I2C EEPROM
// w aaa dd      write data dd (hex) to address aaa (hex)
void cmdw(void){

    EC_adr = upar[1];                                                           // parameter 1 is address 0 to 0x03ff
    EC_data = upar[2] & 0xff;                                                   // parameter 2 is data to write

    i2cEEPROM_WP = 0;                                                           // WP write enable when low
    UART1_Write_Text("\r\nEEPROM Write...");

    __delay_ms(100);                                                              // no idea why I put this here :(

    if(nparams == 3){
        i2cEEPROM_WrSingle(EC_adr, EC_data);                                    // write byte
    }
    else{
        UART1_Write_Text("syntax error - need...\r\nw aaa dd\r\n");
    }
    i2cEEPROM_WP = 1;                                                           // WP write protect when high
    UART1_Write_Text("\r\n");
}

// set fixed date/time to 1307 RT
void cmdz(void){
    I2C1_Start();                                                               // issue start signal
    I2C1_Wr(0xD0);                                                              // address DS1307  (0x68 shifted left by one)
    I2C1_Wr(0);                                                                 // start from word at address (REG0)
    I2C1_Wr(0x80);                                                              // write $80 to REG0. (pause counter + 0 sec)
    I2C1_Wr(0x30);                                                              // write to minutes word to (REG1)
    I2C1_Wr(0x11);                                                              // write to hours word (24-hours mode)(REG2)
    I2C1_Wr(0x07);                                                              // write day (1 = Sunday) (REG3)
    I2C1_Wr(0x05);                                                              // write to date word (REG4)
    I2C1_Wr(0x06);                                                              // write to month word (REG5)
    I2C1_Wr(0x01);                                                              // write to year word (REG6)
    I2C1_Stop();                                                                // issue stop signal

    I2C1_Start();                                                               // issue start signal
    I2C1_Wr(0xD0);                                                              // address DS1307  (0x68 shifted left by one)
    I2C1_Wr(0);                                                                 // start from word at address 0
    I2C1_Wr(0);                                                                 // write 0 to REG0 (enable counting + 0 sec)
    I2C1_Stop();                                                                // issue stop signal
    UART1_Write_Text("1307 date/time reset\r\n");
}

// display byte in hex
void PrintHex(unsigned char ihex) {
unsigned char hib,lob;

    hib = ihex & 0xF0;                                                          // high nibble
    hib = hib >> 4;
    hib = hib + '0';
    if (hib > '9') hib = hib + 7;
    lob = (ihex & 0x0F) + '0';                                                  // low nibble
    if (lob > '9') lob = lob+7;

    UART1_Write(hib);
    UART1_Write(lob);
}

// display byte in hex with trailing space
void PrintHexSp(unsigned char ihex) {
unsigned char hib,lob;

    hib = ihex & 0xF0;                                                          // high nibble
    hib = hib >> 4;
    hib = hib + '0';
    if (hib > '9') hib = hib + 7;
    lob = (ihex & 0x0F) + '0';                                                  // low nibble
    if (lob > '9') lob = lob + 7;

    UART1_Write(hib);
    UART1_Write(lob);
    UART1_Write(' ');
}

// display unsigned integer in hex
void PrintHexInt(unsigned int ihex) {
    PrintHex((ihex >> 8) & 0xff) ;
    PrintHex(ihex & 0xff);
}

// get parameters from string
char getparams(char* tempstring){
  char oldcmd;                                                                  // remember old command letter
  int  n;                                                                       // counter
  char tempchar;                                                                // temp store
  char tempchar2;                                                               // temp store
  unsigned int pointer1 = 0;                                                    // pointer within string
  unsigned int pointer2 = 0;                                                    // pointer within string

    oldcmd = cmd;                                                               // remember old value
    nparams = 0;                                                                // initialise
    pointer1 = 0;                                                               // initialise

    for ( n = 0 ; n < 8 ; n++){                                                 // count 0 to 7
        // skip leading spaces
        tempchar=1;                                                             // init
        do {
            tempchar = tempstring[pointer1++];
        } while (tempchar == 0x20);
        pointer1--;                                                             // leave pointer after param

        // count parameters
        if ((tempchar != 0) && (nparams < 8)){
            nparams++;
        }

        if (n == 0){                                                            // only for param 0
            tempchar=tempstring[pointer1];                                      // get only first letter
            if ((tempchar > 0x60) && (tempchar < 0x7b)) {
                tempchar -= 0x20;                                               // to upper case
            }
            cmd=tempchar;
        }

        tempchar=1;                                                             // initialise
        if (nparams != 0){                                                      // only for non-blank line
            // get all characters
            pointer2=0;                                                         // initialise
            do {
                tempchar = tempstring[pointer1++];                              // get char
                if ((tempchar > 0x60) && (tempchar < 0x7b)) {
                    tempchar -= 0x20;                                           // to upper case
                }
                param[n][pointer2++] = tempchar;                                // and store it
            } while ((tempchar > 0x20) && (tempchar < 0x7f) && (pointer2 < 20)); // text
            param[n][pointer2-1]=0;                                             // zero terminate param string
            if((tempchar == 0)||(n == 9)){                                      // no more params if end of line
                break;
            }
        }
    }

    // convert parameter strings to hex longwords
    for (n = 0; n < nparams ; n++){                                             // parms are 0 to 7
        tempchar2=1;                                                            // initialise
        pointer1=0;                                                             // initialise
        upar[n]=0;                                                              // initialise
        do {
            tempchar = param[n][pointer1++];
            // read one character
            if ( tempchar != 0 ){
                upar[n] = upar[n] * 0x10;                                       // next most signicant hex digit
            }
            tempchar2 = tempchar;                                               // remember original character
            if ((tempchar < 0x30) || (tempchar > 0x46)) {
                tempchar = 0x00;                                                // non-hex to zero
            }
            if ((tempchar > 0x39) && (tempchar < 0x41)) {
                tempchar = 0x00;                                                // non-hex to zero
            }
            if ((tempchar > 0x40) && (tempchar < 0x47)) {
                tempchar -= 0x37;                                               // to bin
            }
            if ((tempchar > 0x2f) && (tempchar < 0x3a)) {
                tempchar -= 0x30;                                               // to bin
            }
            upar[n] += tempchar;
        } while (tempchar2 != 0);
    }

    if (nparams == 0) {
        cmd = oldcmd;
    }
    return cmd;
}

// get a string from UART1.
// Input: Buffer pointer.
// Output: updated buffer.
void linein(char* pstring){
  char inChar = 0;

    while(inChar != '\r'){                                                      // keep reading until CR

        //UART1 read
        if (PIR1bits.RC1IF){                                                    // if a character is received, then process it
            inChar = UART1_Read();                                              // get the character
            if(inChar != '\n'){                                                 // ignore new line completely
                UART1_Write(inChar);                                            // echo the character
                if(inChar == '\r'){                                             // CR
                    UART1_Write('\n');                                          // send LF if CR received
                    *pstring ++= '\0';                                          // null terminate the received string
                }
                else {
                    if (inChar != 0x08 ){                                       // if not backspace
                        *pstring++ = inChar;                                    // add the new character to the receive string
                    }
                    if (inChar == 0x08 ){                                       // handle backspace (very crudely)
                        *--pstring = 0x00;                                      // move terminator back
                    }
                }
            }
        }
    }
}

//--------------- Writes data to I2C EEPROM - single location
void i2cEEPROM_WrSingle(unsigned int wAddr, unsigned char wData) {
  unsigned char hi_addr;                                                        // top two bits of address to bits 2,1

    wAddr &= 0x3ff;                                                             // force address to a valid address
    hi_addr = (wAddr >> 7) & 0x06;                                              // extract top two address bits to bits 2,1
    I2C1_Start();                                                               // issue I2C start signal
    I2C1_Wr(0xA0 | hi_addr);                                                    // send byte via I2C  (device address + W)
    I2C1_Wr(wAddr);                                                             // send byte (address of EEPROM location)
    I2C1_Wr(wData);                                                             // send data (data to be written)
    I2C1_Stop();                                                                // issue I2C stop signal
    __delay_ms(10);                                                             //  too lazy to work out how long to wait, so over-long wait
}

//--------------- Reads data from I2C EEPROM - single location (random)
unsigned char i2cEEPROM_RdSingle(unsigned int rAddr) {
  unsigned char result;
  unsigned char hi_addr;                                                        // top two bits of address to bits 2,1

    rAddr &= 0x3ff;                                                             // force address to a valid address
    hi_addr = (rAddr >> 7) & 0x06;                                              // extract top two address bits to bits 2,1
    I2C1_Start();                                                               // issue I2C start signal
    I2C1_Wr(0xA0 | hi_addr);                                                    // send byte via I2C  (device address + W)
    I2C1_Wr(rAddr);                                                             // send byte (data address)
    I2C1_Repeated_Start();                                                      // issue I2C signal repeated start
    I2C1_Wr(0xA1 | hi_addr);                                                    // send byte (device address + R)
    result = I2C1_Rd(0);                                                        // Read the data (NO acknowledge)
    I2C1_Stop();                                                                // issue I2C stop signal
    return result;
}
 
Last edited:

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
Great stuff.

Time to try out a monitor program.
It looks complicated, and it is, but you can just accept that it works and just add your own new commands.
@hexreader I will take a time to fully understand your program

But for now I'm stuck with small problem in program #249. I want to send whatever I'm receiving but program is not doing that so I'm just trying to figure out what's wrong in code
 

hexreader

Joined Apr 16, 2011
619
Change 10ms delay to 100 ms.
10ms is not long enough for UART to settle.

EDIT: Better still - make the delay 1000ms. In case something else is slow to start. Does no harm, so always put 1 second delay in every project - at least until you are sure that it is not needed.

That code works perfectly for me.
Presumably your setup (hardware, PC or cabling) still has problems.
 
Last edited:

hexreader

Joined Apr 16, 2011
619
#pragma config PWRTEN = OFF // Power Up Timer->Disabled

I was once advised on Microchip forum, to turn power-up timer ON, to make PIC start-up more reliable. I usually turn it on now.
 

hexreader

Joined Apr 16, 2011
619
Edit : If the two way communication is happening then what's the wrong in my code #249
Don't know why code #249 does not work for you. It works for me.
If code #257 is working, then why not just remove the "Receive++;" and use the remaining code as the basis for future serial communications?
 
Top