PIC Development Board with PK3

hexreader

Joined Apr 16, 2011
619
Are you sure that it is your LCD that is unreliable?

RTC with floating battery pin WILL be unreliable. Either fit battery or connect battery pin to ground.
 

hexreader

Joined Apr 16, 2011
619
I don't understand either.

20MHz external crystal. 8MHz internal oscillator. Both work on my development board.

If internal 8MHz works for you, then stay with it.

When I get really, really bored then I will write monitor program for 8MHz internal oscillator.
I cannot predict when that level of boredom will occur. Might be hours - weeks - never
 
Last edited:

hexreader

Joined Apr 16, 2011
619
RTC / EEPROM monitor for 8MHz internal oscillator is attached...

Code:
// Important Note: some of the code below  is based on example code that is copyright of  mikroE

// original code is copyright Djsarker - 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 20 May 2021....
//    - much tidying desperately needed
//    - backspace does not work correctly
//    - 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 cmdd(void);
void cmdf(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);
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;
    TRISB  = 0;                                                                 // Configure PORT as output
    TRISC  = 0x98;                                                              // UART1 Rx, I2C SDA, SCL input, rest output
    TRISD  = 0;                                                                 // Configure PORT as output
    LATA = 0;
    LATB = 0x00;                                                                // clear all to Low
    LATC = 0x00;                                                                // clear all to Low
    LATD = 0x00;                                                                // clear all to Low

    __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 20 May 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 'D':
                cmdd();
                break;

            case 'F':
                cmdf();
                break;

            case 'R':
                cmdr();
                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("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("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;
            }
        }
    }
}

// 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");
}

// 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");
            PrintHex(EC_adr/256);                                               // print high address byte as hex
            PrintHex(EC_adr & 0xff);                                                   // print low address byte
            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(0x34);                                                              // write to minutes word to (REG1)
    I2C1_Wr(0x12);                                                              // write to hours word (24-hours mode)(REG2)
    I2C1_Wr(0x05);                                                              // write day (1 = Sunday) (REG3)
    I2C1_Wr(0x20);                                                              // write to date word (REG4)
    I2C1_Wr(0x05);                                                              // 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(' ');
}

// 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
            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 != 0x7f ){                                           // if not backspace
                    *pstring++ = inChar;                                        // add the new character to the receive string
                }
                if (inChar == 0x7f ){                                           // handle backspace (very crudely)
                    *--pstring = 0x00;                                          // move terninator 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:

hexreader

Joined Apr 16, 2011
619
What is the one bug?

Print 4 times? Mine only prints once.

Wrong date? - that is the date of writing, not today's date.

Expecting more text? - you need to type a command to show more stuff - such as "?" (return)

Unable to input? - try the tests in post #221 and report results

Code:
i2cEEPROM Monitor 20 May 2021
? for help

?

?                 List Commands
d mm hh w dd mm y write Date/time to 1307 RTC
f dd              Fill with dd i2cEEPROM
r                 Read i2cEEPROM
t                 read Time from 1307 RTC
w aaa dd          Write i2cEEPROM
z                 set fixed date/time to 1307 RTC

r

EEPROM Contents...
0000 = 00 00 00 00 - 00 00 00 00 - 00 00 00 00 - 00 00 00 00 ................
0010 = 00 00 00 00 - 00 00 00 00 - 00 00 00 00 - 00 00 00 00 ................
0020 = 00 00 00 00 - 00 00 00 00 - 00 00 00 00 - 00 00 00 00 ................
0030 = 00 00 00 00 - 00 00 00 00 - 00 00 00 00 - 00 00 00 00 ................
0040 = 00 41 42 43 - 44 45 00 00 - 00 00 00 00 - 00 00 00 00 .ABCDE..........
0050 = 00 00 00 00 - 00 00 00 00 - 00 00 00 00 - 00 00 00 00 ................
0060 = 00 00 00 00 - 00 00 00 00 - 00 00 00 00 - 00 00 00 00 ................
0070 = 00 00 00 00 - 00 00 00 00 - 00 00 00 00 - 00 00 00 00 ................
0080 = 00 00 00 00 - 00 00 00 00 - 00 00 00 00 - 00 00 00 00 ................
0090 = 00 00 00 00 - 00 00 00 00 - 00 00 00 00 - 00 00 00 00 ................
00A0 = 00 00 00 00 - 00 00 00 00 - 00 00 00 00 - 00 00 00 00 ................
00B0 = 00 00 00 00 - 00 00 00 00 - 00 00 00 00 - 00 00 00 00 ................
00C0 = 00 00 00 00 - 00 00 00 00 - 00 00 00 00 - 00 00 00 00 ................
00D0 = 00 00 00 00 - 00 00 00 00 - 00 00 00 00 - 00 00 00 00 ................
00E0 = 00 00 00 00 - 00 00 00 00 - 00 00 00 00 - 00 00 00 00 ................
00F0 = 00 00 00 00 - 00 00 00 00 - 00 00 00 00 - 00 00 00 00 ................
t
time from 1307 RTC
Mon 31-05-2021 09:43:37
 
Last edited:

hexreader

Joined Apr 16, 2011
619
Just to be clear - the above example terminal display includes commands that I typed in...
? (return)
r (return)
t (return)

If I type nothing, then I see exactly what you report seeing in post #225

If typing produces nothing, then the problem is with your hardware. Development board, PC Terminal, or cabling between the two.
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
Just to be clear - the above example terminal display includes commands that I typed in...
? (return)
r (return)
t (return)

If I type nothing, then I see exactly what you report seeing in post #225

If typing produces nothing, then the problem is with your hardware. Development board, PC Terminal, or cabling between the two.
@hexreader your code is not working on my board When I type command I don't see anything on terminal
Here is my code for EEPROM test

C:
/*
* File:   main.c
* Author: Djsarkar
*
* Created on May 31, 2021, 8:08 PM
*/


//
#define _XTAL_FREQ 20000000     // crystal 20MHz

// 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)
// SOSCSEL = No Setting
#pragma config XINST = OFF      // Extended Instruction Set (Disabled)
// CONFIG1H
#pragma config FOSC = HS2       // HS oscillator (high power, 16 MHz-25 MHz
#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 = ON         // Code Protect 00800-01FFF (Enabled)
#pragma config CP1 = ON         // Code Protect 02000-03FFF (Enabled)
#pragma config CP2 = ON         // Code Protect 04000-05FFF (Enabled)
#pragma config CP3 = ON         // Code Protect 06000-07FFF (Enabled)
// CONFIG5H
#pragma config CPB = ON         // Code Protect Boot (Enabled)
#pragma config CPD = ON         // Data EE Read Protect (Enabled)
// CONFIG6L
#pragma config WRT0 = ON        // Table Write Protect 00800-01FFF (Enabled)
#pragma config WRT1 = ON        // Table Write Protect 02000-03FFF (Enabled)
#pragma config WRT2 = ON        // Table Write Protect 04000-05FFF (Enabled)
#pragma config WRT3 = ON        // Table Write Protect 06000-07FFF (Enabled)
// CONFIG6H
#pragma config WRTC = ON        // Config. Write Protect (Enabled)
#pragma config WRTB = ON        // Table Write Protect Boot (Enabled)
#pragma config WRTD = ON        // Data EE Write Protect (Enabled)
// CONFIG7L
#pragma config EBTR0 = ON       // Table Read Protect 00800-01FFF (Enabled)
#pragma config EBTR1 = ON       // Table Read Protect 02000-03FFF (Enabled)
#pragma config EBTR2 = ON       // Table Read Protect 04000-05FFF (Enabled)
#pragma config EBTR3 = ON       // Table Read Protect 06000-07FFF (Enabled)
// CONFIG7H
#pragma config EBTRB = ON       // Table Read Protect Boot (Enabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#pragma warning disable 520

#include <xc.h>

unsigned char Result1;
unsigned char Result2;
unsigned char Result3;
unsigned char Result4;

// The code should set the R/W bit according to its function
#define EEPROM_ADDRESS      0xA0         //I2C slave address of 24c02 (8 bit format)
#define Word_Address1       0x00


#define LCD_RS              LATBbits.LATB3
#define LCD_TRIS_RS         TRISBbits.TRISB3
#define LCD_RW              LATBbits.LATB4
#define LCD_TRIS_RW         TRISBbits.TRISB4
#define LCD_E               LATBbits.LATB5
#define LCD_TRIS_E          TRISBbits.TRISB5

#define  LCDPORT            LATD
#define  LCDTRISD           LATD

void Port_Initialized (void);
void WriteNibble(unsigned char command);
void WaitLCDBusy(void);
void WriteCommand(unsigned char command);

void Port_Initialized (void)
{
// LATx registers
    LATA =  0x00;
    LATB =  0x00;
    LATC =  0x00;
    LATD =  0x00;
    LATE =  0x00;

//  TRISx registers
    TRISA = 0x00;      // All are output, Unused
    TRISB = 0x00;      // all are output, Unused
    TRISC = 0x18;      // Slave SDA and CLOCK
    TRISD = 0x00;      // LCD
    TRISE = 0x00;      // All are output, Unused

    ANCON0 = 0x00;     // set to digital port
    ANCON1 = 0x00;     // Set to digital port
    CM1CON = 0x00;     // Comparator off
    CM2CON = 0x00;     // Comparator off
    ADCON0 = 0x00;     // A/D conversion Disabled
    ADCON1 = 0x00;     // A/D conversion Disabled
    ADCON2 = 0x00;     // A/D conversion Disabled
}

// Wait for 5 ms
void WaitLCDBusy(void)
{
    __delay_ms(5);
}

//Send a command to the LCD
void WriteCommand(unsigned char command)
{
    WaitLCDBusy();                        //wait until not busy
    LCD_RS = 0;                           //setup to send command
    WriteNibble(command);                 //write the high nibble
    WriteNibble( (unsigned char)(command<<4) ); //then the low nibble 
}

//Initialized  LCD
void LCD_Initialized()
{
    LCDTRISD &=0x0f;                //ensure data bits are output
    LCD_E=0;                        //clear enable
    LCD_RS = 0;                     //going to write command
    LCD_TRIS_E=0;                   //Set enable to output
    LCD_TRIS_RS=0;                  //set RS to output
    LCD_TRIS_RW=0;
    LCD_RW=0;
    __delay_ms(30);                 //delay for LCD to initialise.
    WriteNibble(0x30);              //Required for initialisation
    __delay_ms(5);                  //required delay
    WriteNibble(0x30);              //Required for initialisation
    __delay_ms(1);                  //required delay
    WriteCommand(0x20);             //set to 4 bit interface
    WriteCommand(0x2c);             //set to 4 bit interface, 2 line and 5*10 font
    WriteCommand(0x01);             //clear display
    WriteCommand(0x06);             //move cursor right after write
    WriteCommand(0x0C);             //turn on display
}

//Send a character to the LCD
void WriteChar(unsigned char chr)
{
    WaitLCDBusy();                         //wait until not busy
    LCD_RS=1;                              //Setup to send character
    WriteNibble(chr);                      //write the high nibble         
    WriteNibble( (unsigned char)(chr<<4)); //then the low nibble
}

//Send any 4 bits to the LCD
void WriteNibble(unsigned char command)
{
    LCDPORT &= 0x0f;                        //clear the data bits
    LCDPORT|=((command & 0xf0));            //or in the new data
    LCD_E = 1;                              //enable the LCD interface
    NOP();                                  // delay of 1uS
    NOP();
    NOP();
    LCD_E = 0;                              //disable it
}

void LCD_Data( unsigned char *string)
{
    while (*string != '\0')
    {
      WriteChar(*string);
        string++;
    }
}

//Initialize I2C in master mode
void I2C_Initialized(void)
{
    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
__bit I2C_Start(void)
{
    BCLIF = 0;  //Clear 'Bus collision" flag
    SEN = 1;    //initiate a START cycle
    while (SEN);    //wait until it has been sent
    return BCLIF;   //return value of BCLIF flag
}
// Send an I2C STOP
void I2C_Stop(void)
{
    PEN = 1;    //initiate a STOP cycle
    while (PEN);    //wait until it has been sent
}

// Send an I2C REPEATED START
void I2C_Restart(void)
{
    RSEN = 1;    //initiate a REPEATED START cycle
    while (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
__bit I2C_Sendbyte(unsigned char dat)
{
    SSPBUF = dat;

    asm("nop");     // wait a little for R_W to be set

    while (R_W);    //wait until byte sent and ACK/NAK received
    return ACKSTAT;
}

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

//Send an array of data to an I2C device.
//Return 0 if all OK, 1 if bus error, 2 if slave address NAK, 3 if slave register NAK, 4 if slave data NAK
unsigned char EEPROM_Write(unsigned char slave_address, unsigned char start_reg, unsigned char buflen, const unsigned char * bufptr)
{
    if (I2C_Start() )   //send a start, and check if it succeeded
        return 1;   //abort if bus collision
    //send the I2C slave address (force R/W bit low)
    if (I2C_Sendbyte(slave_address & 0xfe))  // <<---- Added AND to force R/W- low.
    {
        I2C_Stop(); //if address was NAKed, terminate the cycle
        return 2;   //and return error code
    }
    //send the device register index
    if (I2C_Sendbyte(start_reg))
    {
        I2C_Stop(); //if register was NAKed, terminate the cycle
        return 3;   //and return error code
    }
    //send the data. buflen might be zero!
    for (; buflen>0; --buflen)
    {
        if (I2C_Sendbyte(*bufptr++))
        {
            I2C_Stop(); //if register was NAKed, terminate the cycle
            return 4;   //and return error code
        }
    }
    I2C_Stop();
    return 0;   //no error
}

//Receive an array of data from an I2C device.
//Return 0 if all OK, 1 if bus error, 2 if slave address NAK, 3 if slave register NAK
unsigned char EEPROM_Read(unsigned char slave_address, unsigned char start_reg, unsigned char buflen, unsigned char * bufptr)
{
    //do a dummy zero length write cycle to set the register address
    unsigned char retval = EEPROM_Write(slave_address, start_reg, 0, 0);
    if (retval)
    {
        return retval;  //abort if there was an error
    }
    //now start the READ cycle
    if (I2C_Start() )   //send a start, and check if it succeeded
        return 1;   //abort if bus collision
    //send the I2C slave address (force the R/W bit high)
    if (I2C_Sendbyte(slave_address | 0x01))
    {
        I2C_Stop(); //if address was NAKed, terminate the cycle
        return 2;   //and return error code
    }
    //receive the data.
    for (; buflen>0; --buflen)
    {
        unsigned char ackflag = (buflen == 1);   //1 if this is the last byte to receive => send NAK

        *bufptr++ = I2C_Recvbyte(ackflag);
    }
    I2C_Stop();
    return 0;   //no error
}
const unsigned char EEPROM_data[] =
{
    0x07,   // Count 7
    0x06,   // Count 6
    0x05,   // Count 5
    0x04,   // Count 4
    0x03,   // Count 3
    0x02,   // Count 2
    0x01,   // Count 1
};
unsigned char rd_buf[7];

// Test variable for one byte transfer
const unsigned char testchar = 'A';
unsigned char testchar_readback[17];  // init to this to see difference after read

void main(void)
{
     unsigned char i = 0;

     unsigned char Data1 [10]="tst ";

     Port_Initialized ();
     LCD_Initialized();
     I2C_Initialized();
     LCD_Data(Data1);

    // Write test buffer
     Result1 = EEPROM_Write(EEPROM_ADDRESS , Word_Address1 , sizeof(EEPROM_data), EEPROM_data);
     __delay_ms(10);

    // Read test buffer back
     Result2 = EEPROM_Read(EEPROM_ADDRESS, Word_Address1 , sizeof(rd_buf), rd_buf) ;
     __delay_ms(10);


     // Read back ONE number from 0x01
     Result4 = EEPROM_Read(EEPROM_ADDRESS, 0x01 , 1, rd_buf);
    __delay_ms(10);

    while (1)
    {
      
        Data1[0] = ((rd_buf[1] >> 4) & 0x0f) + '0';
        Data1[1] = (rd_buf[1] & 0x0f) + '0';
        LCD_Data(Data1);
    }
      
}
When I ran code I see 06t on LCD but I wonder I should get 1

1622543688884.png
 

hexreader

Joined Apr 16, 2011
619
I think you have a hardware problem with your RS232 communication. Follow instructions in post #221 and report.

When EEPROM is connected, my LCD shows 06t 8 times, exactly the same as yours.
When EEPROM is disconnected, my LCD shows 00t 8 times
 

hexreader

Joined Apr 16, 2011
619
I made minor changes to your LCD/EEPROM code above...

Code:
/*
* File:   main.c
* Author: Djsarkar
*
* Created on May 31, 2021, 8:08 PM
*/


//
#define _XTAL_FREQ 20000000     // crystal 20MHz

// 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)
// SOSCSEL = No Setting
#pragma config XINST = OFF      // Extended Instruction Set (Disabled)
// CONFIG1H
#pragma config FOSC = HS2       // HS oscillator (high power, 16 MHz-25 MHz
#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 = ON         // Code Protect 00800-01FFF (Enabled)
#pragma config CP1 = ON         // Code Protect 02000-03FFF (Enabled)
#pragma config CP2 = ON         // Code Protect 04000-05FFF (Enabled)
#pragma config CP3 = ON         // Code Protect 06000-07FFF (Enabled)
// CONFIG5H
#pragma config CPB = ON         // Code Protect Boot (Enabled)
#pragma config CPD = ON         // Data EE Read Protect (Enabled)
// CONFIG6L
#pragma config WRT0 = ON        // Table Write Protect 00800-01FFF (Enabled)
#pragma config WRT1 = ON        // Table Write Protect 02000-03FFF (Enabled)
#pragma config WRT2 = ON        // Table Write Protect 04000-05FFF (Enabled)
#pragma config WRT3 = ON        // Table Write Protect 06000-07FFF (Enabled)
// CONFIG6H
#pragma config WRTC = ON        // Config. Write Protect (Enabled)
#pragma config WRTB = ON        // Table Write Protect Boot (Enabled)
#pragma config WRTD = ON        // Data EE Write Protect (Enabled)
// CONFIG7L
#pragma config EBTR0 = ON       // Table Read Protect 00800-01FFF (Enabled)
#pragma config EBTR1 = ON       // Table Read Protect 02000-03FFF (Enabled)
#pragma config EBTR2 = ON       // Table Read Protect 04000-05FFF (Enabled)
#pragma config EBTR3 = ON       // Table Read Protect 06000-07FFF (Enabled)
// CONFIG7H
#pragma config EBTRB = ON       // Table Read Protect Boot (Enabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#pragma warning disable 520

#include <xc.h>

unsigned char Result1;
unsigned char Result2;
unsigned char Result3;
unsigned char Result4;

// The code should set the R/W bit according to its function
#define EEPROM_ADDRESS      0xA0         //I2C slave address of 24c02 (8 bit format)
#define Word_Address1       0x00


#define LCD_RS              LATBbits.LATB3
#define LCD_TRIS_RS         TRISBbits.TRISB3
#define LCD_RW              LATBbits.LATB4
#define LCD_TRIS_RW         TRISBbits.TRISB4
#define LCD_E               LATBbits.LATB5
#define LCD_TRIS_E          TRISBbits.TRISB5

#define  LCDPORT            LATD
#define  LCDTRISD           LATD

void Port_Initialized (void);
void WriteNibble(unsigned char command);
void WaitLCDBusy(void);
void WriteCommand(unsigned char command);

void Port_Initialized (void)
{
// LATx registers
    LATA =  0x00;
    LATB =  0x00;
    LATC =  0x00;
    LATD =  0x00;
    LATE =  0x00;

//  TRISx registers
    TRISA = 0x00;      // All are output, Unused
    TRISB = 0x00;      // all are output, Unused
    TRISC = 0x18;      // Slave SDA and CLOCK
    TRISD = 0x00;      // LCD
    TRISE = 0x00;      // All are output, Unused

    ANCON0 = 0x00;     // set to digital port
    ANCON1 = 0x00;     // Set to digital port
    CM1CON = 0x00;     // Comparator off
    CM2CON = 0x00;     // Comparator off
    ADCON0 = 0x00;     // A/D conversion Disabled
    ADCON1 = 0x00;     // A/D conversion Disabled
    ADCON2 = 0x00;     // A/D conversion Disabled
}

// Wait for 5 ms
void WaitLCDBusy(void)
{
    __delay_ms(5);
}

//Send a command to the LCD
void WriteCommand(unsigned char command)
{
    WaitLCDBusy();                        //wait until not busy
    LCD_RS = 0;                           //setup to send command
    WriteNibble(command);                 //write the high nibble
    WriteNibble( (unsigned char)(command<<4) ); //then the low nibble
}

//Initialized  LCD
void LCD_Initialized()
{
    LCDTRISD &=0x0f;                //ensure data bits are output
    LCD_E=0;                        //clear enable
    LCD_RS = 0;                     //going to write command
    LCD_TRIS_E=0;                   //Set enable to output
    LCD_TRIS_RS=0;                  //set RS to output
    LCD_TRIS_RW=0;
    LCD_RW=0;
    __delay_ms(30);                 //delay for LCD to initialise.
    WriteNibble(0x30);              //Required for initialisation
    __delay_ms(5);                  //required delay
    WriteNibble(0x30);              //Required for initialisation
    __delay_ms(1);                  //required delay
    WriteCommand(0x20);             //set to 4 bit interface
    WriteCommand(0x2c);             //set to 4 bit interface, 2 line and 5*10 font
    WriteCommand(0x01);             //clear display
    WriteCommand(0x06);             //move cursor right after write
    WriteCommand(0x0C);             //turn on display
}

//Send a character to the LCD
void WriteChar(unsigned char chr)
{
    WaitLCDBusy();                         //wait until not busy
    LCD_RS=1;                              //Setup to send character
    WriteNibble(chr);                      //write the high nibble        
    WriteNibble( (unsigned char)(chr<<4)); //then the low nibble
}

//Send any 4 bits to the LCD
void WriteNibble(unsigned char command)
{
    LCDPORT &= 0x0f;                        //clear the data bits
    LCDPORT|=((command & 0xf0));            //or in the new data
    LCD_E = 1;                              //enable the LCD interface
    NOP();                                  // delay of 1uS
    NOP();
    NOP();
    LCD_E = 0;                              //disable it
}

void LCD_Data( unsigned char *string)
{
    while (*string != '\0')
    {
      WriteChar(*string);
        string++;
    }
}

//Initialize I2C in master mode
void I2C_Initialized(void)
{
    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
__bit I2C_Start(void)
{
    BCLIF = 0;  //Clear 'Bus collision" flag
    SEN = 1;    //initiate a START cycle
    while (SEN);    //wait until it has been sent
    return BCLIF;   //return value of BCLIF flag
}
// Send an I2C STOP
void I2C_Stop(void)
{
    PEN = 1;    //initiate a STOP cycle
    while (PEN);    //wait until it has been sent
}

// Send an I2C REPEATED START
void I2C_Restart(void)
{
    RSEN = 1;    //initiate a REPEATED START cycle
    while (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
__bit I2C_Sendbyte(unsigned char dat)
{
    SSPBUF = dat;

    asm("nop");     // wait a little for R_W to be set

    while (R_W);    //wait until byte sent and ACK/NAK received
    return ACKSTAT;
}

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

//Send an array of data to an I2C device.
//Return 0 if all OK, 1 if bus error, 2 if slave address NAK, 3 if slave register NAK, 4 if slave data NAK
unsigned char EEPROM_Write(unsigned char slave_address, unsigned char start_reg, unsigned char buflen, const unsigned char * bufptr)
{
    if (I2C_Start() )   //send a start, and check if it succeeded
        return 1;   //abort if bus collision
    //send the I2C slave address (force R/W bit low)
    if (I2C_Sendbyte(slave_address & 0xfe))  // <<---- Added AND to force R/W- low.
    {
        I2C_Stop(); //if address was NAKed, terminate the cycle
        return 2;   //and return error code
    }
    //send the device register index
    if (I2C_Sendbyte(start_reg))
    {
        I2C_Stop(); //if register was NAKed, terminate the cycle
        return 3;   //and return error code
    }
    //send the data. buflen might be zero!
    for (; buflen>0; --buflen)
    {
        if (I2C_Sendbyte(*bufptr++))
        {
            I2C_Stop(); //if register was NAKed, terminate the cycle
            return 4;   //and return error code
        }
    }
    I2C_Stop();
    return 0;   //no error
}

//Receive an array of data from an I2C device.
//Return 0 if all OK, 1 if bus error, 2 if slave address NAK, 3 if slave register NAK
unsigned char EEPROM_Read(unsigned char slave_address, unsigned char start_reg, unsigned char buflen, unsigned char * bufptr)
{
    //do a dummy zero length write cycle to set the register address
    unsigned char retval = EEPROM_Write(slave_address, start_reg, 0, 0);
    if (retval)
    {
        return retval;  //abort if there was an error
    }
    //now start the READ cycle
    if (I2C_Start() )   //send a start, and check if it succeeded
        return 1;   //abort if bus collision
    //send the I2C slave address (force the R/W bit high)
    if (I2C_Sendbyte(slave_address | 0x01))
    {
        I2C_Stop(); //if address was NAKed, terminate the cycle
        return 2;   //and return error code
    }
    //receive the data.
    for (; buflen>0; --buflen)
    {
        unsigned char ackflag = (buflen == 1);   //1 if this is the last byte to receive => send NAK

        *bufptr++ = I2C_Recvbyte(ackflag);
    }
    I2C_Stop();
    return 0;   //no error
}
const unsigned char EEPROM_data[] =
{
    0x07,   // Count 7
    0x06,   // Count 6
    0x05,   // Count 5
    0x04,   // Count 4
    0x03,   // Count 3
    0x02,   // Count 2
    0x01,   // Count 1
};
unsigned char rd_buf[7];

// Test variable for one byte transfer
const unsigned char testchar = 'A';
unsigned char testchar_readback[17];  // init to this to see difference after read

void main(void)
{
     unsigned char i = 0;

     unsigned char Data1 [10]="xx";

     Port_Initialized ();
     LCD_Initialized();
     I2C_Initialized();
     //LCD_Data(Data1);

    // Write test buffer
     Result1 = EEPROM_Write(EEPROM_ADDRESS , Word_Address1 , sizeof(EEPROM_data), EEPROM_data);
     __delay_ms(10);

    // Read test buffer back
     Result2 = EEPROM_Read(EEPROM_ADDRESS, Word_Address1 , sizeof(rd_buf), rd_buf) ;
     __delay_ms(10);


     // Read back ONE number from 0x01
     Result4 = EEPROM_Read(EEPROM_ADDRESS, 0x00 , 8, rd_buf);                   // read first 8 bytes of EEPROM data
    __delay_ms(10);

    for (i = 0; i < 8; i++)                                                     // output buffer contents address 0 to 7
    {
        Data1[0] = ((rd_buf[i] >> 4) & 0x0f) + '0';                             // hex conversion - high nibble
        Data1[1] = (rd_buf[i] & 0x0f) + '0';                                    // hex conversion - low nibble
        LCD_Data(Data1);
    }
    LCD_Data("                        EEPROM Contents");                        // this is the dumbest way EVER to write to LCD
    while(1); 
}
 
Last edited:

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
@JohnInTX and @hexreader
I've some issue with ESUART program

When I ran below code I see the text "Hello" continuously on terminal. In this case I don't need to reset the power to see the text

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 = 0xFF;
    TRISC = 0x80;
    TRISD = 0xFF;
    /**
    ANSELx registers
    */
    ANCON0 = 0x00;
    ANCON1 = 0x00;
 
    
}
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();
}
void send(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(*p); 
     p++;
   }
}
void main(void)
{
    char message[]= {"Hello "};
    SYSTEM_Initialize();
 
    while (1)
    {
     __delay_ms(5);
     string(message);
    }
  
    return;
}
I want to see the text only once so I change below part of code but the problem is I don't see text on terminal until I reset board.

C:
void main(void)
{
    char message[]= {"Hello G  "};
    SYSTEM_Initialize();
     __delay_ms(5);
     string(message);
    while (1)
    {

    }
  
    return;
}
What's wrong with code ? Why doesn't text show on terminal without resetting power ? Why it's happening text show only after resetting the power ?
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
The message is sent only once after board power up. Maybe your terminal is not ready to receive it so quickly. Try to make delay bigger (say 2000 ms instead of 5 ms) before sending the message.
@trebla Thank you
I tried 2000ms but still terminal not showing message I also tried bigger 5000ms delay but I have same issue
 

trebla

Joined Jun 29, 2019
599
Try to activate message sending process with a button press instead of delay:
while (button != PRESSED) ;
string(message);

I don't know your board schematics and button press level (high or low) so you must determine which button to use and which level to detect :)
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
Try to activate message sending process with a button press instead of delay:
while (button != PRESSED) ;
string(message);

I don't know your board schematics and button press level (high or low) so you must determine which button to use and which level to detect :)
Button connection
https://forum.allaboutcircuits.com/threads/pic-development-board-with-pk3.172494/page-2#post-1553836

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 = 0x80;
    TRISD = 0xFF;
    /**
    ANSELx registers
    */
    ANCON0 = 0x00;
    ANCON1 = 0x00;
 
    
}
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();
}
void send(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(*p); 
     p++;
   }
}
void main(void)
{
    char message[]= {"Hello1"};
    SYSTEM_Initialize();
  
    if (PORTBbits.RB0 != 1)
    {
         string(message);
    }
    
    while (1)
    {

    }
  
    return;
}
I've done test as you said but still I don't see the text on terminal
 

trebla

Joined Jun 29, 2019
599
Describe how do you operate with this rig:
1. when you connect terminal
2. when you apply power to the board
3. when you press the button
Btw, after initializing EUSART is good point to put in a small delay, maybe max 100 ms
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
Describe how do you operate with this rig:
1. when you connect terminal
2. when you apply power to the board
3. when you press the button
Btw, after initializing EUSART is good point to put in a small delay, maybe max 100 ms
I've tried two way's

  1. First I power on the board then I connect pick kit 3 to laptop. after that I run the program. when program is successfully verified then I connect the hyper terminal and then I press button

  • First I power on the board then I connect pick kit 3 to laptop. then I connect the hyper terminal to laptop then I run the program. when program is successfully verified and then I press button
 

hexreader

Joined Apr 16, 2011
619
Your button code in post #236 is no good.

Do you want the fixed code, or do you want to work out the logic error for yourself?

Hint - comment your button code - it might help you to think about where your error in thinking is.
 

Thread Starter

Djsarakar

Joined Jul 26, 2020
489
As this message appears on startup only once, the sequence must be:
Your button code in post #236 is no good.
Program to check serial communication

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 = 0x80;
    TRISD = 0xFF;
    /**
    ANSELx registers
    */
    ANCON0 = 0x00;
    ANCON1 = 0x00;

  
}
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();
}
void send(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(*p);
     p++;
   }
}
void main(void)
{
    char message[]= {"Hello1"};
    SYSTEM_Initialize();

    while (BUTTON != 1); // Button not  PRESSED)
  
    string(message);
  
    while (1)
    {

    }

    return;
}
I'm getting Hello1 when I press button but I don't know why so many question mark ? shows at beginning

1622640485880.png
 
Top