// 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;
}
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
@hexreader your code is not working on my board When I type command I don't see anything on terminalJust 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.
/*
* 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);
}
}

/*
* 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);
}
#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;
}
void main(void)
{
char message[]= {"Hello G "};
SYSTEM_Initialize();
__delay_ms(5);
string(message);
while (1)
{
}
return;
}
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.problem is I don't see text on terminal until I reset board
@trebla Thank youThe 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.
Button connectionTry 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![]()
#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 tried two way'sDescribe 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
As this message appears on startup only once, the sequence must be:
Program to check serial communicationYour button code in post #236 is no good.
#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;
}

This may be some random data in recieve buffer, due the EUSART setup process or during connecting serial cable.I don't know why so many question mark ? shows at beginning