
| i2c.h |
|---|
#ifndef __I2C #define __I2C #define ACK 0x00 // ACK Signal #define NACK 0x01 // NACK Signal void I2C_START(); // START Bit-Patten Generate void I2C_STOP(); // END Bit-Pattern Generate void SEND_ACK(char ack); // Send ACK or NACK Signal char WAIT_ACK(); // Wait ACK or NACK Siganl void WriteByte(char b); // I2C Write Byte char ReadByte(char ack); // I2C Read Byte void Delay(int i); // Delay Func. #endif |
| i2c.c |
|---|
#include "i2c.h"
// 簡易I2Cなので複数のデバイスは繋げない
// ブルアップ抵抗は要らない
// CPUのスピードによりDeleyを調整する
void Delay(int i)
{
// for(; i != 0 ; i--) ;
}
#define HIGH 1
#define LOW 0
#define SDA PORTC.F4
#define SCL PORTC.F3
/*
startのビットパターンを生成する
~~|________ SDA
~~~~|_____ SCL
*/
void I2C_START()
{
SDA = HIGH; Delay(1); //SDA HIGH
SCL = HIGH; Delay(1); //SCL HIGH
SDA = LOW ; Delay(1); //SDA LOW
SCL = LOW ; Delay(1); //SCL LOW
}
/*
ENDのビットパターンを生成する
______|~~~ SDA
___|~~~~~~ SCL
*/
void I2C_STOP()
{
SCL = LOW ;Delay(1); // SCL LOW
SDA = LOW ;Delay(1); // SDA LOW
SCL = HIGH;Delay(1); // SCL HIGH;
SDA = HIGH;Delay(1); // SDA HIGH;
}
void SEND_ACK(char ack)
{
// Send ACK(LOW) or NACK(HIGH) and Generate SCL clock.
SCL = LOW ; Delay(1);
if(ack == ACK) // If ACK?
SDA = LOW ;
else // If NACK?
SDA = HIGH;
Delay(2);
SCL = HIGH; Delay(1); // SCL Clock
SCL = LOW ; Delay(1);
}
char WAIT_ACK()
{
char ack; // Wait for ACK or NACK
TRISC |= 0x10;
SCL = LOW ; Delay(1);
SCL = HIGH; Delay(1);
ack = SDA;
SCL = LOW ;
TRISC &= 0xEF;
return ack;
}
// 1バイト送出する
void WriteByte(char b)
{
char i =0;
for( ; i < 8 ; i++)
{
SCL = LOW;
if( b & 0x80)
SDA = HIGH;
else // If ‘0′-> ‘Low’ to SDA
SDA = LOW;
Delay(1);
SCL = HIGH; Delay(1);
b <<=1;
}
SCL = LOW ;Delay(1);
while(WAIT_ACK());
}
// 1バイト読み込む
char ReadByte(char ack)
{
char ret;
char i = 0;
ret = 0;
SCL = LOW ; Delay(1); // SCL LOW
TRISC |= 0x10;
for(; i<8 ; i++)
{
SCL = HIGH; Delay(1); // SCL HIGH
ret <<= 1;
if(SDA) ret++;
SCL = LOW ; Delay(1); // SCL LOW
}
TRISC &= 0xEF;
SEND_ACK(ack);
return ret;
}
|
| I2CLCD.h |
|---|
#ifndef __LCD #define __LCD typedef unsigned char byte; void LCDinit(); void home(); void clear(); void writeCh(unsigned char ch); void writeString(char* ch); void write(unsigned char control, unsigned char dt); void writeF(int x, int column, char zeroPad); void writeInt(int x); void setIcon(int x); void setCG(char mode, char* cgData); #endif |
| I2CLCD.c |
|---|
#define Wait 40
#include "I2CLCD.h"
#include "i2c.h"
/*
PIC16F690はハード的にマスターになれないようなので、
ソフト的にマスターにする。
I2C低電圧キャラクタ液晶モジュール(16x2行)を用いる。
http://strawberry-linux.com/catalog/items?code=27001
*/
byte chCount;
byte LCD_WRITE;
void write(unsigned char control, unsigned char dt);
// 初期化 コントラストなどは要チェック
void LCDinit()
{
chCount = 0;
Delay_ms(40);
LCD_WRITE= 0x7c;
write(0x0, 0x38); //data8bit, numberOfLine=2
Delay_us(Wait);
write(0x0, 0x39); //data8bit, numberOfLine=2
Delay_us(Wait);
write(0x0, 0x14); //internal OSC frequency
Delay_us(Wait);
write(0x0, 0x7f); // contrast
Delay_us(Wait);
write(0x0, 0x5F); // power/icon/contrast control
Delay_us(Wait);
write(0x0, 0x6a); // follower control
Delay_ms(200); // 200ms
write(0x0, 0x0c); // Display ON
Delay_us(Wait);
write(0x0, 0x01); // clear disply
Delay_us(2000); // 2ms
write(0x00, 0x06); // entry mode set
Delay_us(Wait);
}
// カーソルをホームに持って行く
void home()
{
write(0x00,0x02); // return to home
chCount=0;
Delay_ms(2);
}
// 画面クリア
void clear()
{
write(0x00,0x01); // clear display
chCount=0;
Delay_ms(2);
}
// 一文字表示
void writeCh(unsigned char ch)
{
int x;
if(ch==0x0a){
x= chCount %32;
if(x<16) {
write(0x00,0xc0);
chCount=16;
}
else {
write(0x00,0x01); // clear display
chCount=0;
Delay_ms(2);
}
}
else
{
write(0x40,ch);
x= ++chCount %32;
if( x ==16) write(0x00,0xc0);
}
}
// 文字列表示
void writeString(char* ch)
{
while(*ch){
writeCh(*ch++);
}
}
// データ送出
void write(unsigned char control, unsigned char dt)
{
I2C_START();
WriteByte(LCD_WRITE);
WriteByte(control);
WriteByte(dt);
I2C_STOP();
}
// 簡易書式付き整数表示
void writeF(int x, int column, char zeroPad)
{
char Buffer[10];
char num[5];
int i,j, n=0, signFlag=0;
if(x<0) { // マイナスの値の場合
signFlag=1;
x *= -1;
}
do {
num[n++] = x%10;
x /= 10;
} while(x != 0);
i = column-n;
if(i>0) {
for(i=0; i<10; i++) Buffer[i]=' ';
if(zeroPad) for(i=0; i<column-n; i++) Buffer[i]='0';
Buffer[9]=0;
for(i=column-n, j=n-1; i<column; i++, j--) Buffer[i]=num[j]|'0';
Buffer[i]=0;
if(signFlag) Buffer[column-n-1]='-';
}
else {
j=0;
if(signFlag) Buffer[j++]='-';
for(i=--n; i>=0; i--) Buffer[j++]=num[i]|'0';
Buffer[j]=0;
}
writeString(Buffer);
}
// 整数表示
void writeInt(int x)
{
char num[5];
int n=0;
if(x<0) { // マイナスの値の場合
writeCh('-');
x *= -1;
}
do {
num[n++] = x%10 +'0';
x /= 10;
} while(x != 0);
while(--n >=0) writeCh(num[n]);
}
// アイコン表示
void setIcon(int x)
{
write(0x00, 0x39); // Function set
write(0x00, 0x40 | 0x0f); // flower icon
if(x & 1) write(0x40, 0x10);
else write(0x40, 0x00);
write(0x00, 0x40 | 0x0d); // Battery icon
write(0x40, 0);
if(x & 0x0e) {
write(0x00, 0x40 | 0x0d); // Battery icon
write(0x40, ((x & 0x0e)<<1) | 2);
}
write(0x00, 0x40 | 0x0b); // no sound icon
if(x & 0x10) write(0x40, 0x10);
else write(0x40, 0);
write(0x00, 0x40 | 0x09); // Key icon
if(x & 0x20) write(0x40, 0x10);
else write(0x40, 0);
write(0x00, 0x40 | 0x07); // 矢印 icon
write(0x40, 0);
if(x & 0xC0) {
write(0x00, 0x40 | 0x07); // 矢印 icon
write(0x40, (x & 0xC0)>>3);
}
write(0x00, 0x40 | 0x06); // enter icon
if(x & 0x100) write(0x40, 0x10);
else write(0x40, 0);
write(0x00, 0x40 | 0x04); // ring icon
if(x & 0x200) write(0x40, 0x10);
else write(0x40, 0);
write(0x00, 0x40 | 0x02); // 電話 icon
if(x & 0x400) write(0x40, 0x10);
else write(0x40, 0);
write(0x00, 0x40); // antena icon
if(x & 0x800) write(0x40, 0x10);
else write(0x40, 0);
write(0x00, 0x38); // Function set
}
// グラフィック表示
void setCG(char mode, char* cgData)
{
unsigned char i, j;
write(0x00,0x38); // Function set IS= 0
write(0x00,0x40); // CGRAM set address= 0
if(mode == 0) { // StringModeで呼ばれた時はデフォールトにセット
for(i=0; i<8; i++) {
for(j=0; j<8; j++) {
if(j < (7-i)) write(0x40,0x00);
else write(0x40,0x1f); // 横棒をセット
}
}
}
else {
for(i=0; i<64; i++ ) write(0x40, cgData[i]);
}
}
|
| main.c |
|---|
// LCD: Reset(1), SCL(2), SDA(3), Vss(4)、Vdd(5)
// ResetはVddに繋いでおく
// LCD : 16F690
// SDA(3) : PORTC.F4(6)
// SCL(2) : PORTC.F3(7)
// TxD(10)
#include "i2c.h"
#include "I2CLCD.h"
char buff[16];
void main()
{
float F;
int i=0;
OSCCON = 0x75; // 内部OSC8MHzで動作させる
ANSEL = 0; // アナログ入力をOFF
ANSELH = 0; // アナログ入力をOFF
PORTC = 0xff; // PORTCを0xffにする
TRISC = 0xe7; // PORTCを入力に設定する
LCDinit();
while(1) {
clear();
writeString("LCD test ");
writeInt(i++); // 整数型を表示
writeCh(0x0a);
F = i*3.3/1024;
FloatToStr(F, buff); // float型を表示
writeString(buff);
Delay_ms(100);
}
}
|