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にしてファームウエア書き込む

https://www.alselectro.com/esp8266---01-module.html より書き込みソフトをゲット

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

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

   

2024年4月24日水曜日

PIC16f1827 and aqm1602 success code

AQM1602_rev2.pdf (akizukidenshi.com) にて半田するのでモシニャガ本のpullup不要

> コピペで超簡単!PICマイコンでI2C接続のLCD(AQM1602)を使う【PIC16F1938】 | Wak-tech のコードをみているとsda,sclをプルアップしていません 同サイトの回路をみてもプルアップ抵抗が使われていません これでうごくのでしょうか?
<私もこのサイトを参考にさせていただきました。秋月の付属データシートには「基板上のプルアップ抵抗(10KΩ)」をはんだするか、別途プルアップ抵抗を接続するように書いています。私ははんだして同サイトのようにしました
> (ちなみにモシニャガ先生はソフト的にsda,sclをweak pullupする方法をとっていました) それとsda,sclをinputにしておくのはackを受け取るためでしょうか sda/sclをinputにしておいてもPICからLCDに命令がだせるのはなぜでしょうか?
<先にお送りしたAQM1602のライブラリではハードでプルアップしていますのでこのコードはありません。ソフトプルアップするにはポートをINPUTにする必要があり、OUTPUTではプルアップできません。ACM1602NIの回路図ではSDA,SCLをプルアップするように指定されていますので、このようなコードになっているのではないでしょうか。
よろしくお願いします。

//コピペで超簡単!PICマイコンでI2C接続のLCD(AQM1602)を使う【PIC16F1938】 | Wak-tech を参考にしているとのこと

 /* from yosino san

 *  AQM1602 【16F1827】

 *   AQM1602/main.c   Created on 2024/04/20, 21:48

 */

// 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>

#define _XTAL_FREQ 8000000

#define LCD_ADD 0x7C // 下記参照

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

char moji2[] = "PIC16F1827";

void I2C_Master_Init(const unsigned long c){

 // OPTION_REGbits.nWPUEN = 0; // この2行はプルアップ半田したので不要

   // WPUB    |= 0b00010010;

    SSP1CON1 = 0b00101000;

    SSP1CON2 = 0; 

    SSPADD = (_XTAL_FREQ/(4*c))-1; // これでcに1000000 つまり100khZを入れる

   // つまり SSP1ADD = 19;                 // (_XTAL_FREQ / (4*c))-1;

    SSP1STAT = 0b00000000 ;    // 標準速度モードに設定する(100kHz)

}

void I2C_Master_Wait(){

    while ((SSP1STAT & 0x04) || (SSP1CON2 & 0x1F));

// start sequence 検出 または acken=1 & rcen=1 & pen=1 & rsen=1 & sen=1

// https://nukomabo.work/post-528/ ssp1stat == 0x04 は送信中

// 【PIC】I2C通信のやり方 | 理系男子の電子工作 (rikeden.net) では後半も含めて

//  trasnmission is in progresと表現

// cf I2C温度センサーLM75ADをPIC12F1822で使う (r271-635) (netlog.jpn.org)

}

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

    }

}


int main(void){

 OSCCON=0x72;            // 8MHz

    ANSELA=0x00;

    ANSELB=0x00;

    TRISA=0x00;

    TRISB=0x12;             // 0b00010010 for sda and scl

    PORTB=0x00;

    LCD_Init();

    writeCommand(0x01); //画面をクリア

    __delay_ms(20);

    writeCommand(0x02); //ホームへカーソル移動

    __delay_ms(2);                  // LCD側の処理待ち


    while(1){

        writeCommand(0x02);         //ホームへカーソル移動

        LCD_str(moji);

        writeCommand(0x40+0x80);    //2列目へ移動

        __delay_ms(200);

        LCD_str(moji2);

        __delay_ms(1000);

        writeCommand(0x01); //画面をクリア

        __delay_ms(200);

    }

    return 0;

}

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

I2C接続AQMシリーズのキャラクタ表示LCDをArduinoで使う (2) AQM1602 | 電子工作の環境向上 (denshi.club) より 上記0x7cはwriteの0を含んでいる!

※ライブラリFaBoLCDmini_AQM0802Aのヘッダ・ファイルには、スレーブ・アドレスが、0x3eと固定されています。AQM1602のデータシートには0x7cと書かれています。マスタがスレーブのLCDに対してスレーブ・アドレスを指定するとき、最後にRead/Writeビットを追加します。LCDはライト・オンリなので、8ビットの0x7c(01111100)の最後のwriteビット0を取り去ると0111110=0x3eになります。

ーーーーーーーーーーー以下をheader,lib,mainにわけたーーーーーーーーーーーーーーーーーーー

/* 

 *   AQM1602 ライブラリ用 ヘッダファイル aqm1602.h

 */


#include <xc.h> 


#ifndef AQM1602_H

#define AQM1602_H


void I2C_Master_Init(const unsigned long c);

void I2C_Master_Wait(void);

void I2C_Master_Start(void);

void I2C_Master_Stop(void);

void I2C_Master_Write(unsigned char d);

void writeData(unsigned char t_data);

void writeCommand(unsigned char t_command);

void LCD_Init(void);                                    // LCDの初期化

void LCD_str(char *c);                                  // LCDに配列の文字を表示

void LCD_clear(void);                                   // LCDの画面をクリア

void LCD_home(void);                                    // LCDのカーソルをホームへ

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

// LCDのカーソル位置を指定(行,列))

// 行:1,2 列:1~16

#endif

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

/*
 *   AQM1602用 ライブラリ関数 aqm1602.c
 */

#include <xc.h>
#include "aqm1602.h"

#define _XTAL_FREQ 8000000
#define LCD_ADD 0x7C

void I2C_Master_Init(const unsigned long c){
    SSP1CON1 = 0b00101000;
    SSP1CON2 = 0;
    SSPADD = (_XTAL_FREQ/(4*c))-1; // これでcに1000000 つまり100khZを入れる
   // SSP1ADD = 19;                 // (_XTAL_FREQ / (4*c))-1;
    SSP1STAT = 0b00000000 ;       // 標準速度モードに設定する(100kHz)
}
void I2C_Master_Wait(void){
    while ((SSP1STAT & 0x04) || (SSP1CON2 & 0x1F));
}
void I2C_Master_Start(void){
    I2C_Master_Wait();
    SSP1CON2bits.SEN = 1;
}
void I2C_Master_Stop(void){
    I2C_Master_Wait();
    SSP1CON2bits.PEN = 1;
}
void I2C_Master_Write(unsigned char d){
    I2C_Master_Wait();
    SSP1BUF = d;
}
void writeData(unsigned 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(unsigned 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 LCD_Init(void){           
    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) {     
    unsigned char i,wk;
    for (i=0 ; ; i++) {
      wk = c[i];
      if  (wk == 0x00) {break;}
      writeData(wk);
    }
}
void LCD_clear(void){
    writeCommand(0x01);
    __delay_ms(5);
}
void LCD_home(void){
    writeCommand(0x02);
    __delay_ms(5);
}
void LCD_locate(unsigned char row, unsigned char col){
    char addr;
    switch(row){
        case 1: addr = 0x00; break;
        case 2: addr = 0x40; break;
    }
    if (col > 0x15)
        col = -1;
    addr += col - 1;
    addr |= 0x80;
    writeCommand(addr);
    __delay_ms(5);
}
ーーーーーーーーーーーーーーー
// 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
#define LCD_ADD 0x7C

char moji[] = "Hello, PIC World!";
char moji2[] = "Wak-tech";
int main(void){
      
OSCCON = 0x72; // 8MHZ
ANSELA = 0x00; // RA DIGITAL
ANSELB = 0x00; // RB DIGITAL
TRISA = 0b00000000;
TRISB = 0x12; // pulluped input for sda scl
PORTA = 0;
PORTB = 0;
 // OPTION_REGbits.nWPUEN = 0; // この2行はプルアップ半田したので不要
 // WPUB    |= 0b00010010;   
  LCD_Init();
  writeCommand(0x01); //画面をクリア
  __delay_ms(20);
 writeCommand(0x02); //ホームへカーソル移動
 __delay_ms(2); // LCD側の処理待ち

   while(1){
          writeCommand(0x02);   //ホームへカーソル移動
          LCD_str(moji);
          writeCommand(0x40+0x80); //2列目へ移動
          __delay_ms(200);
          LCD_str(moji2);
          __delay_ms(1000);
          writeCommand(0x01); //画面をクリア
          __delay_ms(200);
  }
  return 0;
}

2024年4月20日土曜日

PIC weakpullup,I2C speed,US距離、

 P176の質問です 勝手にled点滅がおこります ウィークプルアップ不良?



こんばんは。テストしてみました。おっしゃる通りです。約5秒消灯、約5秒点滅を繰り返しています。
「8ピンPIC…」にも書いていましたが、内部抵抗は約40KΩ相当で流れる電流は25uAらしいです。
ノイズに弱いのでスイッチとの距離が長いとかノイズが多いときは抵抗の外付けを推奨していました。
テストでは電源に47uFと0.1uFのコンデンサを付け、スイッチもすぐ横につけましたがすぐに点滅し始めました。
1827のデータシートを見ると内部プルアップ時の電流は5Vで25~300uAとありました。ということは200Kから17KΩということですか。
AVRリファレンスではATmega44/88/168で20~50KΩとなっていました。
なんのノイズを拾うのでしょうかね。しかも一定周期で???

追伸です。失礼しました。以下の一行を WPUB4  = 1;       // RB4 weak pullupedの前に追加してください。

OPTION_REGbits.nWPUEN = 0;   // PORTB プルアップ有効
OPTION_REG 34,35ページ、それと45ページ1から3行あたりご参照ください。
初期値は「nWPUENは’1’、全WPU不可(MCLR除く)」になっています。よろしくお願いします。
--------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------

2024年4月15日月曜日

dht11 and lcd1602-i2c code / keypad

// http://7ujm.net/micro/i2clcd.html // nano and atmega328p-8mhz both success // arduino as isp(nano)10->atmega8 1pin,11->same 11,12->same 12,13->same 13 #include //アドレス0x27 16文字2行の液晶 LiquidCrystal_I2C lcd(0x27, 16, 2); #include // ライブラリのインクルード #define DHT_PIN 7 // DHT11のDATAピンをデジタルピン7に定義 1wire #define DHT_MODEL DHT11 // 接続するセンサの型番を定義する(DHT11やDHT22など) DHT dht(DHT_PIN, DHT_MODEL); // センサーの初期化 void setup() { dht.begin(); // センサーの動作開始 lcd.init(); // lcd initialize lcd.backlight(); } void loop() { delay(2000); // センサーの読み取りを2秒間隔に lcd.clear(); float Humidity = dht.readHumidity(); // 湿度の読み取り float Temperature = dht.readTemperature(); // 温度の読み取り(摂氏) if (isnan(Humidity) || isnan(Temperature)) { // 読み取りのcheck return; } lcd.setCursor(0, 0); lcd.print("humid "); lcd.print(Humidity,DEC); lcd.setCursor(0, 1); lcd.print("temp "); lcd.print(Temperature,DEC); } ------------------------------------------------------------------------ //https://novicengineering.com/arduino%E3%82%92%E7%94%A8%E3%81%84%E3%81%A6%E3%83%86%E3%83%B3%E3%82%AD%E3%83%BC%E3%83%91%E3%83%83%E3%83%89%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B/ #include const byte ROWS = 4; //4行のキーパッドを使用 const byte COLS = 4; //4列のキーパッドを使用 char keys[ROWS][COLS] = { //配列を表す {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} }; byte rowPins[ROWS] = {9, 8, 7, 6}; //接続するピン番号 byte colPins[COLS] = {5, 4, 3, 2}; Keypad customKeypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS); //キーパッドの初期化 void setup(){ Serial.begin(9600); } void loop(){ char customKey = customKeypad.getKey();//押されたキーを検出 if (customKey){ Serial.println(customKey); } }

2024年4月4日木曜日

7 segment pedia(CATHODE+TC4511,ANODE)


https://nobita-rx7.hatenablog.com/entry/2020/09/13/011558 

TC4511BPでBCD入力でカソードコモン7セグの操作 配線が詳しい


#define TC4511_LE 6

#define TC4511_BI 5

#define TC4511_LT 4

#define TC4511_D 7

#define TC4511_C 3

#define TC4511_B 2

#define TC4511_A 8


void setup() {

  Serial.begin(9600);

  pinMode(TC4511_LE, OUTPUT);

  pinMode(TC4511_BI, OUTPUT);

  pinMode(TC4511_LT, OUTPUT);

  pinMode(TC4511_D, OUTPUT);

  pinMode(TC4511_C, OUTPUT);

  pinMode(TC4511_B, OUTPUT);

  pinMode(TC4511_A, OUTPUT);

}


#define Array 19

bool Val[Array][7] ={

 /*LE,BI,LT, D, C, B, A*/

  { 0, 0, 0, 0, 0, 0, 0},  //0:8         ※優先順位1位(条件:                  LT=0)

  { 0, 0, 1, 0, 0, 0, 0},  //1:Blank     ※優先順位2位(条件:         BI=0 and LT=1)

  { 1, 1, 1, 0, 0, 0, 0},  //2:前回値保持 ※優先順位3位(条件:LE=1 and BI=1 and LT=1)

  { 0, 1, 1, 0, 0, 0, 0},  //3:0     ※以下優先順位4位(条件:LE=0 and BI=1 and LT=1)

  { 0, 1, 1, 0, 0, 0, 1},  //4:1

  { 0, 1, 1, 0, 0, 1, 0},  //5:2

  { 0, 1, 1, 0, 0, 1, 1},  //6:3

  { 0, 1, 1, 0, 1, 0, 0},  //7:4

  { 0, 1, 1, 0, 1, 0, 1},  //8:5

  { 0, 1, 1, 0, 1, 1, 0},  //9:6

  { 0, 1, 1, 0, 1, 1, 1},  //10:7

  { 0, 1, 1, 1, 0, 0, 0},  //11:8

  { 0, 1, 1, 1, 0, 0, 1},  //12:9

  { 0, 1, 1, 1, 0, 1, 0},  //Blank

  { 0, 1, 1, 1, 0, 1, 1},  //Blank

  { 0, 1, 1, 1, 1, 0, 0},  //Blank

  { 0, 1, 1, 1, 1, 0, 1},  //Blank

  { 0, 1, 1, 1, 1, 1, 0},  //Blank

  { 0, 1, 1, 1, 1, 1, 1},  //Blank

} ;


void loop() {

  for (int i = 3; i < 13; i++) { // 3=>0,13=>ARRAY ORIGINAL 

    Serial.println(i);

    digitalWrite(TC4511_LE, Val[i][0]);

    digitalWrite(TC4511_BI, Val[i][1]);

    digitalWrite(TC4511_LT, Val[i][2]);

    digitalWrite(TC4511_D, Val[i][3]);

    digitalWrite(TC4511_C, Val[i][4]);

    digitalWrite(TC4511_B, Val[i][5]);

    digitalWrite(TC4511_A, Val[i][6]);

    delay(1000);

  }

}

// https://nobita-rx7.hatenablog.com/entry/2020/09/13/011558

おはようございます。遅くまでやっていますね。

> AVマイコンプログラミング入門 258pで2sc1815を使う場合 スイッチする端子から
> 10kΩ経由で(15kΩの抵抗を分岐してGNDにつなぎつつ)ベースにつないでいます
> この理由がわかりません 電流がながれんときに確実にGNDにおちるように?
> (ちなみにモシニャガ先生本では55pで10kΩの抵抗のみベースにつないでいました)

Webより抜粋です。
『抵抗R3,4について
以下の理由で抵抗R3,4を入れた方が良いらしいです、抵抗値はR1,2と同じ値でOKですね。
・コレクタしゃ断電流(ICBO=0.6uA)の為にベースに漏れ電流が流れる、これにより(ICBO x hFE:0.6uA x 200)0.12mAの電流がコレクタに流れるのでその電流を逃がす必要が有る。
・ベースの入力に、トライステート出力やオープンコレクタ出力やスイッチなどを繋いだ場合にその信号がオープンになる可能性があり、オープンになるとICBOの漏れ電流の影響によりコレクタ電流が不安定になります、よって確実にトランジスタをON/OFFさせる必要が有ります。
・また、抵抗R1,2が断線した時や、R1,2の値が非常に大きい時において、外来ノイズによりトランジスタがON してしまう可能性が有るのでこれを防ぐ役目も有ります。』
それと2SC1815のベース・エミッタ間の最大電圧は5Vなので、抵抗R3,4を入れたほうが良いかもしれません。
よろしくお願いします。

-------ANODE COMMON---------------static点灯----------------------------

まずはUnoで試運転 led 抵抗は1kΩとした 

// https://burariweb.info/electronic-work/arduino-learning/arduino-7segment-led.html

// Arduino入門編㉔ 7セグメントLEDを制御する①

// https://burariweb.info

// 7セグメントLED配列

//         A(D2)

//        -------

//  F(D7)|       |B(D3)

//       | G(D8) |

//         -----

//       |       |

//  E(D6)|       |C(D4)

//        -------      .DP

//         D(D5) 

const int ASeg = 2;

const int BSeg = 3;

const int CSeg = 4;

const int DSeg = 5;

const int ESeg = 6;

const int FSeg = 7;

const int GSeg = 8;

 void setup() {

  pinMode(ASeg, OUTPUT);

  pinMode(BSeg, OUTPUT);

  pinMode(CSeg, OUTPUT);

  pinMode(DSeg, OUTPUT);

  pinMode(ESeg, OUTPUT);

  pinMode(FSeg, OUTPUT);

  pinMode(GSeg, OUTPUT);

}

void loop() {

  zero();

  delay(500);

  one();

  delay(500);

  two();

  delay(500);

  three(); 

  delay(500);

  four();

  delay(500);

  five(); 

  delay(500);

  six(); 

  delay(500);

  seven();

  delay(500);

  eight();

  delay(500);

  nine();

  delay(500);

}

// LED表示関数の定義

// 0を表示

void zero() {

  digitalWrite(ASeg, LOW);

  digitalWrite(BSeg, LOW);

  digitalWrite(CSeg, LOW);

  digitalWrite(DSeg, LOW);

  digitalWrite(ESeg, LOW);

  digitalWrite(FSeg, LOW);

  digitalWrite(GSeg, HIGH);

}

// 1を表示

void one() { 

  digitalWrite(ASeg, HIGH);

  digitalWrite(BSeg, LOW);

  digitalWrite(CSeg, LOW);

  digitalWrite(DSeg, HIGH);

  digitalWrite(ESeg, HIGH);

  digitalWrite(FSeg, HIGH);

  digitalWrite(GSeg, HIGH);

}

// 2を表示

void two() {

  digitalWrite(ASeg, LOW);

  digitalWrite(BSeg, LOW);

  digitalWrite(CSeg, HIGH);

  digitalWrite(DSeg, LOW);

  digitalWrite(ESeg, LOW);

  digitalWrite(FSeg, HIGH);

  digitalWrite(GSeg, LOW);

}

// 3を表示

void three() {

  digitalWrite(ASeg, LOW);

  digitalWrite(BSeg, LOW);

  digitalWrite(CSeg, LOW);

  digitalWrite(DSeg, LOW);

  digitalWrite(ESeg, HIGH);

  digitalWrite(FSeg, HIGH);

  digitalWrite(GSeg, LOW);

}

// 4を表示

void four() {

  digitalWrite(ASeg, HIGH);

  digitalWrite(BSeg, LOW);

  digitalWrite(CSeg, LOW);

  digitalWrite(DSeg, HIGH);

  digitalWrite(ESeg, HIGH);

  digitalWrite(FSeg, LOW);

  digitalWrite(GSeg, LOW);

}

// 5を表示

void five() {

  digitalWrite(ASeg, LOW);

  digitalWrite(BSeg, HIGH);

  digitalWrite(CSeg, LOW);

  digitalWrite(DSeg, LOW);

  digitalWrite(ESeg, HIGH);

  digitalWrite(FSeg, LOW);

  digitalWrite(GSeg, LOW);

}

// 6を表示

void six() {

  digitalWrite(ASeg, LOW);

  digitalWrite(BSeg, HIGH);

  digitalWrite(CSeg, LOW);

  digitalWrite(DSeg, LOW);

  digitalWrite(ESeg, LOW);

  digitalWrite(FSeg, LOW);

  digitalWrite(GSeg, LOW);

}

// 7を表示

void seven() {

  digitalWrite(ASeg, LOW);

  digitalWrite(BSeg, LOW);

  digitalWrite(CSeg, LOW);

  digitalWrite(DSeg, HIGH);

  digitalWrite(ESeg, HIGH);

  digitalWrite(FSeg, HIGH);

  digitalWrite(GSeg, HIGH);

// 8を表示

void eight() {

  digitalWrite(ASeg, LOW);

  digitalWrite(BSeg, LOW);

  digitalWrite(CSeg, LOW);

  digitalWrite(DSeg, LOW);

  digitalWrite(ESeg, LOW);

  digitalWrite(FSeg, LOW);

  digitalWrite(GSeg, LOW);

}

// 9を表示

void nine() {

  digitalWrite(ASeg, LOW);

  digitalWrite(BSeg, LOW);

  digitalWrite(CSeg, LOW);

  digitalWrite(DSeg, LOW);

  digitalWrite(ESeg, HIGH);

  digitalWrite(FSeg, LOW);

  digitalWrite(GSeg, LOW);

}


2024年3月27日水曜日

AVR ISP シールド

 AVR ISP Shieldを使ってみた #Arduino - Qiita やら

Arduino (Shield) (ht-deko.com) にある説明では十分要領を得んのでメモ

押し下げ棒があるほうにpin1,pin28がくるようにセット avrispのsocketは以下のように挿す

〇 〇 miso  vtg

〇 〇  sck     mosi

〇 〇  rst     gnd

ISP記載が下にある6穴のやつを用いる

注:あくまでatmega88v/328p用と心得よう


2024年3月26日火曜日

fastPWM and ADC/INT0,PCINT (attiny13a)

// https://www.adnbr.co.uk/articles/adc-and-pwm-basics

// code:   https://gist.github.com/adnbr/9289235

#define F_CPU 9600000

#define LED PB1

#include <avr/io.h>


void pwm_setup(){

  TCCR0B |= (1<<CS01); // prescale 8

  TCCR0A |= (1<<WGM01) | (1<<WGM00);// fast PWM

  // Clear OC0B output on compare match, upwards counting.

  TCCR0A |= (1<<COM0B1);

}


void pwm_write(int val)

{

OCR0B = val;

}


void adc_setup(void)

{

// set the ADC input to PB2/ADC1

  ADMUX |= (1<<MUX0); // mux1/0=01 select adc1

  ADMUX |= (1<<ADLAR);

  // set the prescaler 128 , adps2 add by me

  ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADEN);

}


int adc_read(void)

{

ADCSRA |= (1<<ADSC); // start conversion

  while(ADCSRA&(1<<ADSC));

  return ADCH;

}

int main (void)

{

   int adc_in;

    // LED is an output.

    DDRB |= (1 << LED);

    adc_setup();

    pwm_setup();

    while (1) {

        // Get the ADC value

        adc_in = adc_read();

        // Now write it to the PWM counter

        pwm_write(adc_in);

    }

}

ーーーーーーーーーINT0ーーーーーーーーーーーーー

// https://kurobekoblog.com/attiny_gaibuwarikomi 

#include <avr/interrupt.h>

volatile byte state = 0;

int16_t cnt;

ISR(INT0_vect){

  state = 1;

}

void sw_up(){

  switch(state){

   case 0:

    break;

   case 1:

    cnt = 1000;

    state = 2;

    break;

  case 2:

    cnt --; // avoid chattering

    if(cnt == 0){

    PORTB ^= 0b00000001; // toggle led on off

    state = 0;

   }

 }

}

void setup(){

  DDRB  |=  0b0000001 ; // pb0 output

  PORTB |=  0b0000010 ; // pb1 input pullup

  MCUCR &= ~0b00000011; // if low level, int0 occur

  GIMSK |= (1<<INT0) ; // int0 enable

  sei();

}

void loop(){

  sw_up();

}

ーーーPCINTーーーーーーーーーーーーーーーーーーー

注:pb3をinput pullupでスイッチにつなぎ、スイッチはグランドともつなぐ

 #include <avr/interrupt.h>

#include <avr/sleep.h>

#define F_CPU 960000UL 

#define LED PB0

//#define SWITCH PINB3 どっちでもうごくが。。。。

#define SWITCH PB3

ISR(PCINT0_vect){ // 0番台の割り込みがpcint0~5ピンに割当られているようだ

  if(PINB & _BV(SWITCH)){

    PORTB ^= _BV(LED);

  }

}

int main(void)

{

   DDRB |= _BV(LED); // SET PORT B0 AS OUTPUT(ALL OTHERS ARE INPUT)

 PORTB = 0b0001000 ; // pb3(switch) input pullup

 PCMSK |= _BV(SWITCH); // SET PCINT MASK TO LISTEN TO PORT B3

 GIMSK |= _BV(PCIE);

 sei();

 set_sleep_mode(SLEEP_MODE_PWR_DOWN);

 for (;;){

  sleep_mode();

}

}

ーーーーーーPCINTもう一つーーーーーーーーー  

// https://karlsnautr.blogspot.com/2013/04/attiny13apcint.html
#include <avr/interrupt.h>
#include <avr/sleep.h>
#define F_CPU 960000UL

//#define SWITCH PINB3
#define SWITCH PB3

ISR(PCINT0_vect){
  if(bit_is_set(PINB,PORTB4)){ 
    PORTB ^= (1<<PORTB2); // PB2を反転
  }
}

void initIOInterrupt(){
  GIMSK |= (1<<PCIE); // PCINT enable
  PCMSK = 0b00010000; // PB4// switch押すで5Vかかる
  sei();
}
int main(void)
{
    DDRB |= (0<<DDB4)|(1<<DDB2); // PB4が入力,PB2が出力
    PORTB = 0b0010100 ; // PORTBの出力値
    initIOInterrupt();
    while(true){
    }
}
  

2024年3月20日水曜日

ACM1602/SD1602 ASM 表示のみ

 -----------------acm1602-------------------------------------------------------------------------------https://mctouringadv.net/20200823/arduino11/ にピン番号詳しい

nanoではコントラスうまくいかん

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


向かって右より 15に100Ω経由で5V、16はGND、これらはバックライト
1:VSSはGND,2:VDDは5V、3:VEEはPOTENTIOMETERでコントラスト,
4:RS,5:RWはGND,6:E、14~11がPD7~4につながる(出力オンリーなのでRWはGND)
15、16、1、2,3,4、5、6、7,8、9、10、11、12,13、14

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

; ファイル名 : LCD.asm

.include "m88def.inc"

.def R_TEMP0 = R2

.def STACK = R16

.def R_FLAG1 = R17 ; 割込状態他

.def R_TMR0 = R18 ; タイマ0カウント領域(10mS単位)

.def R_TMR2 = R19 ; タイマ2カウント領域(0.1mS単位)

.def R_TEMP1 = R20

.def R_TEMP2 = R21

.def R_TEMP3 = R22

.def R_TEMP4 = R23

.def R_TEMP5 = R24


;---- R_FLAG1 ----(割込状態他)


.EQU B_IOVF0 = 0 ; タイマ0オーバーフロー

.EQU B_IOVF1 = 1 ; タイマ1オーバーフロー

.EQU B_IOVF2 = 2 ; タイマ2オーバーフロー

.EQU B_INT0 = 3 ; 手動スイッチ押下割込み


;---- PORT ----

.EQU P_LCD = PORTD ; LCD

;.EQU P_SW0 = PINC ; SW0


;---- 入出力ビット -------------


.EQU B_LCD_RS = 4

.EQU B_LCD_E = 5

.EQU B_SDC_CS = 2


; 割り込みベクタ定義


.CSEG ; コードセグメント

RJMP MAIN ; リセット

.ORG $0009

RJMP IOVF2 ; タイマ2

.ORG $0010

RJMP IOVF0 ; タイマ0


;*******************************************************************************

; 割込みルーチン

;*******************************************************************************

;*******************************************************************************

;***************************************

; タイマ2(0.1mS単位)

;***************************************

IOVF2:

IN STACK,SREG ; PUSH SREG


DEC R_TMR2

BRNE IOVF2_1


SBR R_FLAG1,(1<<B_IOVF2)

RJMP IOVF2_9


IOVF2_1:

LDI R_TEMP1, 0x9C ; 割込時間0.1mSを再セット

STS TCNT2, R_TEMP1


IOVF2_9:

OUT SREG,STACK ; POP SREG


RETI


;***************************************

; タイマ0 (10mS単位)

;***************************************


IOVF0:

IN STACK,SREG ; PUSH SREG


DEC R_TMR0

BRNE IOVF0_1


SBR R_FLAG1,(1<<B_IOVF0)

RJMP IOVF0_9


IOVF0_1:

LDI R_TEMP1, 0xD9 ; 割込時間10mSを再セット

OUT TCNT0, R_TEMP1


IOVF0_9:

OUT SREG,STACK ; POP SREG


RETI


;*******************************************************************************

; サブルーチン

;*******************************************************************************

;*****************************

; タイマ2 (0.1mSタイマ) SUBROUTINE

;*****************************


STMR2:


;---- タイマ2 割込み許可 ----


LDS R_TEMP1,TIMSK2 ; タイマ割込許可

SBR R_TEMP1,(1<<TOIE2)

STS TIMSK2,R_TEMP1


;---- タイマ2 開始----


CBR R_FLAG1,(1<<B_IOVF2) ; タイマ2オーバーフローフラグクリア


LDI R_TEMP1, 0x9C ; 割込時間0.1mS

STS TCNT2, R_TEMP1


LDI R_TEMP1, 0x01 ; プリスケーラ 1

STS TCCR2B, R_TEMP1


STMR2_1:

SBRS R_FLAG1,B_IOVF2 ; タイマ0カウント完了判定

RJMP STMR2_1 ; カウント中


;---- タイマ 停止 ----


LDI R_TEMP1, 0x00

STS TCCR2B, R_TEMP1


;---- タイマ2 割込み禁止 ----


LDS R_TEMP1,TIMSK2

CBR R_TEMP1,(1<<TOIE2)

STS TIMSK2,R_TEMP1


RET


;*****************************

; タイマ0 (10mSタイマ) SUBROUTINE

;*****************************


STMR0:


;---- タイマ0 割込み許可 ----


LDS R_TEMP1,TIMSK0 ; タイマ割込許可

SBR R_TEMP1,(1<<TOIE0)

STS TIMSK0,R_TEMP1


;---- タイマ0 開始----


CBR R_FLAG1,(1<<B_IOVF0) ; タイマ0オーバーフローフラグクリア


LDI R_TEMP1, 0xD9 ; 割込時間10mS

OUT TCNT0, R_TEMP1


LDI R_TEMP1, 0x04 ; プリスケーラ 256

OUT TCCR0B, R_TEMP1


STMR0_1:

SBRS R_FLAG1,B_IOVF0 ; タイマ0カウント完了判定

RJMP STMR0_1 ; カウント中


;---- タイマ 停止 ----


LDI R_TEMP1, 0x00

OUT TCCR0B, R_TEMP1


;---- タイマ0 割込み禁止 ----


LDS R_TEMP1,TIMSK0

CBR R_TEMP1,(1<<TOIE0)

STS TIMSK0,R_TEMP1


RET


;*****************************

; USART 送信

;*****************************

;UARTS:

; LDS R_TEMP0,UCSR0A

; SBRS R_TEMP0,UDRE0

; RJMP UARTS

; STS UDR0,R_TEMP3

; RET

;*****************************

; LCD WAIT処理

;*****************************

LCDW:

CBI PORTC,B_LCD_E


;---- タイマー(1mS)セット ----


LDI R_TMR2,0x0A ; 1mSでフラグセット

RCALL STMR2


SBI PORTC,B_LCD_E


;---- タイマー(1mS)セット ----


LDI R_TMR2,0x0A ; 1mSでフラグセット

RCALL STMR2


RET

;*****************************

; LCD 表示処理

;*****************************

;*************************************************

; 引数で渡されたキャラクタを表示する

; 引数 R_TEMP3 キャラクタフォント

;*************************************************


LCDP:


OUT P_LCD,R_TEMP3


RCALL LCDW


SWAP R_TEMP3


OUT P_LCD,R_TEMP3


RCALL LCDW


RET


;*****************************

; LCD 初期化処理

;*****************************


LCDI:;■■■■ ファンクションセット ■■■■


;********* 初期セットモードへの移行 ******************************


NOP

CBI PORTC,B_LCD_RS

NOP


LDI R_TEMP1,0b00110000

OUT P_LCD,R_TEMP1


RCALL LCDW


;---- タイマー(10mS)セット ----


LDI R_TMR2,0x64 ; 10mSでフラグセット

RCALL STMR2


LDI R_TEMP1,0b00110000

OUT P_LCD,R_TEMP1


RCALL LCDW


;---- タイマー(1mS)セット ----


LDI R_TMR2,0x0A ; 1mSでフラグセット

RCALL STMR2


LDI R_TEMP1,0b00110000

OUT P_LCD,R_TEMP1


RCALL LCDW


;********* 各種設定 ******************************


;---- 4bit-mode セット ----


LDI R_TEMP1,0b00100000

OUT P_LCD,R_TEMP1


RCALL LCDW


;---- 2-line,5x8dot-font セット ----


LDI R_TEMP3,0b00101000

RCALL LCDP


;---- display off セット ----


LDI R_TEMP3,0b00001000

RCALL LCDP


;---- display クリア ----


LDI R_TEMP3,0b00000001

RCALL LCDP


;---- entry-mode セット ----


LDI R_TEMP3,0b00000110

RCALL LCDP


;---- display on セット ----


LDI R_TEMP3,0b00001100

RCALL LCDP


SBI PORTC,B_LCD_RS


RET


;*************************************************

; LCD 起動表示

;*************************************************


LCDS:

;---- リターンホーム ----


CBI PORTC,B_LCD_RS

LDI R_TEMP3,0b00000010

RCALL LCDP

SBI PORTC,B_LCD_RS


;---- display クリア ----


CBI PORTC,B_LCD_RS

LDI R_TEMP3,0b00000001

RCALL LCDP

SBI PORTC,B_LCD_RS


;---- 1行目表示 ----


LDI R_TEMP3,' '

RCALL LCDP


LDI R_TEMP3,'W'

RCALL LCDP


LDI R_TEMP3,'E'

RCALL LCDP


LDI R_TEMP3,'L'

RCALL LCDP


LDI R_TEMP3,'C'

RCALL LCDP


LDI R_TEMP3,'O'

RCALL LCDP


LDI R_TEMP3,'M'

RCALL LCDP


LDI R_TEMP3,'E'

RCALL LCDP


LDI R_TEMP3,' '

RCALL LCDP


LDI R_TEMP3,'T'

RCALL LCDP


LDI R_TEMP3,'O'

RCALL LCDP


LDI R_TEMP3,' '

RCALL LCDP


LDI R_TEMP3,'T'

RCALL LCDP


LDI R_TEMP3,'H'

RCALL LCDP


LDI R_TEMP3,'E'

RCALL LCDP


;---- 2行目先頭へ ----


CBI PORTC,B_LCD_RS

LDI R_TEMP3,0b11000000

RCALL LCDP

SBI PORTC,B_LCD_RS


;---- 2行目表示 ----


LDI R_TEMP3,' '

RCALL LCDP


LDI R_TEMP3,' '

RCALL LCDP


LDI R_TEMP3,' '

RCALL LCDP


LDI R_TEMP3,'L'

RCALL LCDP


LDI R_TEMP3,'C'

RCALL LCDP


LDI R_TEMP3,'D'

RCALL LCDP


LDI R_TEMP3,' '

RCALL LCDP


LDI R_TEMP3,'S'

RCALL LCDP


LDI R_TEMP3,'A'

RCALL LCDP


LDI R_TEMP3,'M'

RCALL LCDP


LDI R_TEMP3,'P'

RCALL LCDP


LDI R_TEMP3,'L'

RCALL LCDP


LDI R_TEMP3,'E'

RCALL LCDP


RET


;*************************************************

; LCD 動作表示

;*************************************************


;LCDM:

;---- リターンホーム ----


; CBI PORTC,B_LCD_RS

; LDI R_TEMP3,0b00000010

; RCALL LCDP

; SBI PORTC,B_LCD_RS


;---- display クリア ----


; CBI PORTC,B_LCD_RS

; LDI R_TEMP3,0b00000001

; RCALL LCDP

; SBI PORTC,B_LCD_RS


;---- 1行目表示 ----


; LDI R_TEMP3,'R'

; RCALL LCDP


; LDI R_TEMP3,'='

; RCALL LCDP


;---- 2行目先頭へ ----


; CBI PORTC,B_LCD_RS

; LDI R_TEMP3,0b11000000

; RCALL LCDP

; SBI PORTC,B_LCD_RS


;---- 2行目表示 ----


; LDI R_TEMP3,'S'

; RCALL LCDP


; LDI R_TEMP3,'='

; RCALL LCDP


; RET


;*****************************

; メインルーチン(MAIN)

;*****************************

MAIN:

CLI ; 全割込み禁止

;---- PORT 設定 ----

;LDI R_TEMP1,0b11111111

;LDI R_TEMP2,0b00000000

;OUT DDRB,R_TEMP1

;OUT PORTB,R_TEMP2


LDI R_TEMP1,0b11110000

LDI R_TEMP2,0b00101111

OUT DDRC,R_TEMP1

OUT PORTC,R_TEMP2


LDI R_TEMP1,0b11111111

LDI R_TEMP2,0b00000000

OUT DDRD,R_TEMP1

OUT PORTD,R_TEMP2


;---- USART 設定 ----


;LDI R_TEMP1,25

;STS UBRR0L,R_TEMP1

;LDI R_TEMP1,0

;STS UBRR0H,R_TEMP1 ; ボーレート2400


;LDS R_TEMP1,UCSR0C

;SBR R_TEMP1,((1<<UCSZ01)+(1<<UCSZ00)) ; ノンパリティ/1ストップビット/8ビット長

;STS UCSR0C,R_TEMP1


;LDS R_TEMP1,UCSR0B

;SBR R_TEMP1,((1<<RXEN0)+(1<<TXEN0)) ; 送受信イネーブル

;STS UCSR0B,R_TEMP1


;---- フラグ・ワークレジスタ 初期化 ----


LDI R_FLAG1, 0x00


SEI ; 全割込み許可


;---- LCD(液晶パネル) 初期化 ----------------------


RCALL LCDI


;---- LCD(液晶パネル) 起動表示 ----------------------


RCALL LCDS


;---- タイマ(2秒) ----


;LDI R_TMR0,0xC8

;RCALL STMR0


;---- LCD(液晶パネル) 動作表示 ----------------------


;RCALL LCDM


;---- LCD 文字初期表示位置設定 ----------------------


;LDI R_TEMP4,0x82


MAIN01:

;---- 1文字受信 ----

;LDS R_TEMP1,UCSR0A

;SBRS R_TEMP1,RXC0

;RJMP MAIN01 ; 受信バッファが空

;LDS R_TEMP5,UDR0


;---- LCD 文字表示位置 最終桁+1判定 ----------------------


CPI R_TEMP4,0x90

BREQ MAIN10 ; 最終桁+1である


MAIN02:

;---- LCD 受信文字表示位置設定 ----------------------


;CBI PORTC,B_LCD_RS

;MOV R_TEMP3,R_TEMP4

;RCALL LCDP

;SBI PORTC,B_LCD_RS


;---- LCD(液晶パネル) 受信文字表示 ----------------------


;MOV R_TEMP3,R_TEMP5

;RCALL LCDP


;---- LCD 送信文字表示位置設定 ----------------------


;CBI PORTC,B_LCD_RS

;MOV R_TEMP3,R_TEMP4

;LDI R_TEMP1,0x40

;ADD R_TEMP3,R_TEMP1

;RCALL LCDP

;SBI PORTC,B_LCD_RS


;---- 受信文字 判定 ----------------------


;CPI R_TEMP5,'T'

;BRNE MAIN20 ; 受信文字が'T'でない


;IN R_TEMP3,P_SW0 ; 受信文字が'T'である

;ANDI R_TEMP3,0x0F ; 不要ビットマスキング

;LDI R_TEMP1,0x0F

;EOR R_TEMP3,R_TEMP1 ; リアルコード→コンプリメンタリコード変換

;LDI R_TEMP1,0x30

;ADD R_TEMP3,R_TEMP1


MAIN03:

;---- 1文字送信 ----

;RCALL UARTS ; パソコン転送


;---- LCD(液晶パネル) 送信文字表示 ----------------------


;RCALL LCDP

;INC R_TEMP4

;RJMP MAIN01


MAIN10:


;---- LCD(液晶パネル) 動作表示 ----------------------


;RCALL LCDM


;---- LCD 文字初期表示位置設定 ----------------------


LDI R_TEMP4,0x82


RJMP MAIN02


MAIN20:

;LDI R_TEMP3,'X'

RJMP MAIN03