/************************************************************************/ // MCP795XX-Routine für PIC18F47Q43 // Programmierer: Fa. Schwabenplan, Ingo Schick // Compiler: XC8 // Datum: 10.06.2024 /************************************************************************/ /************************************************************************/ // Include-Dateien /************************************************************************/ #include // Standard-Bibiotheken einbeziehen #include "../MCP795XX.h" /************************************************************************/ // interne Variablen-Deklaration date_time_t dt; // globale Variable für Datum und Uhrzeit /************************************************************************/ /************************************************************************/ // BCD -> Binär // Diese Fuktion konvertiert einen 8-Bit BCD-Wert zu einem 8-Bit Binärwert // Wertebereich: 0 to 99 /************************************************************************/ uint8_t BCD2BIN(uint8_t bcd_value) { uint8_t temp; temp = bcd_value; // Shifting the upper digit right by 1 is // the same as multiplying it by 8. temp >>= 1; // Isolate the bits for the upper digit. temp &= 0x78; // Now return: (Tens * 8) + (Tens * 2) + Ones return (temp + (temp >> 2) + (bcd_value & 0x0f)); } /************************************************************************/ /************************************************************************/ // Binär -> BCD // Diese Fuktion konvertiert einen 8-Bit Binärwert zu einem 8-Bit BCD-Wert // Wertebereich: 0 to 99 /************************************************************************/ uint8_t BIN2BCD(uint8_t value) { uint8_t retval; retval = 0; while(1) { // Get the tens digit by doing multiple subtraction // of 10 from the binary value. if(value >= 10) { value -= 10; retval += 0x10; } else // Get the ones digit by adding the remainder. { retval += value; break; } } return(retval); } /************************************************************************/ /************************************************************************/ // Allgemeines Schreiben eines Bytes /************************************************************************/ uint8_t MCP795XX_Write_Byte(uint8_t address, uint8_t data) { while (!SPI1_Open(SPI1_DEFAULT)); //4.00 MHz CS_RTC_SetLow(); RTC_SPI_WRITE8(MCP795XX_WRITE); RTC_SPI_WRITE8(address); RTC_SPI_WRITE8(data); CS_RTC_SetHigh(); SPI1_Close(); __delay_ms(5); //Pausenzeit zum schreiben return 1; } /************************************************************************/ /************************************************************************/ // Allgemeines Lesen eines Bytes /************************************************************************/ uint8_t MCP795XX_Read_Byte(uint8_t address) { uint8_t retval; while (!SPI1_Open(SPI1_DEFAULT)); //4.00 MHz CS_RTC_SetLow(); RTC_SPI_WRITE8(MCP795XX_READ); RTC_SPI_WRITE8(address); retval = RTC_SPI_READ8(); CS_RTC_SetHigh(); SPI1_Close(); return(retval); } /************************************************************************/ /************************************************************************/ //Write Programme RTC /************************************************************************/ void MCP795XX_Write_HSekunden(date_time_t *dt) { uint8_t bcd_HSekunden; bcd_HSekunden = BIN2BCD(dt->HSekunden); MCP795XX_Write_Byte(RTCSEC, bcd_HSekunden); } /************************************************************************/ /************************************************************************/ void MCP795XX_Write_Sekunden(date_time_t *dt) { uint8_t bcd_Sekunden; bcd_Sekunden = BIN2BCD(dt->Sekunden); MCP795XX_Write_Byte(RTCSEC, (0x80 | ((bcd_Sekunden) & 0x7F))); // ST ON } /************************************************************************/ /************************************************************************/ void MCP795XX_Write_Minuten(date_time_t *dt) { uint8_t bcd_Minuten; bcd_Minuten = BIN2BCD(dt->Minuten); MCP795XX_Write_Byte(RTCMIN, bcd_Minuten & 0x7F); } /************************************************************************/ /************************************************************************/ void MCP795XX_Write_Stunden(date_time_t *dt) { uint8_t bcd_Stunden; bcd_Stunden = BIN2BCD(dt->Stunden); MCP795XX_Write_Byte(RTCHOUR, bcd_Stunden & 0x3F); } /************************************************************************/ /************************************************************************/ void MCP795XX_Write_Wochentag(date_time_t *dt) { uint8_t bcd_Wochentag; bcd_Wochentag = BIN2BCD(dt->Wochentag); MCP795XX_Write_Byte(RTCWKDAY, (0x08 | ((BIN2BCD(dt->Wochentag)) & 0x07))); MCP795XX_Write_Byte(RTCWKDAY, bcd_Wochentag | 0xF8); // VBATEN ON } /************************************************************************/ /************************************************************************/ void MCP795XX_Write_Tag(date_time_t *dt) { uint8_t bcd_Tag; bcd_Tag = BIN2BCD(dt->Tag); MCP795XX_Write_Byte(RTCDATE, bcd_Tag & 0x3F); } /************************************************************************/ /************************************************************************/ void MCP795XX_Write_Monat(date_time_t *dt) { uint8_t bcd_Monat; bcd_Monat = BIN2BCD(dt->Monat); MCP795XX_Write_Byte(RTCMTH, bcd_Monat & 0x1F); } /************************************************************************/ /************************************************************************/ void MCP795XX_Write_Jahr(date_time_t *dt) { uint8_t bcd_Jahr; bcd_Jahr = BIN2BCD(dt->Jahr); MCP795XX_Write_Byte(RTCYEAR, bcd_Jahr); } /************************************************************************/ /************************************************************************/ // Read-Programme RTC /************************************************************************/ uint8_t MCP795XX_Read_HSekunden(date_time_t *dt) { dt->HSekunden = BCD2BIN(MCP795XX_Read_Byte(RTCHSEC)); return(dt->HSekunden); } /************************************************************************/ /************************************************************************/ uint8_t MCP795XX_Read_Sekunden(date_time_t *dt) { dt->Sekunden = BCD2BIN(MCP795XX_Read_Byte(RTCSEC) & 0x7F); return(dt->Sekunden); } /************************************************************************/ /************************************************************************/ uint8_t MCP795XX_Read_Minuten(date_time_t *dt) { dt->Minuten = BCD2BIN(MCP795XX_Read_Byte(RTCMIN) & 0x7F); return(dt->Minuten); } /************************************************************************/ /************************************************************************/ uint8_t MCP795XX_Read_Stunden(date_time_t *dt) { dt->Stunden = BCD2BIN(MCP795XX_Read_Byte(RTCHOUR) & 0x3F); return(dt->Stunden); } /************************************************************************/ /************************************************************************/ uint8_t MCP795XX_Read_Wochentag(date_time_t *dt) { dt->Wochentag = BCD2BIN(MCP795XX_Read_Byte(RTCWKDAY) & 0x07); return(dt->Wochentag); } /************************************************************************/ /************************************************************************/ uint8_t MCP795XX_Read_Tag(date_time_t *dt) { dt->Tag = BCD2BIN(MCP795XX_Read_Byte(RTCDATE) & 0x3F); return(dt->Tag); } /************************************************************************/ /************************************************************************/ uint8_t MCP795XX_Read_Monat(date_time_t *dt) { dt->Monat = BCD2BIN(MCP795XX_Read_Byte(RTCMTH) & 0x1F); return(dt->Monat); } /************************************************************************/ /************************************************************************/ uint8_t MCP795XX_Read_Jahr(date_time_t *dt) { dt->Jahr = BCD2BIN(MCP795XX_Read_Byte(RTCYEAR)); return(dt->Jahr); } /************************************************************************/ /************************************************************************/ // MCP795XX auf Werkseinseinstellung zurücksetzen /************************************************************************/ void MCP795XX_Reset(void) { MCP795XX_Write_Byte(RTCHSEC, 0x00); MCP795XX_Write_Byte(RTCHSEC, 0x00); MCP795XX_Write_Byte(RTCMIN, 0x00); MCP795XX_Write_Byte(RTCHOUR, 0x00); MCP795XX_Write_Byte(RTCWKDAY, 0x01); MCP795XX_Write_Byte(RTCDATE, 0x01); MCP795XX_Write_Byte(RTCMTH, 0x01); MCP795XX_Write_Byte(RTCYEAR, 0x00); } /************************************************************************/ /************************************************************************/ // MCP795XX Speicher schreiben /************************************************************************/ uint8_t MCP795XX_Write_EE_Byte(uint8_t unc_Register, uint8_t unc_Daten) { while (!SPI1_Open(SPI1_DEFAULT)); //4.00 MHz CS_RTC_SetLow(); FLASH_SPI_WRITE8(MCP795XX_EEWREN); //Baustein mit WREN-Befehl vorbereiten CS_RTC_SetHigh(); CS_RTC_SetLow(); FLASH_SPI_WRITE8(MCP795XX_EEWRITE); // Baustein schreiben FLASH_SPI_WRITE8(unc_Register); FLASH_SPI_WRITE8(unc_Daten); CS_RTC_SetHigh(); SPI1_Close(); __delay_ms(5); //Pausenzeit zum schreiben return unc_Daten; } /************************************************************************/ /************************************************************************/ // MCP795XX Speicher lesen /************************************************************************/ uint8_t MCP795XX_Read_EE_Byte(uint8_t unc_Register) { uint8_t unc_Daten; while (!SPI1_Open(SPI1_DEFAULT)); //4.00 MHz CS_RTC_SetLow(); FLASH_SPI_WRITE8(MCP795XX_EEREAD); FLASH_SPI_WRITE8(unc_Register); unc_Daten = FLASH_SPI_READ8(); CS_RTC_SetHigh(); SPI1_Close(); return unc_Daten; } /************************************************************************/ /************************************************************************/ // MCP795XX Speicher lesen /************************************************************************/ uint8_t MCP795XX_Read_ID_Byte(uint8_t unc_Register) { uint8_t unc_Daten; while (!SPI1_Open(SPI1_DEFAULT)); //4.00 MHz CS_RTC_SetLow(); FLASH_SPI_WRITE8(MCP795XX_IDREAD); FLASH_SPI_WRITE8(unc_Register); unc_Daten = FLASH_SPI_READ8(); CS_RTC_SetHigh(); SPI1_Close(); return unc_Daten; } /************************************************************************/ /************************************************************************/ // MCP795XX Speicher lesen /************************************************************************/ void MCP795XX_Clear_SRAM(void) { while (!SPI1_Open(SPI1_DEFAULT)); //4.00 MHz CS_RTC_SetLow(); FLASH_SPI_WRITE8(MCP795XX_CLRRAM); FLASH_SPI_WRITE8(0x00); CS_RTC_SetHigh(); SPI1_Close(); } /************************************************************************/ /************************************************************************/ // Schaltjahr ja / nein /************************************************************************/ bool Schaltjahr(void) { bool bl_Schaltjahr; bl_Schaltjahr = BCD2BIN(MCP795XX_Read_Byte(RTCMTH) & 0x20); return bl_Schaltjahr; } /************************************************************************/