#pragma config FEXTOSC = OFF // External Oscillator Selection (Oscillator not enabled)
#pragma config RSTOSC = HFINTOSC_64MHZ// Reset Oscillator Selection (HFINTOSC with HFFRQ = 64 MHz and CDIV = 1:1)
// CONFIG1H
#pragma config CLKOUTEN = OFF // Clock out Enable bit (CLKOUT function is disabled)
#pragma config PR1WAY = ON // PRLOCKED One-Way Set Enable bit (PRLOCK bit can be cleared and set only once)
#pragma config CSWEN = ON // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)
// CONFIG2L
#pragma config MCLRE = EXTMCLR // MCLR Enable bit (If LVP = 0, MCLR pin function is port defined function; If LVP =1, RE3 pin fuction is MCLR)
#pragma config PWRTS = PWRT_OFF // Power-up timer selection bits (PWRT is disabled)
#pragma config MVECEN = ON // Multi-vector enable bit (Multi-vector enabled, Vector table used for interrupts)
#pragma config IVT1WAY = ON // IVTLOCK bit One-way set enable bit (IVTLOCK bit can be cleared and set only once)
#pragma config LPBOREN = OFF // Low Power BOR Enable bit (ULPBOR disabled)
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled , SBOREN bit is ignored)
// CONFIG2H
#pragma config BORV = VBOR_2P45 // Brown-out Reset Voltage Selection bits (Brown-out Reset Voltage (VBOR) set to 2.45V)
#pragma config ZCD = OFF // ZCD Disable bit (ZCD disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON)
#pragma config PPS1WAY = ON // PPSLOCK bit One-Way Set Enable bit (PPSLOCK bit can be cleared and set only once; PPS registers remain locked after one clear/set cycle)
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config DEBUG = OFF // Debugger Enable bit (Background debugger disabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Extended Instruction Set and Indexed Addressing Mode disabled)
// CONFIG3L
#pragma config WDTCPS = WDTCPS_31// WDT Period selection bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = OFF // WDT operating mode (WDT Disabled; SWDTEN is ignored)
// CONFIG3H
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC // WDT input clock selector (Software Control)
// CONFIG4L
#pragma config BBSIZE = BBSIZE_512// Boot Block Size selection bits (Boot Block size is 512 words)
#pragma config BBEN = OFF // Boot Block enable bit (Boot block disabled)
#pragma config SAFEN = OFF // Storage Area Flash enable bit (SAF disabled)
#pragma config WRTAPP = OFF // Application Block write protection bit (Application Block not write protected)
// CONFIG4H
#pragma config WRTB = OFF // Configuration Register Write Protection bit (Configuration registers (300000-30000Bh) not write-protected)
#pragma config WRTC = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
#pragma config WRTSAF = OFF // SAF Write protection bit (SAF not Write Protected)
#pragma config LVP = ON // Low Voltage Programming Enable bit (Low voltage programming enabled. MCLR/VPP pin function is MCLR. MCLRE configuration bit is ignored)
// CONFIG5L
#pragma config CP = OFF // PFM and Data EEPROM Code Protection bit (PFM and Data EEPROM code protection disabled)
#include <xc.h>
#include <string.h>
#include <stdlib.h>
#define _XTAL_FREQ 64000000
void OSC_init(){
OSCFRQ=0x08; // 8=64 Mhz----0=1Mhz
}
void IO_init(){
ANSELA=0; // all digital
ANSELB=0; // all digital
ANSELC=0; // all digital
TRISBbits.TRISB5=0; // led
TRISBbits.TRISB4=0; // U1TX
TRISBbits.TRISB3=1; // U1RX
LATBbits.LATB5=1; // Turns the led on
}
void PPS_init(){
RB4PPS=0x13; // RB4 = UART1 TX.
U1RXPPS=0x0B; // RB3 = UART1 RX
}
void UART_init(){
U1BRG=207; // SET BAUD OF 19200 for 64Mhz Fosc.
//U1CON0
U1BRGS=0; // Baud speed clock / bits
U1ABDEN=0; // en auto baud
U1TXEN=1; // TX enable
U1RXEN=1; // RX enable
U1CON0bits.MODE=0;// 8,N,1 mode
//U1CON1
U1ON=1; // U1 serial port enabled
U1WUE=0; // Wake up bit enable
U1RXBIMD=0; // RX break int mode
U1BRKOVR=0; // Break override
U1SENDB=0; // send break
//
//U1CON2
U1RUNOVF=0; // Run in overflow
U1RXPOL=0; // RX polarity
U1CON2bits.STP=0; // =1 Stop bit,
U1C0EN=0; // Check sum mode bits
U1TXPOL=0; // TX polarity
U1CON2bits.FLO=0; // Flow ctrl off
//
U1ERRIR=0x00; // error flags
//
// U1ERRIE // UART1 INTERRUPT ENABLE
U1TXMTIE=0; // TX empty
U1PERIE=0; // Parity err
U1ABDOVE=0; // Auto baud detect
U1CERIE=0; // Check sum err
U1FERIE=0; // Frame err
U1RXBKIE=0; // Break received
U1RXFOIE=0; // FIFO overflow
U1TXCIE=0; // TX collision
PIE3bits.U1RXIE=0; //RX interrrupt enable
PIE3bits.U1TXIE=0; //TX interrrupt enable
PIE3bits.U1EIE=0; //Frame err interrrupt enable
PIE3bits.U1IE=0; //UART1 interrrupt enable
}
void serial_print(unsigned char *Pline,int nl)
{
int x = 0;
for ( x = 0; Pline[x]!=0x00 ; x++)
{
while (U1TXMTIF == 0) {}
U1TXB = Pline[x];
}
while (U1TXMTIF == 0 ) {}
if(nl) U1TXB = 0x0D ; // new line
}
int main(void) {
OSC_init();
IO_init();
PPS_init();
UART_init();
__delay_ms(100);
serial_print(" The answer to Life the Universe and Everything ? ",1);
serial_print("= K42 ",0);
while(1){}
return ;
}
// CONFIG1L
#pragma config FEXTOSC = HS // External Oscillator Selection (HS (crystal oscillator) above 8 MHz; PFM set to high power)
#pragma config RSTOSC = EXTOSC_4PLL// Reset Oscillator Selection (EXTOSC with 4x PLL, with EXTOSC operating per FEXTOSC bits)
// CONFIG1H
#pragma config CLKOUTEN = OFF // Clock out Enable bit (CLKOUT function is disabled)
#pragma config PR1WAY = ON // PRLOCKED One-Way Set Enable bit (PRLOCK bit can be cleared and set only once)
#pragma config CSWEN = ON // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)
// CONFIG2L
#pragma config MCLRE = EXTMCLR // MCLR Enable bit (If LVP = 0, MCLR pin is MCLR; If LVP = 1, RE3 pin function is MCLR )
#pragma config PWRTS = PWRT_OFF // Power-up timer selection bits (PWRT is disabled)
#pragma config MVECEN = ON // Multi-vector enable bit (Multi-vector enabled, Vector table used for interrupts)
#pragma config IVT1WAY = ON // IVTLOCK bit One-way set enable bit (IVTLOCK bit can be cleared and set only once)
#pragma config LPBOREN = OFF // Low Power BOR Enable bit (ULPBOR disabled)
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled , SBOREN bit is ignored)
// CONFIG2H
#pragma config BORV = VBOR_2P45 // Brown-out Reset Voltage Selection bits (Brown-out Reset Voltage (VBOR) set to 2.45V)
#pragma config ZCD = OFF // ZCD Disable bit (ZCD disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON)
#pragma config PPS1WAY = ON // PPSLOCK bit One-Way Set Enable bit (PPSLOCK bit can be cleared and set only once; PPS registers remain locked after one clear/set cycle)
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config DEBUG = OFF // Debugger Enable bit (Background debugger disabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Extended Instruction Set and Indexed Addressing Mode disabled)
// CONFIG3L
#pragma config WDTCPS = WDTCPS_31// WDT Period selection bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = OFF // WDT operating mode (WDT Disabled; SWDTEN is ignored)
// CONFIG3H
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC // WDT input clock selector (Software Control)
// CONFIG4L
#pragma config BBSIZE = BBSIZE_512// Boot Block Size selection bits (Boot Block size is 512 words)
#pragma config BBEN = OFF // Boot Block enable bit (Boot block disabled)
#pragma config SAFEN = OFF // Storage Area Flash enable bit (SAF disabled)
#pragma config WRTAPP = OFF // Application Block write protection bit (Application Block not write protected)
// CONFIG4H
#pragma config WRTB = OFF // Configuration Register Write Protection bit (Configuration registers (300000-30000Bh) not write-protected)
#pragma config WRTC = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
#pragma config WRTSAF = OFF // SAF Write protection bit (SAF not Write Protected)
#pragma config LVP = ON // Low Voltage Programming Enable bit (Low voltage programming enabled. MCLR/VPP pin function is MCLR. MCLRE configuration bit is ignored)
// CONFIG5L
#pragma config CP = OFF // PFM and Data EEPROM Code Protection bit (PFM and Data EEPROM code protection disabled)
// CONFIG5H
#include <xc.h>
#include <PIC18F26K42.h>
volatile int t = 0;
void init(){
TRISB = 0x7E; //B7 as output
LATB = 0x80;
T2CLK = 0x01; //clock source = Fosc/4, Fosc = 32MHz = 8MHz*4xPLL
//T2HLT = 0x00; //rising edge triggered, free running with software gate
T2CON = 0x60; //T2 off, /64 prescaler, 1:1 postcaler (125KHz)
T2PR = 125; //125KHz/125=1KHz or 1ms delay
T2TMR=0; //clear TMR2 counter
TMR2IF = 0; //clear TMR2 interrupt flag
GIE = 1; //global interrupts enabled
TMR2IE = 1; //T2 interrupt enabled
}
void delay_millis(int time){
t=time;
T2TMR=0;
T2ON=1;
while(t>0);
T2ON=0;
}
void main(void) {
init();
while(1){
delay_millis(1000);
LATB ^= 0x80;
}
return;
}
void __interrupt (irq(IRQ_TMR2)) TMR2_ISR(void){
TMR2IF = 0;
t--;
}
void I2C_init(){ // ---7---|---6---|---5---|---4---|---3---|---2---|---1---|---0---|
// -- -- -- -- -- BTO<2:0>
I2C1BTO =0; // 0 0 0 0 0 0 0 0
// -- -- -- -- -- CLK<2:0>
I2C1CLK =0x03; // 0 0 0 0 0 0 1 1
// CNTIE ACKTIE -- WRIE ADRIE PCIE RSCIE SCIE
I2C1PIE =0; // 0 0 0 0 0 0 0 0
// CNTIF ACKTIF WRIF ADRIF PCIF RSCIF SCIF
I2C1PIR =0; // 0 0 0 0 0 0 0 0
// -- BTOIF BCLIF NACKIF -- BTOIE BCLIE NACKIE
I2C1ERR =0; // 0 0 0 0 0 0 0 0
// BFRE SMA MMA R D -- -- --
I2C1STAT0 =0; // 0 0 0 0 0 0 0 0
// TXWE -- TXBE -- RXRE CLRBF -- RXBF
I2C1STAT1 =0; // 0 0 0 0 0 0 0 0
// EN RSEN S CSTR MDR MODE<2:0>
I2C1CON0 =0x04; // 0 0 0 0 0 1 0 0
// ACKCNT ACKDT ACKSTAT ACKT -- RXOV TXU CSD
I2C1CON1 =0x80; // 1 0 0 0 0 0 0 0
// ACNT GCEN FME ADB* SDAHT<3:2> BFRET<1:0>
I2C1CON2 =0x31; // 0 0 1 1 0 0 0 1
I2C1ADR0 =0; // ADR<7:0> *addr buf disabled
I2C1ADR1 =0; // ADR<7:1>
I2C1ADR2 =0; // ADR<7:0>
I2C1ADR3 =0; // ADR<7:1>
I2C1ADB0 =0; // ADB<7:0>
I2C1ADB1 =0; // ADB<7:0>
I2C1CNT =0; // CNT<7:0>
I2C1RXB =0; // RXB<7:0>
I2C1TXB =0; // TXB<7:0>
I2C1CON0bits.EN = 1; // enable I2C module
}
void IO_init(){
ANSELA=0; // all digital
ANSELB=0; // all digital
ANSELC=0; // all digital
TRISBbits.TRISB5=0;
LATBbits.LATB5=1; //led on
// Configure the pins as Open-drain
ODCONCbits.ODCC3 = 1;
ODCONCbits.ODCC4 = 1;
// Set the I2C levels
RC3I2Cbits.TH = 1;
RC4I2Cbits.TH = 1;
// Configure the pins as Outputs
TRISCbits.TRISC3 = 0;
TRISCbits.TRISC4 = 0;
}
void PPS_init(){ // do PPS before IO_init();
//UART1
RB4PPS=0x13; // RB4 = UART1 TX.
U1RXPPS=0x0B; // RB3 = UART1 RX
// Set RC4 for SDA1
RC4PPS = 0x22;
I2C1SDAPPS = 0x14;
// Set RC3 for SCL1
RC3PPS = 0x21;
I2C1SCLPPS = 0x13;
}
void LCD_init()
{
unsigned int x;
I2C1CNT=0x08; // load I2C1CNT with number of INIT bytes
I2C1TXB = 0x7C; // load addr
I2C1CON0bits.S=1; // set start
for(x=0;x<8;x++){
while(!I2C1STAT1bits.TXBE){} // wait for buffer empty
I2C1TXB = LCD_init_data[x];
}
__delay_ms(200);
}
void send_I2C_lcd(char *message, unsigned char Lpos) // send message at line + location
{
LCD_loc(Lpos) ;
unsigned int x;
unsigned int sendlen;
sendlen= strlen(message);
I2C1CNT=sendlen + 1; // load I2C1CNT with number of bytes
I2C1TXB=0x7C; // load I2C1TXB with device address
I2C1CON0bits.S=1; // set start
while (!I2C1STAT1bits.TXBE); // wait for buffer empty
I2C1TXB = 0x40; // load control byte
for(x=0;x<sendlen;x++){
while (!I2C1STAT1bits.TXBE); // wait for buffer empty
I2C1TXB = message[x]; // load next message byte
__delay_ms(1);
}
}
void LCD_loc(unsigned char Lpos) // line 1 0x80 to 0x8F
{ // line 2 0xC0 to 0xCF
unsigned int x;
I2C1CNT=0x02; // load I2C1CNT with number of bytes
I2C1TXB=0x7C; // load I2C1TXB with device address
I2C1CON0bits.S=1; // set start
while (!I2C1STAT1bits.TXBE); // wait for buffer empty
I2C1TXB = 0x00; // load next byte
while (!I2C1STAT1bits.TXBE); // wait for buffer empty
I2C1TXB = Lpos; // load next byte
__delay_ms(1);
}
void __interrupt(irq(IRQ_U1RX)) U1RX_ISR()
{
LATBbits.LATB5=1; //led on
Serial_in=1; // flag main to send to lcd
byte_in=U1RXB; / get the byte
PIR3bits.U1RXIF = 0; // Clear the interrupt flag
}
void __interrupt(irq(default)) DEFAULT_ISR()
{
while(1); // Unhandled interrupts go here
}
void INTERRUPT_Initialize(void)
{
INTCON0bits.GIEH=1; // Global int enable
INTCON0bits.GIEL=0; //
INTCON0bits.IPEN=0; // Interrupt priority not used
PIE3bits.U1RXIE=1; // Enable U1RX INTERRUPT
IPR3bits.U1RXIP=0; //
IVTBASEU=0x00; // default 0x000008
IVTBASEH=0x00; //
IVTBASEL=0x08; //
}
...seems you cannot clear the U1RX interrupt flag without first reading the receive buffer , then it all behaves as it should lag...
// info
//char RTC_I[]={0x00,0x00,0x38,0x15,0x04,0x18,0x10,0x17,0x10};
//Ds1338 start-reg sec min hrs day# Day Mth Year out
void RTC_get_DateTime(char *Time_date)
{
unsigned int x;
I2C1CNT=0x01; // load I2C1CNT with number of bytes
I2C1ADB1 = 0xD0; //RTC_write; // load addr
I2C1TXB = 0x00; // write 0x00 start addr and tx byte
while(!I2C1PIRbits.PCIF); // WAIT FOR STOP.
I2C1CNT=0x08; // load I2C1CNT with number of bytes
I2C1ADB1= 0xD1; // RTC_read; // load addr
I2C1CON0bits.S=1; // set start
for(x=0;x<8;x++){ // loop while reading
while(!I2C1STAT1bits.RXBF); // RX test
*Time_date = I2C1RXB; // update data
Time_date++; // advance pointer
}
}
{
// fast mode , address buffer enabled , T2 is bus timeout
void I2C_init(){ // ---7---|---6---|---5---|---4---|---3---|---2---|---1---|---0---|
// -- -- -- -- -- BTO<2:0>
I2C1BTO =0x01; // 0 0 0 0 0 0 0 1
// -- -- -- -- -- CLK<2:0>
I2C1CLK =0x03; // 0 0 0 0 0 0 1 1
// CNTIE ACKTIE -- WRIE ADRIE PCIE RSCIE SCIE
I2C1PIE =0; // 0 0 0 0 0 0 0 0
// CNTIF ACKTIF WRIF ADRIF PCIF RSCIF SCIF
I2C1PIR =0; // 0 0 0 0 0 0 0 0
// -- BTOIF BCLIF NACKIF -- BTOIE BCLIE NACKIE
I2C1ERR =0; // 0 0 0 0 0 0 0 0
// BFRE SMA MMA R D -- -- --
I2C1STAT0 =0; // 0 0 0 0 0 0 0 0
// TXWE -- TXBE -- RXRE CLRBF -- RXBF
I2C1STAT1 =0; // 0 0 0 0 0 0 0 0
// EN RSEN S CSTR MDR MODE<2:0>
I2C1CON0 =0x04; // 0 0 0 0 0 1 0 0
// ACKCNT ACKDT ACKSTAT ACKT -- RXOV TXU CSD
I2C1CON1 =0x80; // 1 0 0 0 0 0 0 0
// ACNT GCEN FME ADB* SDAHT<3:2> BFRET<1:0>
I2C1CON2 =0x21; // 0 0 1 0 0 0 0 1
I2C1ADR0 =0; // ADR<7:0> *enabled
I2C1ADR1 =0; // ADR<7:1>
I2C1ADR2 =0; // ADR<7:0>
I2C1ADR3 =0; // ADR<7:1>
I2C1ADB0 =0; // ADB<7:0>
I2C1ADB1 =0; // ADB<7:0>
I2C1CNT =0; // CNT<7:0>
I2C1RXB =0; // RXB<7:0>
I2C1TXB =0; // TXB<7:0>
I2C1CON0bits.EN = 1; // enable I2C module
}
void LCD_init()
{
unsigned int x;
I2C1ADB1 = 0x7C; // load addr 7c
I2C1CNT=0x08; // load I2C1CNT with number of INIT bytes
for(x=0;x<8;x++){
I2C1TXB = LCD_init_data[x]; // send data
while(!I2C1STAT1bits.TXBE); // wait for buffer empty
}
while(!I2C1PIRbits.PCIF); // WAIT FOR STOP.
__delay_ms(100);
}
void DS1338_init()
{
unsigned int x;
I2C1CNT=0x09; // load I2C1CNT with number of INIT bytes
I2C1ADB1 = 0xD0; // load addr 7c
for(x=0;x<9;x++){
I2C1TXB = RTC_I[x];
while(!I2C1STAT1bits.TXBE); // wait for buffer empty
}
while(!I2C1PIRbits.PCIF); // WAIT FOR STOP.
__delay_ms(1);
}
void send_I2C_lcd(char *message,unsigned char Lpos) /// send message at line + location
{
LCD_loc(Lpos);
unsigned int x;
unsigned int sendlen;
sendlen= strlen(message);
I2C1ADB1=0x7C; // load I2C1TXB with device address
I2C1CNT=sendlen + 1; // load I2C1CNT with number of bytes
while (!I2C1STAT1bits.TXBE); // wait for buffer empty
I2C1TXB = 0x40; // load control byte
for(x=0;x<sendlen;x++){
while (!I2C1STAT1bits.TXBE); // wait for buffer empty
I2C1TXB = message[x]; // load next message byte
}
while(!I2C1PIRbits.PCIF); // WAIT FOR STOP.
__delay_ms(1);
}
void LCD_loc(unsigned char Lpos) // line 1 0x80 to 0x8F
{ // line 2 0xC0 to 0xCF
unsigned int x;
I2C1ADB1=0x7C; // load I2C1TXB with device address
I2C1CNT=0x02; // load I2C1CNT with number of bytes
while (!I2C1STAT1bits.TXBE); // wait for buffer empty
I2C1TXB = 0x00; // load next byte
while (!I2C1STAT1bits.TXBE); // wait for buffer empty
I2C1TXB = Lpos; // load next byte
__delay_ms(1);
}
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?