|
|
发表于 2014-5-15 15:10:50
|
显示全部楼层
本帖最后由 caiwenping 于 2014-5-15 18:02 编辑
这里贴上我用PCF8574T做i2c扩展8个IO驱动1602的51的一些代码
[pre lang="c" line="1" file="lcd1602_i2c.h"]
#ifndef __STC12C5A_H_
#include "STC12c5a.h"
#endif
#ifndef __I2C_H_
#include "i2c.h"
#endif
#ifndef __INTRINS_H_
#include <intrins.h>
#endif
#ifndef __LCD1602I2C_H_
#define __LCD1602I2C_H_
#define LINE1 0
#define LINE2 1
#define LINE1_HEAD 0x80
#define LINE2_HEAD 0xC0
#define DATA_MODE 0x28
#define OPEN_SCREEN 0x0C
#define DISPLAY_ADDRESS 0x80
#define CLEARSCREEN LCD_en_command(0x01)
#define MSB 0x80
#define LSB 0x01
unsigned char LCD1602_RS=0x01;
unsigned char LCD1602_RW=0x01<<1;
unsigned char LCD1602_EN=0x01<<2;
unsigned char LCDIO;
unsigned char code PCF8574_ADD=0x4e;
bit LCD_send(unsigned dat);
unsigned char LCD_recv(void);
void LCD_en_command(unsigned char command);//write command function
void LCD_en_dat(unsigned char temp);//write data function
void LCD_set_xy(unsigned char x,unsigned char y );//set display address function
void LCD_init(void);//lcd initize function
void LCD_write_char(unsigned char x,unsigned char y,unsigned char dat);//write lcd a character function
void LCD_write_string(unsigned char x,unsigned char y,unsigned char *s);//write lcd string function
void LCD_custom(unsigned char add,unsigned char *string);
void LCD_switch(bit onoff);
bit busy(void); //读忙函数
void delay_us(unsigned char us); //@11.0592MHz
void delay_ms(unsigned char ms);
void LCD_switch(bit onoff)
{
if(onoff==1)
{
LCDIO=LCDIO|0x08;
}
else
{
LCDIO=LCDIO&0xf7;
}
LCD_send(LCDIO);
}
bit LCD_send(unsigned dat)
{
bit busy;
i2c_start();
i2c_send(PCF8574_ADD|0x00);
busy|=i2c_recv_ack();
i2c_send(dat);
busy|=i2c_recv_ack();
i2c_stop();
return busy;
}
unsigned char LCD_recv()
{
unsigned char dat;
i2c_start();
i2c_send(PCF8574_ADD|0x01);
i2c_recv_ack();
dat=i2c_recv();
i2c_send_noack();
i2c_stop();
return dat;
}
bit busy(void)
{
unsigned char busy;
LCDIO&=0x08;
LCDIO&=~(LCD1602_EN|LCD1602_RW);
LCDIO|=LCD1602_RW|0x80;
i2c_start();
i2c_send(PCF8574_ADD|0x00);
i2c_recv_ack();
i2c_send(LCDIO);
i2c_recv_ack();
LCDIO|=LCD1602_EN;
i2c_send(LCDIO);
i2c_recv_ack();
i2c_stop();
busy=LCD_recv()&0x80;
LCDIO&=~LCD1602_EN;
i2c_start();
i2c_send(PCF8574_ADD|0x00);
i2c_recv_ack();
i2c_send(LCDIO);
i2c_recv_ack();
LCDIO|=LCD1602_EN;
i2c_send(LCDIO);
i2c_recv_ack();
LCDIO&=~LCD1602_EN;
i2c_send(LCDIO);
i2c_recv_ack();
LCDIO&=~LCD1602_RW;
i2c_send(LCDIO);
i2c_recv_ack();
i2c_stop();
return (bit)busy;
}
void LCD_en_command(unsigned char command)
{
unsigned char delay=1;
while(busy());
LCDIO&=0x08;
i2c_start();
i2c_send(PCF8574_ADD|0x00);
i2c_recv_ack();
i2c_send(LCDIO);
i2c_recv_ack();
{
LCDIO|=LCD1602_EN;
i2c_send(LCDIO);
i2c_recv_ack();
LCDIO&=0x0f;
LCDIO|=command&0xf0;
i2c_send(LCDIO);
i2c_recv_ack();
delay_us(delay);
LCDIO&=~LCD1602_EN;
i2c_send(LCDIO);
i2c_recv_ack();
command<<=4;
LCDIO|=LCD1602_EN;
i2c_send(LCDIO);
i2c_recv_ack();
LCDIO&=0x0f;
LCDIO|=command&0xf0;
i2c_send(LCDIO);
i2c_recv_ack();
delay_us(delay);
LCDIO&=~LCD1602_EN;
i2c_send(LCDIO);
i2c_recv_ack();
}
i2c_stop();
}
void LCD_en_dat(unsigned char command)
{
unsigned char delay=1;
while(busy());
LCDIO&=0x08;
LCDIO|=0x01;
i2c_start();
i2c_send(PCF8574_ADD|0x00);
i2c_recv_ack();
i2c_send(LCDIO);
i2c_recv_ack();
{
LCDIO|=LCD1602_EN;
i2c_send(LCDIO);
i2c_recv_ack();
LCDIO&=0x0f;
LCDIO|=command&0xf0;
i2c_send(LCDIO);
i2c_recv_ack();
delay_us(delay);
LCDIO&=~LCD1602_EN;
i2c_send(LCDIO);
i2c_recv_ack();
command<<=4;
LCDIO|=LCD1602_EN;
i2c_send(LCDIO);
i2c_recv_ack();
LCDIO&=0x0f;
LCDIO|=command&0xf0;
i2c_send(LCDIO);
i2c_recv_ack();
delay_us(delay);
LCDIO&=~LCD1602_EN;
i2c_send(LCDIO);
i2c_recv_ack();
}
i2c_stop();
}
void LCD_set_xy(unsigned char x,unsigned char y)
{
unsigned char address;
if(y==LINE1)
address=LINE1_HEAD+x;
else
address=LINE2_HEAD+x;
LCD_en_command(address);
}
void LCD_write_char(unsigned char x,unsigned char y,unsigned char dat)
{
LCD_set_xy(x,y);
LCD_en_dat(dat);
}
void LCD_write_string(unsigned char x,unsigned char y,unsigned char *s)
{
LCD_set_xy(x,y); //set address
while(*s) // write character
{
LCD_en_dat(*s);
s++;
}
}
void LCD_custom(unsigned char add,unsigned char *string)
{
unsigned char i;
unsigned char base_add=0x40;
base_add+=(add*8);
for(i=0;i<8;i++)
{
LCD_en_command(base_add+i);
LCD_en_dat(*string);
string++;
}
}
void LCD_init(void)
{
delay_ms(50);
LCD_send(0x30);
LCD_send(0x34);
LCD_send(0x30);
delay_ms(5);
LCD_send(0x30);
LCD_send(0x34);
LCD_send(0x30);
delay_us(160);
LCD_send(0x30);
LCD_send(0x34);
LCD_send(0x30);
LCD_send(0x20);
LCD_send(0x24);
LCD_send(0x20);
LCD_en_command(0x28);
LCD_en_command(0x01);
LCD_en_command(0x06);
LCD_en_command(OPEN_SCREEN);//open display (enable lcd display)
LCD_en_command(DISPLAY_ADDRESS);//set lcd first display address
LCDIO=0x08;
}
void delay_ms(unsigned char ms) //@11.0592MHz
{
unsigned char i, j;
while(ms--)
{
_nop_();
i = 11;
j = 190;
do
{
while (--j);
}
while (--i);
}
}
void delay_us(unsigned char us) //@11.0592MHz
{
while(us--)
{
_nop_();
}
}
#endif
[/code] |
|