Quantcast
Channel: JH7UBCブログ
Viewing all articles
Browse latest Browse all 440

PIC16F883 I2Cインターフェース付きLCD1602

$
0
0
 PIC16F883でI2Cインターフェース付きLCD1602の表示テストをしました。

 Arduinoで実験済みのプログラムを移植しました。Arduinoの記事は、こちら

 回路図です。

イメージ 1

ブレッドボードです。表示された文字がちょっと見ずらいです。すみません。

イメージ 2

プログラムです。I2Cインターフェースを使ってLCD1602に文字を表示する原理は、JH7UBCホームページのこちらの記事を見てください。
---------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config MCLRE = OFF
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = OFF
#pragma config IESO = OFF
#pragma config FCMEN = OFF
#pragma config LVP = OFF
// CONFIG2
#pragma config BOR4V = BOR40V
#pragma config WRT = OFF
#define _XTAL_FREQ 8000000
#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
#define LCD_addr 0x4E   //0x27<<1
#define SW RB0
#define start_addr 0b00000111
#define end_addr 0b01111000

/* I2C 初期化*/
void I2C_init(){
    SSPCON = 0x28;  //SSPEN = 1,I2C Master Mode
    SSPSTATbits.SMP = 1;    //標準速度モード(100KHz)
    SSPADD = 19;    //Fosc/(4*Clock)-1  Clock=100kHz,Fosc=8MHz
}
/* スタートコンディション */
void I2C_start(){
    SEN = 1;
    while(SEN);
}
/* ストップコンディション */
void I2C_stop(){
    SSPIF = 0;
    PEN = 1;
    while(PEN);
    SSPIF = 0;
}
/* I2Cに1byte送信 */
unsigned char I2C_write(unsigned char dat){
    SSPIF = 0;
    SSPBUF = dat;
    while(!SSPIF);
    return ACKSTAT;
}
void Write_data(unsigned char data){
    unsigned char ackn;
    I2C_start();
    ackn = I2C_write(LCD_addr);
    ackn = I2C_write(data | LCD_EN | LCD_BL);
    ackn = I2C_write(data | LCD_BL);
    I2C_stop();
    __delay_us(100);
}
void LCD_write(unsigned char bits,unsigned char mode){
    //send High 4bits
    Write_data((bits & 0xF0) | mode);
    //send Low 4bits
    Write_data(((bits << 4) & 0xF0) | mode);
}
void LCD_init(){
    LCD_write(0x33,LCD_CMD);
    LCD_write(0x32,LCD_CMD);
    LCD_write(0x06,LCD_CMD);
    LCD_write(0x0C,LCD_CMD);
    LCD_write(0x28,LCD_CMD);
    LCD_write(0x01,LCD_CMD);
    __delay_ms(1);
}
void LCD_clear(){
    LCD_write(0x01,LCD_CMD);
    __delay_ms(1);
}
void LCD_home(){
    LCD_write(0x02,LCD_CMD);
    __delay_ms(1);
}
void LCD_cursor(unsigned char x,unsigned char y){
    if (y == 0){
        LCD_write(LCD_LINE1+x,LCD_CMD);
    }
    if (y == 1){
        LCD_write(LCD_LINE2+x,LCD_CMD);
    }
}
void LCD_char(unsigned char byte){
    LCD_write(byte,LCD_CHR);
}
void putch(unsigned char ch){
    LCD_char(ch);
}
void main() {
    ANSEL = 0;  //アナログポートを使わない
    ANSELH = 0;
    OSCCON = 0x70;  //内蔵クロック8MHz
    TRISA = 0b00000000;
    TRISB = 0b00000000;
    TRISC = 0b00011000; //RC3(SCL),RC4(SDA)input
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
   
    I2C_init();
    LCD_init();
   
    printf("Hello World!");
    LCD_cursor(5,1);
    printf("JH7UBC");
   
    while(1){
    }
}
-----------------------------------------------
 今回のトラブルシューティング

 すでにArduinoで実験済みのプログラムです。簡単に動作すると思ったのですが、どっこい、電源を入れてもまったく表示しません。

 回路は簡単ですから、接続に間違いはないはず。

 うーーん。表示されない原因が分からない。

 Arduinoでやってみると、ちゃんと表示されます。

 I2C1の信号はちゃんと出ているのか、picoスコープで確認すると問題ありません。

 いろいろ確認に1日かかりました。

 一夜明けて、はっつと気づきました。SDAとSCLの配線が逆になっているでは、ありませんか。

 入れ替えたら、ぱっと表示されました。

 正しく配線したはず、という思い込みでした。

 反省。

 さて、次に進みましょう。

Viewing all articles
Browse latest Browse all 440

Trending Articles