2024年5月11日土曜日

PIC16F1827にRTCを実現 カウント開始まで数秒かかるのが課題

// https://wak-tech.com/archives/292#google_vignette をpic16f1827用に

// #pragma config FOSC = LP    
// 32.768khz eternal oscillatorをモシニャガでは指定しているが LPでもINOSCでも動いた
// PCinitでOSCCONを8Mhzにしているので無視されるのかも

#pragma config FOSC = INTOSC, WDTE = OFF , PWRTE = ON , MCLRE = ON , CP = OFF ,
#pragma config CPD = OFF, BOREN = OFF , CLKOUTEN = OFF , IESO = OFF 
#pragma config FCMEN = OFF,WRT = OFF , PLLEN = OFF , STVREN = ON , LVP = OFF 

#include <xc.h>
#include <stdio.h>
#define _XTAL_FREQ 8000000
#define LCD_ADD 0x7C
  
int timer = 0;

void I2C_Master_Init(const unsigned long c)
{
    SSP1CON1 = 0b00101000;
    SSP1CON2 = 0;
    SSP1ADD = (_XTAL_FREQ/(4*c))-1;
    SSP1STAT = 0b00000000 ;    // 標準速度モードに設定する(100kHz)
}

 void I2C_Master_Wait()
 {
    while ((SSP1STAT & 0x04) || (SSP1CON2 & 0x1F));
}

void I2C_Master_Start()
{
    I2C_Master_Wait();
    SSP1CON2bits.SEN = 1;
}

void I2C_Master_Stop()
{
    I2C_Master_Wait();
    SSP1CON2bits.PEN = 1;
}

void I2C_Master_Write(unsigned d)
{
     I2C_Master_Wait();
     SSP1BUF = d;
 }
                
void writeData(char t_data)
{
     I2C_Master_Start();
     I2C_Master_Write(LCD_ADD);
    I2C_Master_Write(0x40);
    I2C_Master_Write(t_data);
    I2C_Master_Stop();
    __delay_ms(10);
}

void writeCommand(char t_command){
    I2C_Master_Start();
    I2C_Master_Write(LCD_ADD);
    I2C_Master_Write(0x00);
    I2C_Master_Write(t_command);
    I2C_Master_Stop();
     __delay_ms(10);
}

void PICinit(){
    OSCCON = 0x72;
    ANSELA = 0b00000000;
    ANSELB = 0b00000000;
    TRISA  = 0b00000000;
    TRISB = 0x12; // inputpullup for sda scl
     // 0b00010010 RB4,RB1 inpu
    PORTA  = 0b00000000;   
    PORTB  = 0b000000000;
                }

 void LCD_Init(){            //LCDの初期化
    I2C_Master_Init(100000);
    __delay_ms(400);
    writeCommand(0x38);
    __delay_ms(20);
    writeCommand(0x39);
    __delay_ms(20);
    writeCommand(0x14);
    __delay_ms(20);
    writeCommand(0x73);
    __delay_ms(20);
    writeCommand(0x52);
    __delay_ms(20);
    writeCommand(0x6C);
    __delay_ms(250);
    writeCommand(0x38);
    __delay_ms(20);
    writeCommand(0x01);
    __delay_ms(20);
    writeCommand(0x0C);
    __delay_ms(20);
}

void LCD_str(char *c)  //LCDに配列の文字を表示
{    
    unsigned char i,wk;
    for (i=0 ; ; i++) {
        wk = c[i];
        if  (wk == 0x00) {break;}
        writeData(wk);
    }
}

void __interrupt() TMR1_interrupt(){               //割り込み関数

     GIE = 0;
     if(TMR1IF == 1){
        TMR1H = 0x80;            //タイマー1の初期化
        TMR1L = 0x00;
timer++;
        TMR1IF = 0;                     //割り込みフラグを落とす
    }
    GIE = 1;
}
            
void intrInit(){                    //割り込みの初期設定
    T1CON = 0b10001101;             //extern clock ,prescla 1,lp osc,txsync,_0_,timer1
    TMR1H = 0x80;            //タイマー1の初期化
    TMR1L = 0x00;
    TMR1IF = 0;                     //タイマー1割り込みフラグを0にする
    TMR1IE = 1;                     //タイマー1割り込みを許可する
    INTCONbits.GIE = 1;              //グローバル割り込みを許可
    INTCONbits.PEIE = 1;             //割り込みを許可
 }

int main(void)
{
    PICinit();      //PICを初期化
    LCD_Init();
    intrInit();
    char time[16];
    while(1){
       sprintf(time,"Timer:%d",timer);
       writeCommand(0x02);
       LCD_str(time);
    }
}

   

0 件のコメント:

コメントを投稿