PIC16F883は、MSSPモジュールを持っていますので、そのI2Cモードで、I2C LCD AQM0802Aに文字を表示するテストをします。
回路図です。PIC16F883は、内臓クロック8MHzで動作させ、電源は電池2本、3Vです。
プログラムです。LCD関係の関数は、PIC12F675でAQM0802A表示テストをした時と同じです。
1行目にJH7UBCを表示し、2行目に0~255の数値をカウントアップします。
----------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <xc.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
#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
#pragma config BOR4V = BOR40V
#pragma config WRT = OFF
#define _XTAL_FREQ 8000000
#define LCD_addr 0x7C //3E+0
#define LCD_addr 0x7C //3E+0
/* 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_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_start(){
SEN = 1;
while(SEN);
}
/* ストップコンディション */
void I2C_stop(){
SSPIF = 0;
PEN = 1;
while(PEN);
SSPIF = 0;
}
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;
}
unsigned char I2C_write(unsigned char dat){
SSPIF = 0;
SSPBUF = dat;
while(!SSPIF);
return ACKSTAT;
}
/* write command */
void LCD_cmd(unsigned char cmd){
unsigned char ackn;
I2C_start(); //start condition
ackn = I2C_write(LCD_addr); //send slave address
ackn = I2C_write(0x00); //send control byte
ackn = I2C_write(cmd); //send command
I2C_stop(); //stop condition
}
/* write charactor */
void LCD_char(unsigned char dat){
unsigned char ackn;
I2C_start(); //start condition
ackn = I2C_write(LCD_addr); //send slave address
ackn = I2C_write(0x40); //send control byte
ackn = I2C_write(dat); //send data
I2C_stop(); //stop condition
}
void LCD_cmd(unsigned char cmd){
unsigned char ackn;
I2C_start(); //start condition
ackn = I2C_write(LCD_addr); //send slave address
ackn = I2C_write(0x00); //send control byte
ackn = I2C_write(cmd); //send command
I2C_stop(); //stop condition
}
/* write charactor */
void LCD_char(unsigned char dat){
unsigned char ackn;
I2C_start(); //start condition
ackn = I2C_write(LCD_addr); //send slave address
ackn = I2C_write(0x40); //send control byte
ackn = I2C_write(dat); //send data
I2C_stop(); //stop condition
}
/* LCD initialize */
void LCD_init(){
__delay_ms(40); //40ms wait
LCD_cmd(0x38); //8bit,2line
LCD_cmd(0x39); //IS=1 : extention mode set
LCD_cmd(0x14); //Internal OSC Frequency
LCD_cmd(0x70); //Contrast set
LCD_cmd(0x56); //Power/ICON/Contrast Control
LCD_cmd(0x6C); //Follower control
__delay_ms(200);//200ms wait
LCD_cmd(0x38); //IS=0 : extention mode cancel
LCD_cmd(0x0C); //Display ON
LCD_cmd(0x01); //Clear Display
__delay_ms(2); //wait more than 1.08ms
}
void LCD_init(){
__delay_ms(40); //40ms wait
LCD_cmd(0x38); //8bit,2line
LCD_cmd(0x39); //IS=1 : extention mode set
LCD_cmd(0x14); //Internal OSC Frequency
LCD_cmd(0x70); //Contrast set
LCD_cmd(0x56); //Power/ICON/Contrast Control
LCD_cmd(0x6C); //Follower control
__delay_ms(200);//200ms wait
LCD_cmd(0x38); //IS=0 : extention mode cancel
LCD_cmd(0x0C); //Display ON
LCD_cmd(0x01); //Clear Display
__delay_ms(2); //wait more than 1.08ms
}
/* Clear Display */
void LCD_clear(){
LCD_cmd(0x01);
__delay_ms(1);
__delay_us(80);
}
void LCD_clear(){
LCD_cmd(0x01);
__delay_ms(1);
__delay_us(80);
}
/* Return Home */
void LCD_home(){
LCD_cmd(0x02);
__delay_ms(1);
__delay_us(80);
}
void LCD_home(){
LCD_cmd(0x02);
__delay_ms(1);
__delay_us(80);
}
/* Cursor 2line top */
void LCD_2line(){
LCD_cmd(0xC0);
}
void LCD_2line(){
LCD_cmd(0xC0);
}
/* write 1 charactor to LCD */
void putch(unsigned char ch){
LCD_char(ch);
}
void putch(unsigned char ch){
LCD_char(ch);
}
/* write string */
void putstr(const unsigned char *s){
while(*s){
LCD_char(*s++);
}
}
void putstr(const unsigned char *s){
while(*s){
LCD_char(*s++);
}
}
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();
putstr("JH7UBC");
unsigned char count = 0;
while(1){
LCD_2line();
printf("%3d",count);
count++;
__delay_ms(500);
}
}
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();
putstr("JH7UBC");
unsigned char count = 0;
while(1){
LCD_2line();
printf("%3d",count);
count++;
__delay_ms(500);
}
}