;***** I2C_RTC.sub ******************************************************** ; ; I2C RTC(DS3231)モジュール 制御サブルーチン (ソフトウエア I2C 版) ; ; (I2cRtc_Write, I2cRtc_Read, I2cRtc_Init) ; ; Copyright (C) 2020-2021 by M.Yamamoto. All rights reserved. ; ; ( coding: Ver. 0.00 2020/12/29 by M.Yamamoto ) ; coding: Ver. 1.00 2020/12/31 ; update: Ver. 1.01 2021/01/11 レジスタ名の変更 ; bugfix: Ver. x.xx ; ;******************************************************* PicAsm 0258 ****** ;<使用外部ルーチン> ;(i2c_start, i2c_stop, i2c_byte_send, i2c_byte_reciv, i2c_ack, i2c_nack) ;<使用レジスタ> ;rtc_addr_high ;読み出すデータの high アドレス ;rtc_addr_low ;読み出すデータの low アドレス ;rtc_lpcnt ;ループカウンタ ;(読み書きバッファ) ;seconds ;00h: Seconds: 00-59 ;minutes ;01h: Minutes: 00-59 ;hours ;02h: Hours: 1-12 + AM/PM, 00-23 ;day ;03h: Day: 1-7 ;date ;04h: Date: 01-31 ;month ;05h: Month/Century: 01-12 + Century ;year ;06h: Year: 00-99 ;alarm1s ;07h: Alarm 1 Seconds: 00-59 ;alarm1m ;08h: Alarm 1 Minutes: 00-59 ;alarm1h ;09h: Alarm 1 Hours: 1-12 + AM/PM, 00-23 ;alarm1dy ;0Ah: Alarm 1 Day: 1-7 ;alarm1d ;0Bh: Alarm 1 Date: 1-31 ;alarm2h ;0Ch: Alarm 2 Hours: 1-12 + AM/PM, 00-23 ;alarm2d ;0Dh: Alarm 2 Day: 1-7, Alarm 2 Date: 1-31 ;control ;0Eh: Control ;cont_stat ;0Fh: Control/Status ;aging ;10h: Aging Offset ;temp_m ;11h: MSB of Temp ;temp_l ;12h: LSB of Temp ;========================================================================== ; 定数の定義 ;========================================================================== RtcAddr equ h'68' ;RTC モジュール(DS3231) のスレーブアドレス RtcEepAddr equ h'57' ;RTC モジュール(AT24C32)のスレーブアドレス ;========================================================================== ; マクロ命令定義 ;========================================================================== ; Rtc_Write_M マクロ Rtc_Write_M macro @bufreg,@n movlw @bufreg ;書き込みバッファのレジスタアドレス movwf FSR ;間接アドレスに設定 movlw @n movwf rtc_lpcnt ;ループカウンタ call I2cRtc_Write ;RTC(DS3231)モジュールのレジスタへ書き込み endm ; Rtc_Read_M マクロ Rtc_Read_M macro @bufreg,@n movlw @bufreg ;読み出しバッファのレジスタアドレス movwf FSR ;間接アドレスに設定 movlw @n movwf rtc_lpcnt ;ループカウンタ call I2cRtc_Read ;RTC(DS3231)モジュールのレジスタから読み出し endm ;========================================================================== ; RTC(DS3231)モジュールのレジスタへ書き込み ;========================================================================== ;入力: FSR: 書き込みバッファの(先頭)レジスタアドレス ; rtc_lpcnt: 書き込み数 I2cRtc_Write call i2c_start ;スタートコンディション movlw RtcAddr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 movlw seconds subwf FSR,W ;レジスタアドレス call i2c_byte_send ;1 バイト送信 rtcwr01 movf INDF,W ;書き込みデータ call i2c_byte_send ;1 バイト送信 incf FSR,F ;間接アドレスの更新 decfsz rtc_lpcnt,F ;ループカウンタ - 1 = 0 か? goto rtcwr01 ;No call i2c_stop ;ストップコンディション return ;========================================================================== ; RTC(DS3231)モジュールのレジスタから読み出し ;========================================================================== ;入力: FSR: 読み出しバッファの(先頭)レジスタアドレス ; rtc_lpcnt: 読み出し数 I2cRtc_Read call i2c_start ;スタートコンディション movlw RtcAddr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 movlw seconds subwf FSR,W ;レジスタアドレス call i2c_byte_send ;1 バイト送信 call i2c_start ;再スタートコンディション movlw (RtcAddr << 1) + 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 goto rtcrd02 rtcrd01 call i2c_ack ;ACK rtcrd02 call i2c_byte_reciv ;1 バイト受信 movwf INDF ;読み出しデータ incf FSR,F ;間接アドレスの更新 decfsz rtc_lpcnt,F ;ループカウンタ - 1 = 0 か? goto rtcrd01 ;No call i2c_nack ;NACK call i2c_stop ;ストップコンディション return ;========================================================================== ; I2C RTC(DS3231)モジュールの初期設定 ;========================================================================== I2cRtc_Init movlw high ds3231_init_table ;テーブルデータの先頭 high アドレス movwf rtc_addr_high ; movlw low ds3231_init_table ;テーブルデータの先頭 low アドレス movwf rtc_addr_low ; movlw ds3231_init_table_end - ds3231_init_table movwf rtc_lpcnt ;ループカウンタ call i2c_start ;スタートコンディション movlw RtcAddr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 rtcini01 call rtctbl_read ;テーブルデータの読み出し bcf PCLATH,3 ;ページ 0 に戻す bcf PCLATH,4 call i2c_byte_send ;1 バイト送信 incf rtc_addr_low,F ;読み出すデータの low アドレスの更新 btfsc STATUS,Z ;オーバーフローした場合は incf rtc_addr_high,F ;読み出すデータの high アドレスの更新 decfsz rtc_lpcnt,F ;ループカウンタ - 1 = 0 か? goto rtcini01 ;No call i2c_stop ;ストップコンディション return ; テーブルデータの1文字読み出し rtctbl_read movf rtc_addr_high,W ;読み出すデータの high アドレス movwf PCLATH movf rtc_addr_low,W ;読み出すデータの low アドレス movwf PCL ;-------------------------------------------------------------------------- ; I2C RTC(DS3231)モジュールの初期設定用テーブルデータ ds3231_init_table dt h'00' ;DS3231 レジスタのスタート(先頭)アドレス dt h'00' ;00h: Seconds dt h'00' ;01h: Minutes dt h'00' ;02h: Hours dt h'06' ;03h: Day(Week) dt h'01' ;04h: Date dt h'01' ;05h: Month/Century dt h'21' ;06h: Year dt h'00' ;07h: Alarm 1 Seconds dt h'00' ;08h: Alarm 1 Minutes dt h'00' ;09h: Alarm 1 Hours dt h'00' ;0Ah: Alarm 1 Day dt h'00' ;0Bh: Alarm 1 Date dt h'00' ;0Ch: Alarm 2 Hour dt h'00' ;0Dh: Alarm 2 Day dt h'00' ;0Eh: Control dt h'00' ;0Fh: Control/Status dt h'00' ;10h: Aging Offset ; dt h'00' ;11h: MSB of Temp ; dt h'00' ;12h: LSB of Temp ds3231_init_table_end ;=============================================================== end ======