Version:0.9 StartHTML:0000000105 EndHTML:0000109235 StartFragment:0000001499 EndFragment:0000109219 mikroIDE
 
 
#define Version "190220"
 /*
 
 P18F27K42_at_64Mhz.cfgsch
 
CONFIG1L : $300000 : 0x0004
CONFIG1H : $300001 : 0x0009
CONFIG2L : $300002 : 0x0027
CONFIG2H : $300003 : 0x00A7
CONFIG3L : $300004 : 0x000B
CONFIG3H : $300005 : 0x003F
CONFIG4L : $300006 : 0x009F
CONFIG4H : $300007 : 0x000F
CONFIG5L : $300008 : 0x0001
CONFIG5H : $300009 : 0x0000


*/


 // datasheet 807 pages
//#define Version "190130"
// mikroC version 7.30 beta
// 18F27K42  mis sur circuit imprimé Horloge 60 leds à la place du Pic 18F26K22


  //  ac:pinout

 // Hardware
 /*
 Pin 28  RB7  --x  x----ICSP Data
 Pin 27  RB6  --x  x-----ICSP Clock
 Pin 26  RB5
 Pin 25  RB4
 Pin 24  RB3
 Pin 23  RB2
 Pin 22  RB1
 Pin 21  RB0
 Pin 20      VDD --------+5V
 Pin 19      Vss ---------Gnd          fil noir cable prolific
 Pin 18  RC7  RX UART  <-- Keyboard    fil Vert cable prolific
 Pin 17  RC6  TX UART  --> Display     fil Blanc cable prolific
 Pin 16  RC5

 Pin 15  RC4  SDA  I2C
 Pin 14  RC3  SCL  I2C

 Pin 13  RC2
 Pin 12  RC1
 Pin 11  RC0

 Pin 10  RA6
 Pin  9  RA7
 Pin  8  VSS ---------  Gnd
 Pin  7  RA5  ----> Led
 Pin  6  RA4  -----> led
 Pin  5  RA3
 Pin  4  RA2
 Pin  3  RA1
 Pin  2  RA0  <---- Analog Input
 Pin  1  RE3 MCLR  Reset <--------ICSP PGRM
                          |----x  x----/0V   cavalier RESET
 */
#define Directory "C:\_MikroC\_MesProjets_MikroC\_18F27K42"
#define Project "PIC18F27K42_UART1_RTC_DS3231_I2C1_Hardw_Test.mcppi"
#define Source  "PIC18F27K42_UART1_RTC_DS3231_Hardw_I2C_Test"
//#define Annexe "Tiny_RTC_DS3231_HARDW_I2C1_for_K42.c"
#define Eeprom " not used ...."
#define Config " P18F27K42_at_64Mhz.cfgsch"


#define PROCESSOR "18F27K42"
#define POWER_SUPPLY  " 5V"

#define OSCILLATEUR_INTERNE
#define FOSC "64.0"  // MHz
#define LCD_ADR 0x3A        // adresse sur 7 bits au leu de 8 bits:0x74
#define NbCarPL 16


#define BAUD 115200  // UART1

#define CLS 12
#define CR 13    //0x0D
#define LF 10
#define TAB 9
#define BACK 8
#define Beep 7
#define Separator 0x20   // space
#define ON 0    // because led tirée au +VCC
#define OFF 1
#define SPECIAL 1
#define NORMAL 0

 // pin 1 circuit M948A-2  Melodie
#define STOP 0         //   Bit RB7=0  --> ULN   ---> 1  stop melodie
#define RING 128       //   Bit RB7=1  --> ULN -> 0  active melodie

#ifndef Byte
#define Byte unsigned char
#endif

#ifndef Word
#define Word unsigned int
#endif

#define RTC_DS3231
#define DS3231_ADDR 0x68   // I2C Hardware : sur 7 bits  RTC DS3231
//#define DS3231_ADDR 0xD0   //I2C Software :  sur 8 bits  RTC DS3231
 // I2C SDA sur RC4
 // I2C SCL sur RC3



const code char Jour0[]="Dimanche";
const code char Jour1[]="Lundi";
const code char Jour2[]="Mardi";
const code char Jour3[]="Mercredi.";
const code char Jour4[]="Jeudi";
const code char Jour5[]="Vendredi";
const code char Jour6[]="Samedi";
const code char * JourSemaine[]={Jour0,Jour1,Jour2,Jour3,Jour4,Jour5,Jour6};

const code char mesg0[]=" Directory :"Directory"\r\n";
const code char mesg1[]=" MikroC pro 7.30 Beta \n\r";
const code char mesg2[] =" Projet :"Project"\r\n";
const code char mesg3[]=" Test PIC18F27K42  I2C1 HW \r\n";
const char char mesg4[]=" Config bit : "Config" FOSC:"FOSC" MHz\r\n";
const char char mesg5[]=" Source : "Source"_"Version".c\r\n";
const char char mesg6[]=" 18F27K42 UART1 DS3231\r\n";
const char char mesg7[]=" ";
const char char mesg8[]=" ";
const char char mesg9[]=" ";
const char char mesg10[]=" ";
const code char * Messages[]={mesg0,mesg1,mesg2,mesg3,mesg4,mesg5,mesg6,mesg7,mesg8,mesg9,mesg10};
const char Blancs[]="  ";



sbit Bavard at RA3_bit ;
sbit Bavard_Dir at TRISA3_bit ;
sbit RAZ at LATC.B1;
sbit RAZ_Dir at TRISC.B1;
sbit RTC_Forcee at PORTC.B0;
sbit RTC_Forcee_Dir at TRISC.B0 ;
sbit HZ at LATC.B5;
sbit HZ_Dir at TRISC.B5;
sbit Alarme_Melodie at LATB.B7;
sbit Alarme_Melodie_Dir at LATB.B7;
sbit Clignote_Sec at LATA.B6;
sbit Clignote_Sec_Dir at TRISA.B6;


//sbit Soft_I2C_Scl           at RC3_bit;
//sbit Soft_I2C_Sda           at RC4_bit;
//sbit Soft_I2C_Scl_Direction at TRISC3_bit;
//sbit Soft_I2C_Sda_Direction at TRISC4_bit;


#define LED_ROUGE     RAZ
#define LED_BLANCHE   Clignote_Sec
#define LED_VERTE     Alarme_Melodie

#define MAX_LEN1 128
#define MAX_LEN2 64
#define MAX_LEN3 80

unsigned int i,j,k,l,m,n;

volatile unsigned char Temp=0;
volatile unsigned char Buffer1[MAX_LEN1];
volatile int Flag_Buffer1;
volatile unsigned char c1,cx;
volatile unsigned int i1;
volatile unsigned int Index1;
volatile unsigned int CptErr;


volatile char Temperat[30];
volatile unsigned char TP_Deg,TP_Deci;
volatile unsigned int TAmb;

unsigned char * p1;
unsigned char * p2;

unsigned char CRam1[MAX_LEN2];
unsigned char TEXTE [MAX_LEN3];
unsigned char *txt;

volatile unsigned int Count2, CountS;
volatile unsigned char Sec,Mn,Hour;
unsigned char OldSec;
unsigned int SEA0,EA0,Nb;
float F0,F1;
unsigned long L1;


unsigned char Buff_LCD[33];   // LCD 2x16 + zero
int addr;
unsigned char  I2C_Adresses_Devices[8];
unsigned char tmp[16] ;


unsigned int Count0 = 0;
unsigned char Etat_clock=0;

volatile struct chbits {   // 8 flags
       unsigned FrameErr:1;
       unsigned RAZ:1;
       unsigned Tmr0_Elapsed:1;
       unsigned Togle:1;
       unsigned Second:1;
       unsigned Gie:1;
       unsigned Full:1;
      unsigned Melodie:1;
 }Drapeaux ;
 
unsigned char Melodie=STOP;
unsigned int Duree_Melodie=5; // 5 Sec par defaut
signed  char Offset_Temper;
signed char Dummy;
// gamme Horaire de validation Melodie
unsigned int MinHour=8;  // 8H à 21H00
unsigned int MaxHour=21;

//int Status;
unsigned char Adr;
char time[]="00:00:00";
char date[]="00/00/00";
unsigned short second,minute,heure,jS,jour,mois,Annee;
unsigned short DateTime[9];
volatile int Flag_Timer1=0;
volatile int Flag_Timer2=0;
volatile int Index_Digit=0;

void Init_Hardware(void) ;
void CRLF1(void) ;
void Raz_Buffer(void) ;
void UART1_Write_CText(const char *txt);
void strConstRamCpy(unsigned char *dest, const code char *source);


void Interrupts() iv 0x0008 ics ICS_AUTO
{
    if (( TMR0IE_bit) && (TMR0IF_bit))
    {
       // pour debugger
       // U1TXB=Count0+48;
        // pour 100mS
         TMR0H         = 0x3C; //15536;
         TMR0L         = 0xB0;
        Count0++;
        if (Count0 >9) 
        {
            LED_VERTE = ~LED_VERTE;
            Drapeaux.Tmr0_Elapsed=1;
        }
        PIR3.TMR0IF= 0;
    }
    //RX UART IT
     if (( U1RXIF_bit==1) && ( U1RXIE_bit==1))  //RC1IE_bit==1) )
     {
     //  U1TXB=='?';
      c1 = UART1_Read();

      if (U1ABDOVF_bit==1)    // voir parag  31.2.2.4   page 479
      {
       U1ABDOVF_bit = 0 ;
       CptErr++;
       c1=U1RXB ;
       }
       if(U1FERIF_bit==1 )
       {
        CptErr++;
        c1 = UART1_Read();
       }
       // modif pour test envoi par BluetoothElectronic.apk (pas de CR)
       if ((c1==CR) || (c1==LF) || (Index1>MAX_LEN1-1))
       //  if ((c1==CR) || (Index1>MAX_LEN1-1))
       {
        Flag_Buffer1=1;
        Buffer1[i1]=0;
        U1RXIE_bit=0;
        Index1=i1;
        i1=0;
        if( Index1>MAX_LEN1-1) Flag_Buffer1=2;
        TMR2IE_bit=0;
       }
       else
       {
       Flag_Buffer1=0;
       Buffer1[i1]=c1;
       Index1=i1;
       i1++;
       }
     }
 }



#include "built_in.h"     // for  Hi  Lo ..etc


// --- Copie le texte depuis FLASH ROM vers RAM
void strConstRamCpy(unsigned char *dest, const code char *source)
 {
  while (*source)*dest++ = *source++ ;
  *dest = 0 ;    // terminateur
}

void CRLF1()
{
 UART1_Write(CR); UART1_Write(LF);
}

void UART1_Write_CText(const char *txtR)
 {
   while (*txtR)
      UART1_Write(*txtR++);
 }


void Raz_Buffer1()
{
        // nettoye le debut de buffer ,car utilisé pour init BT
        for(i1=0;i1<MAX_LEN1-1;i1++) Buffer1[i1]=0;
        Buffer1[0]=0;
        i1=0;
        p1=0;
        Index1=0;
        Flag_Buffer1 =0 ;
        c1=0;
        U1RXEN_bit=1;
         U1ERRIR = 0x00;
         U1ERRIE = 0x00;
        U1RXIE_bit=1;
}



void Init_Hardware()
{
  PORTA = 0x00;
  ANSELA=0x01;
  TRISA = 0b10000011 ;   // RA0,RA1=Input  R2..RA6 as output  RA7 input
  Clignote_Sec_Dir=0;
  Clignote_Sec=0;

  ANSELB=0;
  PORTB = 0x00;
  TRISB = 0x00;    //  B0..B7 Output   ATTENTION B7 B6 for ICSP Pickit3
  WPUB=0xFF;
  Alarme_Melodie_Dir=0;
  Alarme_Melodie=OFF  ;
  Melodie=STOP;

  CM1CON0=0;
  CM2CON0=0;

  PORTC=0;
  ANSELC=0 ;
  ANSELC2_bit=1;   // AN14
  TRISC = 0b10010111;    //
  WPUC2_bit=0;
  ODCC2_bit=0;
  
  RTC_Forcee_Dir=1;
  RAZ_Dir=0;
  RC6PPS = 0x13;   //RC6->UART1:TX1;
  // U1CTSPPS = 0x15;   //RC5->UART1:CTS1;
  U1RXPPS = 0x17;   //RC7->UART1:RX1;

   FVRCON=0;
   FVRCON.FVREN=0;  // page 597  paragraph 34.3
  FVRCON.ADFVR1=1; // 01 = Fixed Voltage Reference Peripheral output is 1,024)
  FVRCON.ADFVR0=0;
}

void Init_Timer0()
{

// FOS=64MHz  , FOSC/4=16Mhz
//  Timer0
// pour 100mS
//FOSC=64MHz Prescaler 1:32; TMR0 Preload = 15536; Actual Interrupt Time : 100 ms

//  REGISTER 22-1: T0CON0: TIMER0 CONTROL REGISTER 0
   T0CON0=0;
   T0CON0.B7=1;  //   Enable module and operating
   T0CON0.B4=1;  //MD16=1;
//   OUTPS<3:0>: TMR0 Output Postscaler (Divider) Select bits  0111= 1/8    1111=1/16   0000=1/1
   T0CON0.B3=0;
   T0CON0.B2=0;
   T0CON0.B1=0;
   T0CON0.B0=0;
//   REGISTER 22-2: T0CON1: TIMER0 CONTROL REGISTER 1
//   bit 7-5 CS<2:0>:Timer0 Clock Source Select bits = 011 HFINTOSC    010=FOSC/4
   T0CON1.B7=0;  //T0CON1.CS2 !!!!
   T0CON1.B6=1;  //T0CON1.CS1
   T0CON1.B5=0; //T0CON1.CS0
//   bit 4 ASYNC: TMR0 Input Asynchronization Enable bit
//   T0CON1.ASYNC=0;    //The input to the TMR0 counter is synchronized to FOSC/4
    T0CON1.ASYNC=1;    //The input to the TMR0 counter is synchronized to FOSC/4
//   bit 3-0 CKPS<3:0>: Prescaler Rate Select bit     1/32
   T0CON1.B3=0;   // CKPS3:0   0011=> 1/8     0101=> 1/32
   T0CON1.B2=1 ;
   T0CON1.B1=0 ;
   T0CON1.B0=1 ;
 // pour 100mS
  TMR0H         = 0x3C; //15536;
  TMR0L         = 0xB0;
//pour 1000mS
//   TMR0H         =0x0B ;      // 3036
//   TMR0L         =0xDC ;
//   T0CON1.B3=0;   //  0110=> 1/64
//   T0CON1.B2=1 ;
//   T0CON1.B1=1 ;
//   T0CON1.B0=0 ;
   PIR3.TMR0IF = 0;
   PIE3.TMR0IE = 1 ;      // TMR0 Enable Interrupt.
   T0CON0.B7=1;  //   Enable module and operating
   Drapeaux.Tmr0_Elapsed=0  ;
   Count0=0;
}

 /*
void I2C1_TimeoutCallback(char errorCode) 
{

   if (errorCode == _I2C1_TIMEOUT_RD) {
     // do something if timeout is caused during read
   }
   if (errorCode == _I2C1_TIMEOUT_WR) {
     // do something if timeout is caused during write
   }
   if (errorCode == _I2C_TIMEOUT_START) {
     // do something if timeout is caused during start
   }
   if (errorCode == _I2C_TIMEOUT_REPEATED_START) {
     // do something if timeout is caused during repeated start
   }

}
*/

#define I2C1_GOOD 0
#define I2C1CON0_EN    I2C1CON0.B7
static char lastError = I2C1_GOOD;

void I2C1_Initialize(void) // Initialize I2C Module
{
if(!I2C1CON0_EN || lastError != I2C1_GOOD)
{
lastError = I2C1_GOOD;
I2C1CON0 = 0x04; // Master 7-bit address mode
I2C1CON1 = 0x80; // ACKDT = ACK, ACKCNT = NACK
I2C1CON2 = 0x24; // Enable Address Buffers
// BFRET = 8 I2C pulses
// FME = 1
I2C1CLK = 0x03; // MFINTOSC (500 kHz)
I2C1PIR = 0; // Clear all interrupt flags
I2C1ERR = 0; // Clear all error flags
I2C1CON0_EN = 1; // Enable I2C module
}
}
void PIN_MANAGER_Initialize(void) // Initialize SCL and SDA pins
{
char state;
LATC = 0x00; // Clear PORTC write latches
TRISC = 0xE7; // RC3, RC4 initialized as outputs
ANSELC = 0xE7; // Clear RC3, RC4 analog input
ODCONC = 0x18; // Must configure RC3, RC4 as OD
RC3I2C = 0x01; // Standard GPIO slew rate
// Internal pull-ups not used
// I2C specific thresholds
SLRCONC.SLRC3 = 0; // No slew rate limiting
RC4I2C = 0x01;
SLRCONC.SLRC4 = 0;
// PPS configuration

state= INTCON0.GIE;
INTCON0.GIE = 0;
PPSLOCK = 0x55; // Unlock sequence
PPSLOCK = 0xAA;
PPSLOCK.PPSLOCKED = 0x00; // unlock PPS
RC3PPS = 0x21; // RC3->I2C1:SCL1;
RC4PPS = 0x22; // RC4->I2C1:SDA1;
I2C1SDAPPS = 0x14; // RC4->I2C1:SDA1;
I2C1SCLPPS = 0x13; // RC3->I2C1:SCL1;
PPSLOCK = 0x55; // Lock sequence
PPSLOCK = 0xAA;
PPSLOCK.PPSLOCKED = 0x01; // lock PPS
INTCON0.GIE = state;
}

 void BCD_To_Ascii(unsigned char cc,unsigned char * px)
 {
 *(px)=(cc>>4) + 48;
 *(px+1)=(cc & 0x0F) +48;
 *(px+2)=0;
 }

void main()
 {

 /*
 // REGISTER 7-5: OSCFRQ: HFINTOSC FREQUENCY SELECTION REGISTER
   // Frequence selection 64MHz
     FRQ3_bit=1   ;
     FRQ2_bit=0   ;
     FRQ1_bit=0   ;
     FRQ0_bit=0   ;
    // REGISTER 7-6: OSCTUNE: HFINTOSC TUNING REGISTER
    OSCTUNE=0;
    //REGISTER 7-7: OSCEN: OSCILLATOR MANUAL ENABLE REGISTER
    OSCEN=0;

     //OSCCON2   Clock Source type  = HF INTOSC
     COSC2_bit=1;
     COSC1_bit=1;
     COSC0_bit=0;

     //REGISTER 8-1: CLKRCON: REFERENCE CLOCK CONTROL REGISTER
      CLKRCON.B7 =1;  // EN=1 = Reference clock module enabled
       //DC<1:0>: Reference Clock Duty Cycle bits 50%
      CLKRCON.B4 =1; //DC1=1;
      CLKRCON.B3=0; // DC2=0;
     //DIV<2:0>: Reference Clock Divider bits
      CLKRCON.B2=1;
      CLKRCON.B1=0;
      CLKRCON.B0=0;


    //CLKRCLK: CLOCK REFERENCE CLOCK SELECTION MUX
    //CLK<7:4>:  unused=0
    //CLK<3:0>: CLKR Clock Selection bits
    //0001 = HFINTOSC
    CLKRCLK=1;
    Etat_clock=OSCSTAT;
      Drapeaux.Tmr0_Elapsed=0  ;
    Count0=0;
  */

    for (i=0;i<MAX_LEN2;i++) CRam1[i]=0;
    for (i=0;i<MAX_LEN3;i++) TEXTE[i]=0;
    Init_Hardware();

    LATA.B4=1;
    LATA.B5=0;
    
    UART1_Init(19200);
    UART_Set_Active(&UART1_Read, &UART1_Write, &UART1_Data_Ready, &UART1_Tx_Idle); // set UART1 active

    SWDTEN_bit=0;
    CRLF1();
    txt=&TEXTE[0];
    LATA.B4=0;
    LATA.B5=1;

    //   Open-Drain Configuration on Pins Rx<7:0>
    //1 = Output drives only low-going signals (sink current only)
    //0 = Output drives both high-going and low-going signals (source and sink current)
    // datasheet: The user must configure these pins as open-drain inputs.
    ODCONC.B4=1;
    ODCONC.B3=1;
   
    txt=&TEXTE[0];
    UART1_Write_CText("\r\n Presentation : \r\n");
    for (i=0;i<6;i++)   UART1_Write_CText(Messages[i]);
    UART1_Write_CText(" Init I2C1 HW \r\n");

    I2C1_Init();
    
    // this following code works also OK
    // PIN_MANAGER_Initialize();
    // I2C1_Initialize();

    Delay_ms( 100 );
    UART1_Write_CText(" Init RTC DS3231 \r\n");
    UART1_Write_CText(" Active sortie SQW=1Hz: \r\n");
 /*
    slave_address: slave address.
    ptrdata: pointer to the received data.
    count: number of bytes to be received.
    END_mode: mode in which the I²C module will be set after the reading. Available modes : Value Description
    _I2C_END_MODE_RESTART I²C bus will issue a restart.
    _I2C_END_MODE_STOP I²C bus will issue a stop.
  */
    tmp[0]=0x0E;
    tmp[1]=0b01000000;
    I2C1_Wr( DS3231_ADDR, tmp, 2, _I2C_END_MODE_STOP );

   // clean table tmp
   for (i=1;i<16;i++) tmp[i]=0;

   if(RTC_Forcee==0)    // RC0 input
   {
    UART1_Write_CText( "Init data RTC par defaut, avec RTC_Forcée=0 \r\n");
    tmp[0]=0;
     tmp[1]=0x50;  //Reset second to 0 sec. and stop Oscillator
      tmp[2]=0x59;  //write min
       tmp[3]=0x14; //write hour;
        tmp[4]=0x02;     ///write day of week
         tmp[5]=0x20;     // write date
          tmp[6]=0x02;      // write month
            tmp[7]=0x19;    // write year 2019
         I2C1_Wr( DS3231_ADDR, tmp, 7, _I2C_END_MODE_STOP );
   }
   else
   {
       UART1_Write_CText(" Re-Lecture RTC ");
   }

    CRLF1();
    do
    {
    // relecture RTC
      tmp[0]=0 ;
      I2C1_Wr( DS3231_ADDR, tmp, 1,  _I2C_END_MODE_RESTART );
      I2C1_Rd( DS3231_ADDR, tmp, 7, _I2C_END_MODE_STOP );
      second=tmp[0];
      minute=tmp[1];
      heure=tmp[2];
      jS=tmp[3];
      if (jS>6) jS=0;
      jour=tmp[4];
      mois=tmp[5];
      Annee=tmp[6];
     // affichage data RTC
    for (i=6;i>0;i--)
    {
      BCD_To_Ascii(tmp[i],CRam1);
      UART1_Write_Text(CRam1);UART1_Write(TAB);
    }
      BCD_To_Ascii(tmp[0],CRam1);
      UART1_Write_Text(CRam1);
    CRLF1();
     Delay_ms(1000);
     }
  while(1);
  }
 
 /*
 

 Presentation :
 Directory :C:_MikroC_MesProjets_MikroC_18F27K42
 MikroC pro 7.30 Beta
 ð

 Presentation :
 Directory :C:_MikroC_MesProjets_MikroC_18F27K42
 MikroC pro 7.30 Beta
 Projet :PIC18F27K42_UART1_RTC_DS3231_I2C1_Hardw_Test.mcppi
 Test PIC18F27K42  I2C1 HW
 Config bit :  P18F27K42_at_64Mhz.cfgsch FOSC:64.0 MHz
 Source : PIC18F27K42_UART1_RTC_DS3231_Hardw_I2C_Test_190220.c
 Init I2C1 HW
 Init RTC DS3231
 Active sortie SQW=1Hz:
Init data RTC par defaut, avec RTC_Forcée=0

19      02      20      02      14      59      50
19      02      20      02      14      59      51
19      02      20      02      14      59      52
19      02      20      02      14      59      53
19      02      20      02      14      59      54
19      02      20      02      14      59      55
19      02      20      02      14      59      56
19      02      20      02      14      59      57
19      02      20      02      14      59      58
19      02      20      02      14      59      59
19      02      20      02      15      00      00
19      02      20      02      15      00      01
19      02      20      02      15      00      02
19      02      20      02      15      00      03
19      02      20      02      15      00      04
19      02      20      02      15      00      05
*/