很长的一段时刻的捣鼓,手上的这块段码屏、总算是能够依照我的要求显现数字了.这块小数码屏在我手里现已很久了,记住仍是刚刚玩单片机时买的,其时在地摊上花了3元钱买了一只LCD1601模块和这块屏,其时并不知道怎么才干点亮它,仅仅由于其反面的操控电路是规范的集成块,类型完全明晰,屏面成色尚可,其时地摊上也经常能见到一些小的显现屏,但大都都是黑色树脂封装的电路模块,我只选带有类型的规范集成电路的买,由于我觉得,只需有类型,就能够在网上查到材料,事实证明,我是对的;跟着所学常识的添加,后来玩了一阵子LCD1601,玩理解今后就扔到一边了,而这只模块一向没弄,前些时,在网上找到了这只模块的集成电路材料,才知道这种PCF8576电路、竟然是自成系列的I2C总线操控电路,材料不算多,只需周建功的那两篇文章和使用程序,而找到的C源代码,也多为硬件I2C办法,而AT89S51模仿驱动的C程序也是常被一些网站封闭不能下载,偶然有见,也弄不明白,至于自己编程,我是力不从心的。后来找到了如下这段程序:
MSP430F1121与液晶驱动芯片PCF8576的衔接程序
#i nclude “msp430x11x1.h”
#define uint unsigned int
#define uchar unsigned char
//器材地址
uchar PCF8576=0x70;
//内存数据界说
uchar ByteCnt; //I2C 数据字节计数器
uchar SlvAdr; //被控器地址
uchar SubAdr; //被控器单元地址
uchar XmtDat[5]; //发送数据缓冲区
//uchar MODE1=0x45;
uchar MODE2=0xCD; //
uchar Bank_sel=0x78;
uchar flag;
uchar Digit[10];
#define SDA BIT3 // P2.3 controls SDA line (pull-up used for logic
1)
#define SCL BIT4 // P2.4 controls SCL line (pull-up used for logic
1)
/******************************************************************************
; 子程序
;称号:START
;描绘:发动I2C 总线子程序–发送I2C 开始条件
;;*****************************************************************************/
void START(void)
{
P2OUT |= SDA; //SDA=1
_NOP();
P2OUT |= SCL; //SCL=1
_NOP();
P2OUT &= ~SDA; //SDA=0
_NOP();
P2OUT &= ~SCL; //SCL=0
}
/*————————————————————————–
;称号:STOP
;描绘:中止I2C 总线子程序–发送I2C 总线中止条件
;————————————————————————-*/
void STOP(void)
{
P2OUT &= ~SDA; //SDA=0
_NOP();
P2OUT |= SCL;
_NOP();
P2OUT |= SDA;
_NOP();
P2OUT &= ~SCL;
}
void cack(void) /* 应对位查看 */
{
P2OUT |= SDA;
P2OUT |= SCL;
P2DIR &= ~SDA;
_NOP();
P2OUT &= ~SCL;
P2DIR |= SDA;
}
void delay(uchar time)
{
uchar i;
do{
for(i=100;i!=0;i–);
} while(–time!=0);
}
/*———————————————————————-
;称号:SendByte
;描绘:字节数据传送子程序发送一个字节数据或地址给被控器PCF8576
;要发送的数据在ACC 中
;发送数据正常回来标志F0=0 F0=1 表明被控器无应对或损坏
;————————————————————————*/
void SendByte(uchar Da
{
uchar i=8;
do
{
if((Da
P2OUT |= SDA;
else
P2OUT &= ~SDA;
P2OUT |= SCL;
_NOP ();
P2OUT &= ~SCL;
Da
} while(–i!=0);
cack();
}
/***********************************************************
;发送数据程序
;称号:SendData
;描绘:发送ByteCnt 个字节给被控器PCF8576
;被控器地址在SlvAdr 中单元地址在SubAdr 中
;所发送数据的字节数ByteCnt 在中发送的数据在XmtDat 缓冲区中
;发送数据正常回来标志F0=0 F0=1 表明被控器无应对或损坏
;**********************************************************/
void Display_Da
{
uchar i=0;
uchar size=ByteCnt;
START(); //发送I2C 总线开始条件
SendByte(SlvAdr); //发送被控器总线地址
SendByte(SubAdr); //发送单元地址
// SendByte(0x73); //闪耀办法为正常,闪耀频率为0.5Hz 的命令字送缓冲区首址,
//假如不需求闪耀应将数#70H 送入缓冲区首址
SendByte(0x70); //不闪耀
do
{
SendByte(XmtDat[i]); //发送数据
i++;
} while(–size!=0);
STOP();
delay(100);
}
void ClearLcd(void)
{
uchar size=ByteCnt;
START(); //发动I2C 总线
SendByte(SlvAdr); //送器材地址
SendByte(SubAdr); //发送单元地址
SendByte(0x70);
do
{
SendByte(0x00); //发送数据
} while(–size!=0);
STOP();
delay(200);
}
void PCF8576SET(void)
{
START();
SendByte(SlvAdr); //送器材地址
SendByte(MODE2); //取办法命令字
SendByte(Bank_sel);
STOP();
}
void main(void)
{
uint out_da
uint tmp_da
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_da
while(1)
{
tmp_da
for(i=0;i {
k=tmp_da
tmp_da
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_Da
out_da
}
}
这段程序网上转载的最多,也不知道出处,好在其简略易懂,合作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 Da
{
uchar i=8;
do
{
if((Da
SDA=1;
else
SDA=0; SCL=1;SCL=0;
Da
} while(–i!=0);
cack();
}
/***********************************************************
发送数据函数
称号:Display_Da
描绘:发送ByteCnt 个字节给被控器PCF8576
被控器地址在SlvAdr 中单元地址在SubAdr 中
所发送数据的字节数ByteCnt 在中发送的数据在tmp[ ] 缓冲区中
发送数据正常回来标志F0=0 F0=1 表明被控器无应对或损坏
**********************************************************/
void Display_Da
{
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();
}
void main(void)
{
uchar i,k,m;
uchar cnt[5];
SubAdr=0x80; //为显现缓冲区赋首地址
SlvAdr=PCF8576; //赋器材总线地址
ByteCnt=5; //显现位数赋值
PCF8576SET(); //总线初始化
//ClearLcd(); //铲除屏显
while(1)
{
for(m=1;m<11;m++) //0-9 10个数字计数
{
for(k=0;k<5;k++) //循环5次构成安稳显现
{
for(i=0;i<5;i++) //5位显现
{
/***************************************************************************************
以下的程序意义:
显现数据寄存器cnt[5]设定后,在没有装填前仅仅5个空方位,此刻cnt[0]=0;cnt[1]=0—cnt[i]=0;
在榜首次履行tmp[i]=Digit[cnt[i]];时,屏幕显现5位全0,接下来履行cnt[4]++;后cnt[4]=1
尔后鄙人一次履行tmp[i]=Digit[cnt[i]];时tmp[0]=Digit[cnt[0]]=Digit[0]=0(0xd7)其它顺次同上
直至tmp[4]=Digit[cnt[4]]=Digit[1]=1(0x06);此刻屏显为00001;循环重复直至当榜首字符位累计
为9时屏显为99999尔后屏显清0如上重复。
****************************************************************************************/
tmp[i]=Digit[cnt[i]]; //显现数据装入显现缓存区
Display_Da
delay_long(50); //经过延时操控显现字符的改换速度
}
}
/*********************************************************************
以下的程序意义:
首要在第5位累加,满10进位1至99999时清0重复
才能所限、终未能将下面单调的重复句子变为一个算式模型。
*********************************************************************/
cnt[4]++;
if(cnt[4]>9)
{
cnt[4]=0;
cnt[3]++;
}
if(cnt[3]>9)
{
cnt[3]=0;
cnt[2]++;
}
if(cnt[2]>9)
{
cnt[2]=0;
cnt[1]++;
}
if(cnt[1]>9)
{
cnt[1]=0;
cnt[0]++;
}
if(cnt[0]>9)
break;
}
}
}
程序中0-9的数字编码是依据实践测绘的硬件电路图编制的,至于他人程序中或PDF材猜中的编码办法,是绝不能够照搬的,由于每一种模块的内部接线都不尽相同,编码也就不同了,这种电路在操控时,最主要的一点便是,必定要依据段码位数先树立一个数组(显现数据存储区),在数据显现之前,先把显现数据装填到数组傍边,再把它按位送入显现缓冲区就OK了,至于开总线,关总线,送指令,送数据等等都是模式化操作,只需按规则做好即可,操控起来也没什么太杂乱的;由于仅仅玩玩,囫囵吞枣,至此,这只模块也就玩完了,假如日后需求数字显现的话或许还能用到它,其他用处我就想不出来了,至于做时刻显现,我总觉得它土不土、洋不洋没劲。这种器材已撒播很久了,或许现已过期了,或许还有新出的我不知道,尽管我玩过了,但这些材料或许还会有人有用,所以就放在这儿同享吧。仍是老办法,程序是在μV2编译软件窗口中张贴过来的,若有用的话反向操作即可;假如用到了就知会一声,能够同享能够转载,但不行做为网站的登陆下载资源,发现必究,仅此而已,别无它求。
附硬件电路图: