<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > AT89S51I2C控制PCF8576段碼LCD模塊

          AT89S51I2C控制PCF8576段碼LCD模塊

          作者: 時(shí)間:2016-11-13 來(lái)源:網(wǎng)絡(luò) 收藏
          很長(zhǎng)的一段時(shí)間的搗鼓,手上的這塊段碼屏、總算是可以按照我的要求顯示數(shù)字了.這塊小數(shù)碼屏在我手里已經(jīng)很久了,記得還是剛剛玩單片機(jī)時(shí)買(mǎi)的,當(dāng)時(shí)在地?cái)偵匣?元錢(qián)買(mǎi)了一只LCD1601模塊和這塊屏,當(dāng)時(shí)并不知道如何才能點(diǎn)亮它,只是因?yàn)槠浔趁娴目刂齐娐肥菢?biāo)準(zhǔn)的集成塊,型號(hào)齊全清晰,屏面成色尚可,當(dāng)時(shí)地?cái)偵弦矔r(shí)常能見(jiàn)到一些小的顯示屏,但多數(shù)都是黑色樹(shù)脂封裝的電路模塊,我只選帶有型號(hào)的標(biāo)準(zhǔn)集成電路的買(mǎi),因?yàn)槲矣X(jué)得,只要有型號(hào),就可以在網(wǎng)上查到資料,事實(shí)證明,我是對(duì)的;隨著所學(xué)知識(shí)的增加,后來(lái)玩了一陣子LCD1601,玩明白以后就扔到一邊了,而這只模塊一直沒(méi)弄,前些時(shí),在網(wǎng)上找到了這只模塊的集成電路資料,才知道這種PCF8576電路、竟然是自成系列的I2C總線控制電路,資料不算多,只有周立功的那兩篇文章和應(yīng)用程序,而找到的C源代碼,也多為硬件I2C方式,而AT89S51模擬驅(qū)動(dòng)的C程序也是常被一些網(wǎng)站封鎖不能下載,偶爾有見(jiàn),也弄不懂,至于自己編程,我是無(wú)能為力的。后來(lái)找到了如下這段程序:

          MSP430F1121與液晶驅(qū)動(dòng)芯片PCF8576的連接程序

          本文引用地址:http://www.ex-cimer.com/article/201611/316552.htm

          #i nclude "msp430x11x1.h"

          #define uint unsigned int
          #define uchar unsigned char

          //器件地址
          uchar PCF8576=0x70;

          //內(nèi)存數(shù)據(jù)定義
          uchar ByteCnt; //I2C 數(shù)據(jù)字節(jié)計(jì)數(shù)器
          uchar SlvAdr; //被控器地址
          uchar SubAdr; //被控器單元地址
          uchar XmtDat[5]; //發(fā)送數(shù)據(jù)緩沖區(qū)


          //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)

          /******************************************************************************
          ; 子程序
          ;名稱(chēng):START
          ;描述:啟動(dòng)I2C 總線子程序--發(fā)送I2C 起始條件
          ;;*****************************************************************************/
          void START(void)
          {
          P2OUT |= SDA; //SDA=1
          _NOP();
          P2OUT |= SCL; //SCL=1
          _NOP();
          P2OUT &= ~SDA; //SDA=0
          _NOP();
          P2OUT &= ~SCL; //SCL=0
          }

          /*--------------------------------------------------------------------------
          ;名稱(chēng):STOP
          ;描述:停止I2C 總線子程序--發(fā)送I2C 總線停止條件
          ;-------------------------------------------------------------------------*/
          void STOP(void)
          {
          P2OUT &= ~SDA; //SDA=0
          _NOP();
          P2OUT |= SCL;
          _NOP();
          P2OUT |= SDA;
          _NOP();
          P2OUT &= ~SCL;
          }

          void cack(void) /* 應(yīng)答位檢查 */
          {
          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);

          }

          /*----------------------------------------------------------------------
          ;名稱(chēng):SendByte
          ;描述:字節(jié)數(shù)據(jù)傳送子程序發(fā)送一個(gè)字節(jié)數(shù)據(jù)或地址給被控器PCF8576
          ;要發(fā)送的數(shù)據(jù)在ACC 中
          ;發(fā)送數(shù)據(jù)正常返回標(biāo)志F0=0 F0=1 表示被控器無(wú)應(yīng)答或損壞
          ;------------------------------------------------------------------------*/
          void SendByte(uchar Data)
          {
          uchar i=8;

          do
          {
          if((Data&0x80)==0x80)
          P2OUT |= SDA;
          else
          P2OUT &= ~SDA;

          P2OUT |= SCL;
          _NOP ();
          P2OUT &= ~SCL;

          Data=Data<<1;
          } while(--i!=0);

          cack();

          }

          /***********************************************************
          ;發(fā)送數(shù)據(jù)程序
          ;名稱(chēng):SendData
          ;描述:發(fā)送ByteCnt 個(gè)字節(jié)給被控器PCF8576
          ;被控器地址在SlvAdr 中單元地址在SubAdr 中
          ;所發(fā)送數(shù)據(jù)的字節(jié)數(shù)ByteCnt 在中發(fā)送的數(shù)據(jù)在XmtDat 緩沖區(qū)中
          ;發(fā)送數(shù)據(jù)正常返回標(biāo)志F0=0 F0=1 表示被控器無(wú)應(yīng)答或損壞
          ;**********************************************************/
          void Display_Data(void)
          {
          uchar i=0;
          uchar size=ByteCnt;

          START(); //發(fā)送I2C 總線起始條件

          SendByte(SlvAdr); //發(fā)送被控器總線地址

          SendByte(SubAdr); //發(fā)送單元地址

          // SendByte(0x73); //閃爍方式為正常,閃爍頻率為0.5Hz 的命令字送緩沖區(qū)首址,
          //如果不需要閃爍應(yīng)將數(shù)#70H 送入緩沖區(qū)首址
          SendByte(0x70); //不閃爍


          do
          {
          SendByte(XmtDat[i]); //發(fā)送數(shù)據(jù)
          i++;
          } while(--size!=0);

          STOP();

          delay(100);
          }

          void ClearLcd(void)
          {
          uchar size=ByteCnt;

          START(); //啟動(dòng)I2C 總線

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

          SendByte(SubAdr); //發(fā)送單元地址

          SendByte(0x70);

          do
          {
          SendByte(0x00); //發(fā)送數(shù)據(jù)
          } while(--size!=0);

          STOP();

          delay(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++;

          }

          }
          這段程序網(wǎng)上轉(zhuǎn)載的最多,也不知道出處,好在其簡(jiǎn)單易懂,配合PCF8576的PDF資料,總算是弄懂了這種兩線控制原件的控制方式,接下來(lái),我剖拆了這個(gè)模塊,并測(cè)繪了其硬件電路圖,經(jīng)與資料比照,因其只有不到40段驅(qū)動(dòng)位,只有一個(gè)背極,且其SA0腳接電源正極,從而確認(rèn)其為靜態(tài)驅(qū)動(dòng)方式,總線地址為0x72,工作指令字為0x49,不需閃爍時(shí)閃爍指令字為0x70,沒(méi)有用到存儲(chǔ)體選擇指令,沒(méi)有用到屏幕清零函數(shù)。由于這種I2C器件為單向器件,只送數(shù)據(jù),不讀數(shù)據(jù),送入數(shù)據(jù)的原理就是,不論多少數(shù)據(jù),都是利用“一位數(shù)據(jù)輸出函數(shù)”在時(shí)鐘脈沖的配合下,一位一位的送入器件,所以上述這段程序剛剛好用,比起哪些通用I2C程序簡(jiǎn)單的多。事情往往就是這樣,一旦弄懂了原理,改編自己的應(yīng)用程序就不是很難了。經(jīng)過(guò)改編,得到了自己的程序,這是一段演示程序,由它控制段碼屏在最右側(cè)一位累計(jì)加1,直到顯示99999時(shí)屏顯清零并重復(fù),我是想,只要做到想在那個(gè)位置顯示,就能在那個(gè)位置顯示,也就可以了,至于其他的應(yīng)用方式也就能夠?qū)崿F(xiàn)了,以下是我改編并測(cè)試通過(guò)的程序:

          /********************************************************************
          AT89S51驅(qū)動(dòng)PCF8576演示5位計(jì)數(shù)顯示程序: WANNENGGONG改編 2010/4/25
          AT89S51的P0.1口做I2C的數(shù)據(jù)輸出口;P0.2做I2C的時(shí)鐘輸出口
          顯示效果為首先滿(mǎn)屏清零而后自動(dòng)累加計(jì)數(shù)至顯示99999時(shí)清零后重復(fù)
          *********************************************************************/
          #include
          #include
          #define uchar unsigned char
          #define uint unsigned int
          #define PCF8576 0x72 //器件總線地址
          sbit SDA=P0^1; //定義模擬I2C數(shù)據(jù)傳送端口
          sbit SCL=P0^2; //定義模擬I2C時(shí)鐘控制端口
          bit ack; //定義應(yīng)答標(biāo)志位
          uchar ByteCnt; //I2C 數(shù)據(jù)字節(jié)計(jì)數(shù)器
          uchar SlvAdr; //被控器地址
          uchar SubAdr; //被控器單元地址
          uchar cnt[5]; //顯示數(shù)據(jù)寄存器
          uchar tmp[5]; //顯示數(shù)據(jù)緩沖區(qū)
          uchar MODE2=0x49; //工作方式命令字
          //uchar Bank_sel=0x7a; //存儲(chǔ)體選擇命令字(未定義)
          uchar Digit[]={0xd7,0x06,0xe3,0xa7,0x36,0xb5,0xf5,0x17,0xf7,0xb7,0xd7};
          //{0,1,2,3,4,5,6,7,8,9,0}字形碼;其定義方法參見(jiàn)硬件接線圖。
          //延時(shí)程序======延時(shí)2*t機(jī)器周期=====
          void delay(uchar t)
          {
          while(--t);
          }
          //延時(shí)程序======長(zhǎng)延時(shí)=====
          void delay_long(uint time)
          {
          uchar i;
          do{
          for(i=100;i!=0;i--);
          } while(--time!=0);
          }
          /*********************************************************
          啟動(dòng)總線函數(shù)
          名稱(chēng):START
          描述:啟動(dòng)I2C 總線子程序--發(fā)送I2C 起始條件
          *********************************************************/
          void START(void)
          {
          SDA=1; SCL=1;
          delay(2); SDA=0;
          delay(2); SCL=0;
          }
          /*********************************************************
          停止總線函數(shù)
          名稱(chēng):STOP
          描述:停止I2C 總線子程序--發(fā)送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; //在此發(fā)出應(yīng)答或非應(yīng)答信號(hào)
          else SDA=1;
          delay(2);
          SCL=1;
          delay(2); //時(shí)鐘低電平周期大于4μs
          SCL=0;
          delay(2); //清時(shí)鐘線,鉗住I2C總線以便繼續(xù)接收
          }
          /*********************************************************
          發(fā)送一個(gè)字節(jié)函數(shù)
          名稱(chēng):SendByte
          描述:字節(jié)數(shù)據(jù)傳送子程序發(fā)送一個(gè)字節(jié)數(shù)據(jù)或地址給被控器PCF8576
          要發(fā)送的數(shù)據(jù)在ACC中;
          發(fā)送數(shù)據(jù)正常返回標(biāo)志F0=0 F0=1 表示被控器無(wú)應(yīng)答或損壞
          *********************************************************/
          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();
          }
          /***********************************************************
          發(fā)送數(shù)據(jù)函數(shù)
          名稱(chēng):Display_Data
          描述:發(fā)送ByteCnt 個(gè)字節(jié)給被控器PCF8576
          被控器地址在SlvAdr 中單元地址在SubAdr 中
          所發(fā)送數(shù)據(jù)的字節(jié)數(shù)ByteCnt 在中發(fā)送的數(shù)據(jù)在tmp[ ] 緩沖區(qū)中
          發(fā)送數(shù)據(jù)正常返回標(biāo)志F0=0 F0=1 表示被控器無(wú)應(yīng)答或損壞
          **********************************************************/
          void Display_Data(void)
          {
          uchar i=0;
          uchar size=ByteCnt;
          START(); //發(fā)送I2C 總線起始條件
          SendByte(SlvAdr); //發(fā)送被控器總線地址
          SendByte(SubAdr); //發(fā)送單元地址
          SendByte(0x70); //不閃爍命令字
          do
          {
          SendByte(tmp[i]); //發(fā)送數(shù)據(jù)
          i++;
          } while(--size!=0);
          STOP();
          delay(100);
          }
          /*********************************************************
          清除屏顯函數(shù)(未采用)
          名稱(chēng):ClearLcd
          描述:在向顯示屏送數(shù)據(jù)前清除原有顯示內(nèi)容
          *********************************************************/
          /*********************************************************
          void ClearLcd(void)
          {
          uchar size=ByteCnt;
          START(); //啟動(dòng)I2C 總線
          SendByte(SlvAdr); //送器件地址
          SendByte(SubAdr); //發(fā)送單元地址
          SendByte(0x70); //不閃爍命令字
          do
          {
          SendByte(0x00); //發(fā)送數(shù)據(jù)
          } while(--size!=0);
          STOP();
          delay(200);
          }
          *********************************************************/
          /*********************************************************
          器件總線初始化函數(shù)
          名稱(chēng):PCF8576SET
          描述:用于器件控制的重復(fù)操作的指令集和
          *********************************************************/
          void PCF8576SET(void)
          {
          START();
          SendByte(SlvAdr); //送器件地址
          SendByte(MODE2); //送方式命令字
          // SendByte(Bank_sel); //送存儲(chǔ)體選擇命令字
          STOP();
          }


          void main(void)
          {
          uchar i,k,m;
          uchar cnt[5];
          SubAdr=0x80; //為顯示緩沖區(qū)賦首地址
          SlvAdr=PCF8576; //賦器件總線地址
          ByteCnt=5; //顯示位數(shù)賦值
          PCF8576SET(); //總線初始化
          //ClearLcd(); //清除屏顯
          while(1)
          {
          for(m=1;m<11;m++) //0-9 10個(gè)數(shù)字計(jì)數(shù)
          {
          for(k=0;k<5;k++) //循環(huán)5次形成穩(wěn)定顯示
          {
          for(i=0;i<5;i++) //5位顯示
          {
          /***************************************************************************************
          以下的程序含義:
          顯示數(shù)據(jù)寄存器cnt[5]設(shè)定后,在沒(méi)有裝填前只是5個(gè)空位置,此時(shí)cnt[0]=0;cnt[1]=0---cnt[i]=0;
          在第一次執(zhí)行tmp[i]=Digit[cnt[i]];時(shí),屏幕顯示5位全0,接下來(lái)執(zhí)行cnt[4]++;后cnt[4]=1
          此后在下一次執(zhí)行tmp[i]=Digit[cnt[i]];時(shí)tmp[0]=Digit[cnt[0]]=Digit[0]=0(0xd7)其它依次同上
          直至tmp[4]=Digit[cnt[4]]=Digit[1]=1(0x06);此時(shí)屏顯為00001;循環(huán)重復(fù)直至當(dāng)?shù)谝蛔址焕塾?jì)
          為9時(shí)屏顯為99999此后屏顯清0如上重復(fù)。
          ****************************************************************************************/
          tmp[i]=Digit[cnt[i]]; //顯示數(shù)據(jù)裝入顯示緩存區(qū)
          Display_Data(); //顯示
          delay_long(50); //通過(guò)延時(shí)控制顯示字符的變換速度
          }
          }
          /*********************************************************************
          以下的程序含義:
          首先在第5位累加,滿(mǎn)10進(jìn)位1至99999時(shí)清0重復(fù)
          能力所限、終未能將下面單調(diào)的重復(fù)語(yǔ)句變?yōu)橐粋€(gè)算式模型。
          *********************************************************************/
          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的數(shù)字編碼是根據(jù)實(shí)際測(cè)繪的硬件電路圖編制的,至于別人程序中或PDF資料中的編碼方式,是絕不可以照搬的,因?yàn)槊恳环N模塊的內(nèi)部接線都不盡相同,編碼也就不同了,這種電路在控制時(shí),最主要的一點(diǎn)就是,一定要根據(jù)段碼位數(shù)先建立一個(gè)數(shù)組(顯示數(shù)據(jù)存儲(chǔ)區(qū)),在數(shù)據(jù)顯示之前,先把顯示數(shù)據(jù)裝填到數(shù)組當(dāng)中,再把它按位送入顯示緩沖區(qū)就OK了,至于開(kāi)總線,關(guān)總線,送指令,送數(shù)據(jù)等等都是模式化操作,只要按規(guī)定做好即可,控制起來(lái)也沒(méi)什么太復(fù)雜的;因?yàn)橹皇峭嫱?,不求甚解,至此,這只模塊也就玩完了,如果日后需要數(shù)字顯示的話(huà)或許還能用到它,別的用途我就想不出來(lái)了,至于做時(shí)間顯示,我總覺(jué)得它土不土、洋不洋沒(méi)勁。這種器件已流傳很久了,或許已經(jīng)過(guò)時(shí)了,或許還有新出的我不知道,雖然我玩過(guò)了,但這些資料可能還會(huì)有人有用,所以就放在這里共享吧。還是老辦法,程序是在μV2編譯軟件窗口中粘貼過(guò)來(lái)的,若有用的話(huà)反向操作即可;如果用到了就知會(huì)一聲,可以共享可以轉(zhuǎn)載,但不可做為網(wǎng)站的登陸下載資源,發(fā)現(xiàn)必究,僅此而已,別無(wú)它求。

          附硬件電路圖:



          關(guān)鍵詞: AT89S51I2CPCF8576段碼LCD模

          評(píng)論


          技術(shù)專(zhuān)區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();