/********************************(abc898-18325.c)***
* RTC (DS1307) テスト
****************************************************/
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/examples/i2c1_master_example.h"
#include "string.h"
#include "i2cLCD_ST7032i.h"
#define DS1307 0x68 // RTCのI2Cアドレス
//=== グローバル変数 ============
uint8_t RBuf[BFSIZE]; // シリアル受信用
uint8_t SFlg; // シリアル受信フラグ
char SBuf[20]; // 文字列処理用バッファー
//----RTC用変数(2進数で格納)
uint8_t DayTm[] = { 0, // seconds
30, // minutes
10, // Hours(24h)
6, // day[week]
12, // date
7, // month
24, // year (下2桁)
0 // SQW/OUT
};
/****** 汎用関数 ***************************/
//---- BCD数を2進数に変換
uint8_t bcd2bin(uint8_t bcd){
return ((bcd >> 4)& 0x0F) * 10 + (bcd & 0x0F);
}
//---- 2進数をBCD数に変換
uint8_t bin2bcd(uint8_t bin){
return (uint8_t)((uint16_t)(bin/10) << 4)+(bin % 10);
}
//---- 文字列から数値を取り出し、1バイト配列に逆順で格納
// buf: 取り出した数値を格納する1バイト配列
// src: 数値を取り出す文字列
// delim: 区切り文字を文字列にしたもの
// (戻り値): 取得出来た数値の数
uint8_t get_NumRev(uint8_t *buf, char *src, char *delim){
char *ptr;
uint8_t bt, n = 0;
ptr = strtok(src, delim);
while(ptr != NULL){
bt = (uint8_t)atoi(ptr); //無効データでも0を返す
*buf-- = bt;
n++;
ptr = strtok(NULL, delim);
}
return n;
}
/****** RTC用関数 ******************************/
//--- RTCのadr番地にdatデータを書き込む
void RTC_write(uint8_t adr, uint8_t dat){
uint8_t bf[3];
bf[0] = adr; // Address = adr
bf[1] = dat; // Set Data
I2C1_WriteNBytes(DS1307, bf, 2); // Write Data
}
//--- RTCのadr番地のデータを読み込む
uint8_t RTC_read(uint8_t adr){
uint8_t bf[3];
bf[0] = adr; // Address = adr
I2C1_WriteNBytes(DS1307, bf, 1); // Set Address
I2C1_ReadNBytes(DS1307, bf, 1); // Read Data
return bf[0];
}
//--- RTCの全てのrtcデータを読み込む
void RTC_readAll(uint8_t *buf){
uint8_t rtc[8], i;
rtc[0] = 0; // Address = 0
I2C1_WriteNBytes(DS1307, rtc, 1); // Set Address
I2C1_ReadNBytes(DS1307, rtc, 8); // Read Data
for(i = 0; i < 8; i++){
buf[i] = bcd2bin(rtc[i]);
}
}
//--- RTCの全てにrtcデータを書き込む
void RTC_writeAll(uint8_t *buf){
uint8_t rtc[9], i;
rtc[0]=0; // Address = 0
for(i=0; i < 8; i++){
rtc[i+1] = bin2bcd(buf[i]);
}
I2C1_WriteNBytes(DS1307, rtc, 9);
}
//--- RTCの指定アドレスからnバイトのデータを書き込む
// buf: 書き込むデータが格納された配列
// adr: 書き込むRTCアドレス
// n: 書き込むバイト数
void RTC_writePrt(uint8_t *buf, uint8_t adr, uint8_t n){
uint8_t rtc[9], i;
rtc[0] = adr; // Address = adr
for(i = 0;i < n; i++){
rtc[i+1] = bin2bcd(buf[adr+i]);
}
I2C1_WriteNBytes(DS1307, rtc, n+1);
}
/***** コマンド処理 ********************/
//---- R(read)コマンド
void cmd_r(){
uint8_t i;
RTC_readAll(DayTm);
for(i = 1; i < 9; i++){
printf("%d: %02d\n\r", i, DayTm[i]);
}
}
//---- D(date)コマンド "Dyy/MM/dd/w"
void cmd_d(){
uint8_t n;
n = get_NumRev(DayTm+6, RBuf+1, "/");
if((n > 0)&&(n < 5)){
RTC_writePrt(DayTm, 3, 4);
}
}
//---- T(time)コマンド "Thh:mm:ss"
void cmd_t(){
uint8_t n;
n = get_NumRev(DayTm+2, RBuf+1, ":");
if((n > 0)&&(n < 4)){
RTC_writePrt(DayTm, 0, 3);
}
}
/****** Main application ****************************/
void main(void){
uint8_t sec, cmd;
SYSTEM_Initialize();
LCD_init(); // LCD初期化
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
puts("ready|n\r");
// RTC_writeAll(Dt); // for test
sec = 0;
while (1){
if(SFlg){
cmd = RBuf[0];
switch(cmd){
case 'R': cmd_r(); break;
case 'T': cmd_t(); break;
case 'D': cmd_d(); break;
default: break;
}
SFlg = 0;
}
RTC_readAll(Dt);
if(sec != DayTm[0]){ // 表示は秒単位
sprintf(SBuf, "20%02d/%02d/%02d(%d)",
DayTm[6],DayTm[5],DayTm[4],DayTm[3]);
LCD_clr(); LCD_str(SBuf);
// printf("%s ", SBuf);
sprintf(SBuf, "%02d:%02d:%02d",
DayTm[2], DayTm[1], DayTm[0]);
LCD_cursor(0,1); LCD_str(SBuf);
// printf("%s\n\r", SBuf);
sec = DayTm[0];
}
}
}
|