JH7UBCブログ

アマチュア無線 電子工作 家庭菜園など趣味のブログです

PIC16F1827 MCC RTC(DS1307)テストその1

2021-07-15 22:14:04 | MPLAB X MCC
 先日、ArduinoでRTC(リアルタイムクロック)DS1307をコントロールするテストを行いました。

 これで、DS1307のコントロールの勘所がつかめましたので、PIC16F1827を使って、テストを行います。

 今回は、表示には前の記事で使ったI2Cインターフェース付きLCD1602を使います。
 DS1307とは、I2Cで通信しますので、MCCの設定は、LCD1602のテストの時と同じですが、PICを回路にセットしたまま、プログラムのテストができるように、ICSPを使います。テスト回路図です。


 従って、MCCのpin managerでRA5は、MCLR/VPPのままにしておきます。

プログラムです。
--------------------------------------------------------------
/*
* PIC12F1827 MCC RTC TEST
* 2021.07.15
* JH7UBC Keiji Hata
*/

#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/examples/i2c1_master_example.h"

//LCD関係定義
#define I2C_LCD_addr 0x27
#define LCD_EN 0b00000100//Enable
#define LCD_BL 0b00001000//Back Light
#define LCD_CMD 0x00
#define LCD_CHR 0x01
#define LCD_LINE1 0x80
#define LCD_LINE2 0xC0

//RTC関係定義
#define RTC_addr 0x68
#define SECOND 0x00
#define MINUTE 0x01
#define HOUR 0x02
#define DAY 0x03//WEEK
#define DATE 0x04
#define MONTH 0x05
#define YEAR 0x06
#define CTRL 0x07

char *week[] = {" ","MON","TUE","WED","THU","FRI","SAT","SUN"};
//時刻データ初期値
uint8_t REG[8] = {0x50,0x59,0x23,0x03,0x14,0x07,0x21,0x00};
uint8_t REG_addr = 0x00;


//I2C LCDに1byteのdataを書き込む
void I2C_write_data(uint8_t data){
I2C1_Write1ByteRegister(I2C_LCD_addr, (data | LCD_EN | LCD_BL),(data | LCD_BL));
__delay_us(100);
}

//I2C LCDにコマンドまたは文字を送る
void LCD_write(uint8_t data, uint8_t mode){
//上位4bitを送る
I2C_write_data((data & 0xF0) | mode);
//下位4bitを送る
I2C_write_data(((data << 4) & 0xF0) | mode);
}

//I2C LCD 初期化
void LCD_init(){
__delay_ms(40);
LCD_write(0x33,LCD_CMD);//8bit mode set 2回
LCD_write(0x32,LCD_CMD);//8bit mode set 1回,4bit mode set
LCD_write(0x06,LCD_CMD);//Entry mode set
LCD_write(0x0C,LCD_CMD);//display ON,cursol OFF,blink OFF
LCD_write(0x28,LCD_CMD);//Function set 4bit mode,2line
LCD_write(0x01,LCD_CMD);//Clear display
__delay_ms(1);
}

void LCD_home(){
LCD_write(0x02,LCD_CMD);
__delay_ms(1);
}

void LCD_cursor(uint8_t x,uint8_t y){
if(y == 0){
LCD_write(LCD_LINE1 + x,LCD_CMD);
}
if(y == 1){
LCD_write(LCD_LINE2 + x,LCD_CMD);
}
}

//1文字表示
void putch(char ch){
LCD_write(ch,LCD_CHR);
}

//時刻データをRTCに書き込む
void Time_data_write(){
//I2C1_Write1ByteRegister(RTC_addr,0x00,0x00);//先頭アドレス
I2C1_Write1ByteRegister(RTC_addr,SECOND,REG[0]);
I2C1_Write1ByteRegister(RTC_addr,MINUTE,REG[1]);
I2C1_Write1ByteRegister(RTC_addr,HOUR,REG[2]);
I2C1_Write1ByteRegister(RTC_addr,DAY,REG[3]);
I2C1_Write1ByteRegister(RTC_addr,DATE,REG[4]);
I2C1_Write1ByteRegister(RTC_addr,MONTH,REG[5]);
I2C1_Write1ByteRegister(RTC_addr,YEAR,REG[6]);
I2C1_Write1ByteRegister(RTC_addr,CTRL,REG[7]);
}

//RTCから時刻データを読みだし、REG[]に格納
void Time_data_read(){
I2C1_WriteNBytes(RTC_addr,&REG_addr,1);

I2C1_ReadNBytes(RTC_addr,&REG,7);
}

//Timeデータの表示
void Time_disp(){
LCD_home();
printf("20");
printf("%02x/",REG[6]);
printf("%02x/",REG[5]);
printf("%02x (",REG[4]);
printf(week[REG[3]]);
printf(")");
LCD_cursor(4,1);
printf("%02x:",REG[2]);
printf("%02x:",REG[1]);
printf("%02x",REG[0]);
}

void main(){
// initialize the device
SYSTEM_Initialize();
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();

LCD_init();

Time_data_write();//時刻をセット

while (1){
Time_data_read();//RTCから時刻データを読み込む
Time_disp(); //時刻を表示する
__delay_ms(1000);
}
}

-------------------------------------------------------------------------------------
ブレッドボードです。
プログタマは、PICKit3を使い、VDD=5Vは、外部から供給する設定にしています。


 ともかく、動作することができましたので、今後、Arduinoの時と同様に、時計として使えるようにしてしてみたいと思います。

最新の画像もっと見る

コメントを投稿