
' ************************************************************************
' Test example for RTC DS3231 (Real-time clock with calendar).
' Program: master I2C and DS3231 (I2C HARDWARE).
' Microcontroller: PIC18F46K22, OshonSoft PIC18 BASIC Compiler v6.10
' Author: COS (dogflu66@yahoo.es)
' Date: 2026/04/03
' ************************************************************************
' ************************************************************************
' PCB HL-K18 Jumper Configuration:
' General Jumpers on HL-K18: VCC, GND, PGC, PGD, OSC2, OSC1, VPP
' RS232 Interface: TX (Transmit), RX (Receive), BZ (Buzzer)
' Specific Jumpers for this setup: NONE
' Switches S2 and S4 should both be set to OFF.
' PICKIT2 Jumpers on HL-K18: Not used, external programmer.
' ************************************************************************
' Configuration of microcontroller fuses
' Setting up internal oscillator with 4x PLL to achieve 64MHz system clock
' MCLR enabled for external reset <---------------------------------------
#define CONFIG1L = 0x00  ' Low Power Timer and memory settings
#define CONFIG1H = 0xF8  ' External oscillator with PLL enabled
#define CONFIG2L = 0x1E  ' Brown-out Reset, Power-Up Timer
#define CONFIG2H = 0x3C  ' Watchdog Timer setup
#define CONFIG3L = 0x00  ' Low-voltage programming disabled
#define CONFIG3H = 0xBD  ' Port configuration options
#define CONFIG4L = 0x80  ' Stack overflow and underflow reset enabled
#define CONFIG4H = 0x00  ' Additional configuration bits
#define CONFIG5L = 0x0F  ' Code protection
#define CONFIG5H = 0xC0  ' Data EEPROM code protection
#define CONFIG6L = 0x0F  ' Write protection settings
#define CONFIG6H = 0xE0  ' Configuration protection bits
#define CONFIG7L = 0x0F  ' Boot block protection settings
#define CONFIG7H = 0x40  ' Configuration for block protection
' General configuration
#define CLOCK_FREQUENCY = 64		' System clock frequency in MHz
#define SINGLE_DECIMAL_PLACES = 1	' Number of decimal places for floating-point operations
#define STRING_MAX_LENGTH = 30		' Maximum length For String variables
'#define SIMULATION_WAITMS_VALUE = 0 'Activate only in simulation.
'*************************************************
'*************************************************
Include "_Pic18F46K22Lib.bas"
Include "_I2CLib.bas"
Include "_DS3231Lib.bas"
'Include "_AT24C32Lib.bas"
'*************************************************
main:
    ' Configure the internal clock to 64MHz
    Call _Setup_Oscillator(_OSC_16MHz_HF) ' Set the oscillator to 16MHz HF
    Call _SET_PLL4(_PLL_ON) ' Enable the PLL to multiply frequency by 4
    Call _Interrupts_Mode(_DISABLE_PRIORITY) ' Disable interrupt priority
    '*********************************************
    'Basic configuration for Amicus18 card.
    AllDigital
    TRISA = 0
    TRISB = 0
    TRISC = 0
    TRISE = 0
    UART1_Init 115200	' Initialize UART1 at 115200 baud rate
    'UART2_Init 4800    ' Initialize UART2 at 4800 baud rate (commented out)
    WaitMs 1            ' Wait 1 millisecond
    UART1_Write 0x0C 	' Clear screen (new page)
    WaitMs 100
    UART1_Write "Ready", CrLf
    '*********************************************
    '*********************************************
    ' Initialize I2C
    Init_I2C(100, 64) ' Initialize MSSP1 module in I2C master mode at 100kHz
    WaitMs 10


	' Check if the RTC is initialized
	Dim v_eep(3) As Byte
	Const INIT_RTC = %00000001 ' Change value to trigger a new initialization
	EEPROM_Read 0, v_eep(0)
	EEPROM_Read 1, v_eep(1)
	EEPROM_Read 2, v_eep(2)

	If v_eep(0) = 0xAA And v_eep(1) = INIT_RTC And v_eep(2) = (v_eep(0) + v_eep(1)) Then
		UART1_Write "Clock Initialized", CrLf

	Else
		UART1_Write "Initializing Clock ...", CrLf
		' Mark as RTC initialized
		v_eep(0) = 0xAA
		v_eep(1) = INIT_RTC
		v_eep(2) = v_eep(0) + v_eep(1)
		EEPROM_Write 0, v_eep(0)
		EEPROM_Write 1, v_eep(1)
		EEPROM_Write 2, v_eep(2)

		'Initialize the DS3231 RTC
		Call DS3231_Init()
		WaitMs 10

		Call DS3231_Set_24h() ' Set 24-hour mode

		' Declare variables for date and time
		Dim day, mth, year, dow, hr, min, sec As Byte
		day = 03    ' Set day to 7
		mth = 04   ' Set month to 10 (October)
		year = 26  ' Set year to 2025
		dow = 5    ' Set day of the week (1 = Sunday)
		hr = 19    ' Set hour to 1
		min = 25   ' Set minutes to 28

		Call DS3231_Set_DateTime(day, mth, year, dow, hr, min) ' Set the date and time in the DS3231

	Endif

    WaitMs 10

	'Call DS3231_Set_24h() ' Set 24-hour mode
	'Call DS3231_Set_Hour(18)
	'Call DS3231_Set_12h() ' Set 12-hour mode
	'Call DS3231_Set_Hour(0)
	'Call DS3231_Set_AM_PM(PM_ON)

	Call DS3231_SquareWave(DS3231_Freq_DISABLE)
	Call DS3231_32Khz(True)

	'Call DS3231_SetAlarm1(30, 03, 23, 27, 0) ' sec, min, hr, day, useDow
	'Call DS3231_EnableAlarm1(1)
	'Call DS3231_SetAlarm2(16, 23, 27, 0) ' min, hr, day, useDow
	'Call DS3231_EnableAlarm2(1)

    ' Infinite loop
    While True
        ' Read date and time from the DS3231
        Call DS3231_Get_Time(hr, min, sec)        ' Get the current time
        Call DS3231_Get_Date(day, mth, year, dow) ' Get the current date

        ' Set day of week
		Dim _Dow[9] As String
		Select Case dow
			Case 1
				_Dow = "Monday"
			Case 2
				_Dow = "Tuesday"
			Case 3
				_Dow = "Wednesday"
			Case 4
				_Dow = "Thursday"
			Case 5
				_Dow = "Friday"
			Case 6
				_Dow = "Saturday"
			Case 7
				_Dow = "Sunday"
			Case Else
				_Dow = "Null"
		EndSelect

		Dim th[4] As String
		Select Case DS3231_Get_AM_PM_24h()
			Case 0
				th = "AM"
			Case 1
				th = "PM"
			Case -1
				th = "24h"
			Case Else
				th = "Null"
		EndSelect

        ' Send date, time and temperature via UART1
        UART1_Write #hr, ":", #min, ":", #sec, "   ", #day, "/", #mth, "/", #year, "-", _Dow, " ", th, " Temp: ", #DS3231_ReadTemperature(), "ºC", CrLf

        ' Wait 1 second before repeating
        WaitMs 1000

        'WaitMs 60000
        'Call DS3231_ClearAlarmFlags()
	Wend
End ' End of the program