微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > AT89S51I2C控制PCF8576段码LCD模块

AT89S51I2C控制PCF8576段码LCD模块

时间:11-13 来源:互联网 点击:

(200);
}

void PCF8576SET(void)
{
START();

SendByte(SlvAdr); //送器件地址

SendByte(MODE2); //取方式命令字

SendByte(Bank_sel);

STOP();
}

void main(void)
{
uint out_data;
uint tmp_data;
uchar i;
uchar k;
uchar tmp[5];

P2DIR |= SDA; //SDA
P2DIR |= SCL; //SCL

P2OUT &= ~SDA;
P2OUT &= ~SCL;

WDTCTL = WDTPW+WDTHOLD;

Digit[0]=0x7E; //0
Digit[1]=0x18; //1
Digit[2]=0xB6; //2
Digit[3]=0xBC; //3
Digit[4]=0xD8; //4
Digit[5]=0xEC; //5
Digit[6]=0xEE; //6
Digit[7]=0x38; //7
Digit[8]=0xFE; //8
Digit[9]=0xFC; //9

SubAdr=0x80;
SlvAdr=PCF8576;
ByteCnt=4;

PCF8576SET();

ClearLcd();

out_data=0;

while(1)
{
tmp_data=out_data;

for(i=0;i {
k=tmp_data%10;
tmp_data=tmp_data/10;

XmtDat[i]=Digit[k];
tmp[i]=k;
}

XmtDat[2] |= 0x01;

for(i=ByteCnt-1;i!=0;i--)
{
if( tmp[i] == 0 )
XmtDat[i]=0x00;
else
break;
}

Display_Data();

out_data++;

}

}
这段程序网上转载的最多,也不知道出处,好在其简单易懂,配合PCF8576的PDF资料,总算是弄懂了这种两线控制原件的控制方式,接下来,我剖拆了这个模块,并测绘了其硬件电路图,经与资料比照,因其只有不到40段驱动位,只有一个背极,且其SA0脚接电源正极,从而确认其为静态驱动方式,总线地址为0x72,工作指令字为0x49,不需闪烁时闪烁指令字为0x70,没有用到存储体选择指令,没有用到屏幕清零函数。由于这种I2C器件为单向器件,只送数据,不读数据,送入数据的原理就是,不论多少数据,都是利用“一位数据输出函数”在时钟脉冲的配合下,一位一位的送入器件,所以上述这段程序刚刚好用,比起哪些通用I2C程序简单的多。事情往往就是这样,一旦弄懂了原理,改编自己的应用程序就不是很难了。经过改编,得到了自己的程序,这是一段演示程序,由它控制段码屏在最右侧一位累计加1,直到显示99999时屏显清零并重复,我是想,只要做到想在那个位置显示,就能在那个位置显示,也就可以了,至于其他的应用方式也就能够实现了,以下是我改编并测试通过的程序:

/********************************************************************
AT89S51驱动PCF8576演示5位计数显示程序: WANNENGGONG改编 2010/4/25
AT89S51的P0.1口做I2C的数据输出口;P0.2做I2C的时钟输出口
显示效果为首先满屏清零而后自动累加计数至显示99999时清零后重复
*********************************************************************/
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define PCF8576 0x72 //器件总线地址
sbit SDA=P0^1; //定义模拟I2C数据传送端口
sbit SCL=P0^2; //定义模拟I2C时钟控制端口
bit ack; //定义应答标志位
uchar ByteCnt; //I2C 数据字节计数器
uchar SlvAdr; //被控器地址
uchar SubAdr; //被控器单元地址
uchar cnt[5]; //显示数据寄存器
uchar tmp[5]; //显示数据缓冲区
uchar MODE2=0x49; //工作方式命令字
//uchar Bank_sel=0x7a; //存储体选择命令字(未定义)
uchar Digit[]={0xd7,0x06,0xe3,0xa7,0x36,0xb5,0xf5,0x17,0xf7,0xb7,0xd7};
//{0,1,2,3,4,5,6,7,8,9,0}字形码;其定义方法参见硬件接线图。
//延时程序======延时2*t机器周期=====
void delay(uchar t)
{
while(--t);
}
//延时程序======长延时=====
void delay_long(uint time)
{
uchar i;
do{
for(i=100;i!=0;i--);
} while(--time!=0);
}
/*********************************************************
启动总线函数
名称:START
描述:启动I2C 总线子程序--发送I2C 起始条件
*********************************************************/
void START(void)
{
SDA=1; SCL=1;
delay(2); SDA=0;
delay(2); SCL=0;
}
/*********************************************************
停止总线函数
名称:STOP
描述:停止I2C 总线子程序--发送I2C 总线停止条件
*********************************************************/
void STOP(void)
{
SDA=0; SCL=1;
delay(2); SDA=1;
delay(2); SCL=0;
}
void cack(void)
{
bit a;
if(a==0)SDA=0; //在此发出应答或非应答信号
else SDA=1;
delay(2);
SCL=1;
delay(2); //时钟低电平周期大于4μs
SCL=0;
delay(2); //清时钟线,钳住I2C总线以便继续接收
}
/*********************************************************
发送一个字节函数
名称:SendByte
描述:字节数据传送子程序发送一个字节数据或地址给被控器PCF8576
要发送的数据在ACC中;
发送数据正常返回标志F0=0 F0=1 表示被控器无应答或损坏
*********************************************************/
void SendByte(uchar Data)
{
uchar i=8;
do
{
if((Data&0x80)==0x80)
SDA=1;
else
SDA=0; SCL=1;SCL=0;
Data=Data<1;
} while(--i!=0);
cack();
}
/***********************************************************
发送数据函数
名称:Display_Data
描述:发送ByteCnt 个字节给被控器PCF8576
被控器地址在SlvAdr 中单元地址在SubAdr 中
所发送数据的字节数ByteCnt 在中发送的数据在tmp[ ] 缓冲区中
发送数据正常返回标志F0=0 F0=1 表示被控器无应答或损坏
**********************************************************/
void Display_Data(void)
{
uchar i=0;
uchar size=ByteCnt;
START(); //发送I2C 总线起始条件
SendByte(SlvAdr); //发送被控器总线地址
SendByte(SubAdr); //发送单元地址
SendByte(0x70); //不闪烁命令字
do
{
SendByte(tmp[i]); //发送数据
i++;
} while(--size!=0);
STOP();
delay(100);
}
/*********************************************************
清除屏显函数(未采用)
名称:ClearLcd
描述:在向显示屏送数据前清除原有显示内容
*********************************************************/
/*********************************************************
void ClearLcd(void)
{
uchar size=ByteCnt;
START(); //启动I2C 总线
SendByte(SlvAdr); //送器件地址
SendByte(SubAdr); //发送单元地址
SendByte(0x70); //不闪烁命令字
do
{
SendByte(0x00); //发送数据
} while(--size!=0);
STOP();
delay(200);
}
*********************************************************/
/*********************************************************
器件总线初始化函数
名称:PCF8576SET
描述:用于器件控制的重复操作的指令集和
*********************************************************/
void PCF8576SET(void)
{
START();
SendByte(SlvAdr); //送器件地址
SendByte(MODE2); //送方式命令字
// SendByte(Bank_sel); //送存储体选择命令字
STOP();
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top