2024年5月31日金曜日

加速度センサ KXTC9-2050 / リアルタイムクロックRTC8564


加速度センサ KXTC9-2050



// ちゃんとうごいたReadDateTime.ino ただ毎回 rtc8564.cppで時刻あわせ必要!

#include <Arduino.h> //これが必要だった

#include <Wire.h>

#include <RTC8564.h> // send->write,recevie->


void setup()

{

  Serial.begin(9600);

 

  Rtc.begin();

}


void loop()

{


  delay(1000);

  

  Rtc.available();

  

  Serial.print(0x2000+Rtc.years(),HEX);

  Serial.print("/");

  Serial.print(Rtc.months(),HEX);

  Serial.print("/");

  Serial.print(Rtc.days(),HEX);

  Serial.print(" ");

  Serial.print(Rtc.hours(),HEX);

  Serial.print(":");

  Serial.print(Rtc.minutes(),HEX);

  Serial.print(":");

  Serial.println(Rtc.seconds(),HEX);

}

// RTC8564.h 

#ifndef RTC8564_h

#define RTC8564_h


#include <inttypes.h>


class RTC8564

{

private:

void init(void);

uint8_t _seconds;

uint8_t _minutes;

uint8_t _hours;

uint8_t _days;

uint8_t _weekdays;

uint8_t _months;

uint8_t _years;

bool _century;

public:

enum {

BCD = 0,

Decimal = 1,

};

RTC8564();

void begin(void);

void sync(uint8_t date_time[],uint8_t size = 7);

bool available(void);

bool isvalid(void);

uint8_t seconds(uint8_t format = RTC8564::BCD) const;

uint8_t minutes(uint8_t format = RTC8564::BCD) const;

uint8_t hours(uint8_t format = RTC8564::BCD) const;

uint8_t days(uint8_t format = RTC8564::BCD) const;

uint8_t weekdays() const;

uint8_t months(uint8_t format = RTC8564::BCD) const;

uint8_t years(uint8_t format = RTC8564::BCD) const;

bool century() const;

};


extern RTC8564 Rtc;


#endif

// extern "C" {

  #include <stdlib.h>

  #include <string.h>

  #include <inttypes.h>

}

// #include <WConstants.h> //原文は//なかったが入れた

#include <Arduino.h>

#include <Wire.h>

#include "RTC8564.h"


#define RTC8564_SLAVE_ADRS (0xA2 >> 1)

#define BCD2Decimal(x) (((x>>4)*10)+(x&0xf))


// Constructors ////////////////////////////////////////////////////////////////


RTC8564::RTC8564()

: _seconds(0), _minutes(0), _hours(0), _days(0), _weekdays(0), _months(0), _years(0), _century(0)

{

}


void RTC8564::init(void)

{

delay(1000);

Wire.beginTransmission(RTC8564_SLAVE_ADRS);

Wire.write(0x00); // write reg addr 00

Wire.write(0x20); // 00 Control 1, STOP=1

Wire.write(0x00); // 01 Control 2

Wire.write(0x00); // 02 Seconds

Wire.write(0x29); // 03 Minutes

Wire.write(0x17); // 04 Hours

Wire.write(0x31); // 05 Days

Wire.write(0x01); // 06 Weekdays

Wire.write(0x05); // 07 Months

Wire.write(0x24); // 08 Years

Wire.write(0x00); // 09 Minutes Alarm

Wire.write(0x00); // 0A Hours Alarm

Wire.write(0x00); // 0B Days Alarm

Wire.write(0x00); // 0C Weekdays Alarm

Wire.write(0x00); // 0D CLKOUT

Wire.write(0x00); // 0E Timer control

Wire.write(0x00); // 0F Timer

Wire.write(0x00); // 00 Control 1, STOP=0

Wire.endTransmission();

}

// Public Methods //////////////////////////////////////////////////////////////


void RTC8564::begin(void)

{

Wire.begin();

//if(isvalid() == false) //原文は//はなかったが上記の情報を入れるために入れた

init();

}


void RTC8564::sync(uint8_t date_time[],uint8_t size)

{

Wire.beginTransmission(RTC8564_SLAVE_ADRS);

Wire.write(0x00); // write reg addr 00

Wire.write(0x20); // 00 Control 1, STOP=1

Wire.endTransmission();

Wire.beginTransmission(RTC8564_SLAVE_ADRS);

Wire.write(0x02); // write reg addr 02

Wire.write(date_time, size);

Wire.endTransmission();

Wire.beginTransmission(RTC8564_SLAVE_ADRS);

Wire.write(0x00); // write reg addr 00

Wire.write(0x00); // 00 Control 1, STOP=0

Wire.endTransmission();

}


bool RTC8564::available(void)

{

uint8_t buff[7];

Wire.beginTransmission(RTC8564_SLAVE_ADRS);

Wire.write(0x02); // write reg addr 02

Wire.endTransmission();

Wire.requestFrom(RTC8564_SLAVE_ADRS, 7);

for(int i=0; i<7; i++){

if(Wire.available()){

buff[i] = Wire.read();

}

}

_seconds  = buff[0] & 0x7f;

_minutes  = buff[1] & 0x7f;

_hours   = buff[2] & 0x3f;

_days   = buff[3] & 0x3f;

_weekdays = buff[4] & 0x07;

_months   = buff[5] & 0x1f;

_years   = buff[6];

_century  = (buff[5] & 0x80) ? 1 : 0;

return (buff[0] & 0x80 ? false : true);

}


bool RTC8564::isvalid(void)

{

Wire.beginTransmission(RTC8564_SLAVE_ADRS);

Wire.write(0x02); // write reg addr 02

Wire.endTransmission();

Wire.requestFrom(RTC8564_SLAVE_ADRS, 1);

if(Wire.available()){

uint8_t buff = Wire.read();

return (buff & 0x80 ? false : true);

}

return false;

}


uint8_t RTC8564::seconds(uint8_t format) const {

if(format == Decimal) return BCD2Decimal(_seconds);

return _seconds;

}


uint8_t RTC8564::minutes(uint8_t format) const {

if(format == Decimal) return BCD2Decimal(_minutes);

return _minutes;

}


uint8_t RTC8564::hours(uint8_t format) const {

if(format == Decimal) return BCD2Decimal(_hours);

return _hours;

}


uint8_t RTC8564::days(uint8_t format) const {

if(format == Decimal) return BCD2Decimal(_days);

return _days;

}


uint8_t RTC8564::weekdays() const {

return _weekdays;

}


uint8_t RTC8564::months(uint8_t format) const {

if(format == Decimal) return BCD2Decimal(_months);

return _months;

}


uint8_t RTC8564::years(uint8_t format) const {

if(format == Decimal) return BCD2Decimal(_years);

return _years;

}


bool RTC8564::century() const {

return _century;

}



// Preinstantiate Objects //////////////////////////////////////////////////////


RTC8564 Rtc = RTC8564();

2024年5月25日土曜日

pic family/pic16f1938 and aqm1602

 

---------pic family--------------------------

16F876A       mpasm only  :: japanese  datasheet!  スペックは1827超え!
                           cf https://ww1.microchip.com/downloads/jp/devicedoc/30292a_jp.pdf 

16F84A        mpasm only :: morikita 

16F648          mpasm only :: morikita
 
12F1822       c without mcc :: japanese datasheet!
       cf https://ww1.microchip.com/downloads/jp/DeviceDoc/41413C_JP.pdf

12LF1840    これも一緒でサイト情報豊富


16F1827x2     c without mcc ::  mosinyaga 

16F1938       c without mcc :: japanse datasheet わりとサイト情報豊富
    cf https://ww1.microchip.com/downloads/jp/DeviceDoc/41574A_JP.pdf


16F1778       c with mcc :: 逆引き

16F18857     c with mcc :: 大全

16F18313      c with mcc :: 8ピン



---------------------------------

// https://wak-tech.com/archives/292 tmr1 pic16f1938 using original aqm1602 lib 

      // CONFIG1
                #pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
                #pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
                #pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
                #pragma config MCLRE = OFF      // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
                #pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
                #pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
                #pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
                #pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
                #pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
                #pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)

                // CONFIG2
                #pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
                #pragma config VCAPEN = OFF     // Voltage Regulator Capacitor Enable (All VCAP pin functionality is disabled)
                #pragma config PLLEN = ON// PLL Enable (4x PLL disabled)
                #pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
                #pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
                #pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)

                // #pragma config statements should precede project file includes.
                // Use project enums instead of #define for ON and OFF.

                #include <xc.h>
                #include <pic16f1938.h>
                #include <math.h>
                #include <stdio.h>
                #define _XTAL_FREQ 32000000
                #define LCD_ADD 0x7C
                #define sound RA1
                int timer = 0;


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

                void I2C_Master_Wait()
                {
                  while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));
                }

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

                void I2C_Master_RepeatedStart()
                {
                  I2C_Master_Wait();
                  RSEN = 1;
                }

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

                void I2C_Master_Write(unsigned d)
                {
                  I2C_Master_Wait();
                  SSPBUF = 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 = 0b01110000;
                  ANSELA = 0b00000000;
                  ANSELB = 0b00000000;
                  TRISA  = 0b00000000;
                  TRISB  = 0b00000000;
                  TRISC  = 0b00011000;
                  PORTA  = 0b00000000;    //2進数で書いた場合
                  PORTB  = 0x00;          //16進数で書いた場合
                }
                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() isr(){               //割り込み関数
                volatile static int intr_counter;
                GIE = 0;
                if(TMR1IF == 1){
                  TMR1H = (55536 >>8);            //タイマー1の初期化(65536-10000=55536);
                  TMR1L = (55536 & 0x00ff);

                  intr_counter++;
                  if(intr_counter == 100){        //1sec周期でtimerに1を足す
                    timer++;
                    intr_counter = 0;
                  }
                  TMR1IF = 0;                     //割り込みフラグを落とす
                }
                GIE = 1;
            }
            void intrInit(){                    //割り込みの初期設定
                T1CON = 0b00110001;             //内部クロックの4分の1で,プリスケーラ1:8でカウント
                TMR1H = (55536 >>8);            //タイマー1の初期化(65536-10000=55536);
                TMR1L = (55536 & 0x00ff);
                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);
                  }
                }
    

PIC16F1827 NO MCC AND SB1602/arduinoide linux and sb1602

 http://zattouka.net/GarageHouse/micon/MPLAB/12F1822/LCD/LCD.htmで成功!

SNAPはLVP原則なのでLVP OFFで書き込んだらPICKIT3でLVP ONで書き直す必要があった!

このライブラリはよくできておりAQM0802などのためのものだそうだがPIC16F1827とSB1602で動いた!MCC不要だった。

 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

https://qiita.com/ma2shita/items/927aa9e55962b4137518

 文字化けは直した(file setting でenglish)

https://ore-kb.net/archives/195を参考に、https://github.com/tomozh/arduino_ST7032/tree/masterをzip libインストしてexample のハローワールドがdefaultのscl/sdaでつかえる RSも10Kオームでプルアップすること

/*
    ST7032 I2C LCD control sample
    Original source : HelloWorld.ino (LiquidCrystal Library)
    2013/05/21 tomozh@gmail.com
*/

/*
  LiquidCrystal Library - Hello World
 
 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.
 
 This sketch prints "Hello World!" to the LCD
 and shows the time.
 
  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 22 Nov 2010
 by Tom Igoe
 
 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
//#include <LiquidCrystal.h>
#include <Wire.h>
#include <ST7032.h>

// initialize the library with the numbers of the interface pins
//LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
ST7032 lcd;

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  lcd.setContrast(40);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis()/1000);
}

2024年5月18日土曜日

ambient pedia

 ESP32でBME280から取得したデータをAmbientに送信する | Wak-tech 

bme280をi2cで使う際は注意が必要(秋月パンフみること,GNDに2個おとす!)

Arduino ESP8266で温度・湿度を測定し、Ambientに送ってグラフ化する – Ambient (ambidata.io) これを改変するがサイトにグラフ化の手順も書いている 便利

#include <WiFi.h>

#include <Wire.h>

#include <Adafruit_Sensor.h>

#include <Adafruit_BME280.h>

#include "Ambient.h"

#define PERIOD 300

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme;

WiFiClient client;

Ambient ambient;


unsigned long delayTime;

float temp;

float pressure;

float humid;


const char* ssid = "";

const char* password = "";


unsigned int channelId = 78037;

// AmbientのチャネルID

const char* writeKey = "1cee9795917843b8"; // ライトキー


void setup() {

  Serial.begin(115200);

  bool status;

  status = bme.begin(0x76);  

  while (!status) {

    Serial.println("BME280 sensorが使えません");

    delay(1000);

  }

  delayTime = 1000;

  WiFi.begin(ssid, password);  //  Wi-Fi APに接続

    while (WiFi.status() != WL_CONNECTED) {  //  Wi-Fi AP接続待ち

        delay(100);

    }


  Serial.print("WiFi connected\r\nIP address: ");

  Serial.println(WiFi.localIP());

  ambient.begin(channelId, writeKey, &client); // チャネルIDとライトキーを指定してAmbientの初期化

}

void loop() { 

  temp=bme.readTemperature();

  pressure=bme.readPressure() / 100.0F;

  humid=bme.readHumidity();

  Serial.print("温度 ;");

  Serial.print(temp);

  Serial.println(" °C");

   

  Serial.print("気圧 ;");

  Serial.print(pressure);

  Serial.println(" hPa");

  Serial.print("湿度 ;");

  Serial.print(humid);

  Serial.println(" %");

  Serial.println();

  delay(delayTime);

  ambient.set(1, temp); // 温度をデータ1にセット

  ambient.set(2, humid); // 湿度をデータ2にセット

  ambient.set(3, pressure); // 気圧をデータ3にセット


  ambient.send(); // データをAmbientに送信


  delay(PERIOD * 1000);

}

2024年5月12日日曜日

PIC16F1827で超音波距離/esp01sをAT/3端子レギュレータ

/* 

 *  超音波センサモジュールHC-SR04をタイマ1のゲート制御で 【16F1827】

 *    timer1_gate/main.c  Created on 2024/04/23, 9:04

 */

// config1

#pragma config FOSC = INTOSC , WDTE = OFF , PWRTE = ON , MCLRE = ON , CP = OFF , CPD = OFF

#pragma config BOREN = OFF , CLKOUTEN = OFF , IESO = OFF , FCMEN = OFF

// config2

#pragma config WRT = OFF , PLLEN = OFF , STVREN = ON , LVP = OFF 

#include <xc.h>

#include <stdio.h>

#include "aqm1602.h"

#define _XTAL_FREQ 8000000

long echo_time;

long dist;

char title[] = "Distance";

char data[16];

int main(void){

    OSCCON = 0x72;          // 8MHz    

    ANSELA = 0;

    ANSELB = 0;

    TRISA = 0b00010000;     // RA5:MCLR RA0:Trig

    TRISB = 0b00010011;     // RB0:Echo RB1:SDA1 RB4:SCL1 

    PORTA = 0;

    PORTB = 0;

    

    T1CON  = 0b00010001 ;   // FOSC/4を選択 分周比1/2 タイマー1開始

    T1GCON = 0b11010000 ;   

 // ゲート有効、Hiでカウント、シングルパルス、ゲートピン(RB0)

    LCD_Init();             // LCDの初期化9iu8u0

    // whileの直前においた

    while (1){

        // タイマ1のカウンタ準備

        TMR1 = 0;       // カウンタの初期化

        T1GGO = 1;      // シングルパルス検出待ち(ゲート制御開始))

        // トリガ送信(10us)

        RA0 = 1;

        __delay_us( 10 );

        RA0 = 0;

        // エコー信号のON待ち

        while (RB0 == 0){}     

        // エコー信号のOFF待ち

        while (RB0 == 1){}

        // 超音波の往復時間を取得

        echo_time = TMR1;

        // パルス時間から距離(cm)に変更

        dist = (echo_time / 2) * 34 / 1000;

       

        // 数値を文字列に変換 

        sprintf(data, "%ld", dist);


        LCD_clear();  

      LCD_home();

        LCD_str(title);

        LCD_locate(2,2);

        LCD_str(data);

        LCD_locate(2,6);

        LCD_str("cm");     

        __delay_ms( 1000 );

    }

}

// 吉野さんオリジナルだが 超音波距離センサ | DIYのホームページ (ease-labs.com)

// も参考にした whileのたびにlcd_initは冗長なのでwhile直前においた

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

 ch340が乗っているUSB書き込み機でprogにしてファームウエア書き込む  いつのまにか。。。。。

---------------------------------------------------------------------------

3.3Vレギュレーターとの接続方法 (hiramine.com) 7223の使い方

もう一つの小さい2950は以下を参考に




2024年5月11日土曜日

pic16f1827 and acm1602 success code モシニャガ

 /*

 *      I2CLCD_lib

 */


#include <xc.h>

#include "I2CLCD.h"

#define _XTAL_FREQ 8000000


void I2C_init(void){

  TRISB |= 0b00010010;          //RB4(SCL1),RB1(SDA1)

  OPTION_REGbits.nWPUEN = 0;    // 0:PORTB内部プルアップのため

  WPUB  |= 0b00010010;          //RB4 and RB1 are weakpulluped!

  SSP1CON1 = 0b00101000;        // I2C master mode

  SSP1STAT = 0b00000000;        // I2C status

  SSP1ADD = 39;                 // I2C clock 50khz=8mhz/(4(39+1))

  return;

}

void I2C_start(void){

  SSP1CON2bits.SEN=1;

  while(SSP1CON2bits.SEN);

  return;

}

void I2C_stop(void){

  SSP1CON2bits.PEN=1;

  while(SSP1CON2bits.PEN);

  return;

}

void I2C_byte_write(unsigned char byte){

  SSP1IF=0;

  SSP1BUF=byte;

  while(!SSP1IF);

  while(SSP1CON2bits.ACKSTAT);  // wait for ACK return

  SSP1IF=0;

  return;

}

void I2C_LCD_cmd_write(unsigned char command){

  I2C_start();

  I2C_byte_write(0xA0);         //slave address

  I2C_byte_write(0x00);

  I2C_byte_write(command);

  I2C_stop();

  return;

}

void I2C_LCD_data_write(char data){

  I2C_start();

  I2C_byte_write(0xA0);         //slave address

  I2C_byte_write(0x80);

  I2C_byte_write(data);

  I2C_stop();

  return;

}

void LCD_init(void){

  I2C_init();

  I2C_LCD_cmd_write(0x38);

  __delay_ms(5);

  I2C_LCD_cmd_write(0x0C);

  __delay_ms(5);

  I2C_LCD_cmd_write(0x06);

  __delay_ms(5);

  I2C_LCD_cmd_write(0x01);

  __delay_ms(5);

  return;

}

void LCD_clear(void){

  I2C_LCD_cmd_write(0x01);

  __delay_ms(5);

  return;

}

void LCD_locate(unsigned char row,unsigned char col){

  unsigned char addr;

  switch(row){

    case 0: addr=0x00;

            break;

    case 1: addr=0x40;

            break;

  }

  if(col>15)

   col=0;

  addr+=col;

  addr|=0x80;

  I2C_LCD_cmd_write(addr);

  return;

}

void LCD_putc(char word){

  I2C_LCD_data_write(word);

  return;

}

void LCD_puts(char *string){

  unsigned char i;

  for(i=0;string[i]!='\0';++i){

    LCD_putc(string[i]);

    __delay_ms(5);

  }

  return;

}


  /*

 *      I2CLCD

 */


#include <xc.h>


#ifndef I2CLCD_LIB_H

#define I2CLCD_LIB_H


void I2C_init(void);

void I2C_start(void);

void I2C_stop(void);

void I2C_byte_write(unsigned char byte);

void I2C_LCD_cmd_write(unsigned char command);

void I2C_LCD_data_write(char data);

void LCD_init(void);

void LCD_clear(void);

void LCD_locate(unsigned char row,unsigned char col);

void LCD_putc(char word);

void LCD_puts(char *string);


#endif


/*

 *  I2C ACM1602NI 【16F1827】

 *   ACM1602NI/main.c  Created on 2024/05/06, 12:02

 */


// config1

#pragma config FOSC = INTOSC , WDTE = OFF , PWRTE = ON , MCLRE = ON , CP = OFF , CPD = OFF

#pragma config BOREN = OFF , CLKOUTEN = OFF , IESO = OFF , FCMEN = OFF

// config2

#pragma config WRT = OFF , PLLEN = OFF , STVREN = ON , LVP = OFF 


#include <xc.h>

#include "I2CLCD.h"

#define _XTAL_FREQ 8000000


char moji[] = "Hello,world!";

char moji2[] = "PIC16F1827";

char moji3[] = "OK";


int main(void){

    OSCCON=0x72;            // 8MHz

    ANSELA=0x00;

    ANSELB=0x00;

    TRISA=0x00;

    TRISB=0x12;             // 0b00010010

    PORTB=0x00; // これはあってもなくてもOKだった

  PORTA=0x00; // これはあってもなくてもOKだった

    

    LCD_init();             // LCDの初期化

    LCD_clear();            // 画面をクリア   

    

    LCD_locate(0,1);        // 1行目、2文字(列)目へ移動

    LCD_puts(moji);

    LCD_locate(1,3);        // 2行目、4文字(列)目へ移動

    LCD_puts(moji2);

    LCD_locate(1,14);       // 2行目、15文字(列)目へ移動

    LCD_puts(moji3);

    

    while(1){}


}    

吉野さんのおかげで成功 最初失敗したのはmain.cでTRISB設定をミスっていた?

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);
    }
}