色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ADDA系列PCF8591的驅(qū)動(dòng)程序

          ADDA系列PCF8591的驅(qū)動(dòng)程序

          作者: 時(shí)間:2016-11-18 來(lái)源:網(wǎng)絡(luò) 收藏
          /*************************此部分為I2C總線驅(qū)動(dòng)程序*************************************/

          #include
          #include
          #include

          本文引用地址:http://cafeforensic.com/article/201611/315912.htm

          #define NOP() _nop_() /* 定義空指令 */
          #define _Nop() _nop_() /*定義空指令*/


          sbit SCL=P2^0; //I2C 時(shí)鐘
          sbit SDA=P2^1; //I2C 數(shù)據(jù)
          bit ack; /*應(yīng)答標(biāo)志位*/

          /*******************************************************************
          起動(dòng)總線函數(shù)
          函數(shù)原型: void Start_I2c();
          功能: 啟動(dòng)I2C總線,即發(fā)送I2C起始條件.
          ********************************************************************/
          void Start_I2c()
          {
          SDA=1; /*發(fā)送起始條件的數(shù)據(jù)信號(hào)*/
          _Nop();
          SCL=1;
          _Nop(); /*起始條件建立時(shí)間大于4.7us,延時(shí)*/
          _Nop();
          _Nop();
          _Nop();
          _Nop();
          SDA=0; /*發(fā)送起始信號(hào)*/
          _Nop(); /* 起始條件鎖定時(shí)間大于4μs*/
          _Nop();
          _Nop();
          _Nop();
          _Nop();
          SCL=0; /*鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù) */
          _Nop();
          _Nop();
          }

          /*******************************************************************
          結(jié)束總線函數(shù)
          函數(shù)原型: void Stop_I2c();
          功能: 結(jié)束I2C總線,即發(fā)送I2C結(jié)束條件.
          ********************************************************************/
          void Stop_I2c()
          {
          SDA=0; /*發(fā)送結(jié)束條件的數(shù)據(jù)信號(hào)*/
          _Nop(); /*發(fā)送結(jié)束條件的時(shí)鐘信號(hào)*/
          SCL=1; /*結(jié)束條件建立時(shí)間大于4μs*/
          _Nop();
          _Nop();
          _Nop();
          _Nop();
          _Nop();
          SDA=1; /*發(fā)送I2C總線結(jié)束信號(hào)*/
          _Nop();
          _Nop();
          _Nop();
          _Nop();
          }

          /*******************************************************************
          字節(jié)數(shù)據(jù)發(fā)送函數(shù)
          函數(shù)原型: void SendByte(UCHAR c);
          功能: 將數(shù)據(jù)c發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待應(yīng)答,并對(duì)
          此狀態(tài)位進(jìn)行操作.(不應(yīng)答或非應(yīng)答都使ack=0)
          發(fā)送數(shù)據(jù)正常,ack=1; ack=0表示被控器無(wú)應(yīng)答或損壞。
          ********************************************************************/
          void SendByte(unsigned char c)
          {
          unsigned char BitCnt;

          for(BitCnt=0;BitCnt<8;BitCnt++) /*要傳送的數(shù)據(jù)長(zhǎng)度為8位*/
          {
          if((c< else SDA=0;
          _Nop();
          SCL=1; /*置時(shí)鐘線為高,通知被控器開始接收數(shù)據(jù)位*/
          _Nop();
          _Nop(); /*保證時(shí)鐘高電平周期大于4μs*/
          _Nop();
          _Nop();
          _Nop();
          SCL=0;
          }

          _Nop();
          _Nop();
          SDA=1; /*8位發(fā)送完后釋放數(shù)據(jù)線,準(zhǔn)備接收應(yīng)答位*/
          _Nop();
          _Nop();
          SCL=1;
          _Nop();
          _Nop();
          _Nop();
          if(SDA==1)ack=0;
          else ack=1; /*判斷是否接收到應(yīng)答信號(hào)*/
          SCL=0;
          _Nop();
          _Nop();
          }

          /*******************************************************************
          字節(jié)數(shù)據(jù)接收函數(shù)
          函數(shù)原型: UCHAR RcvByte();
          功能: 用來(lái)接收從器件傳來(lái)的數(shù)據(jù),并判斷總線錯(cuò)誤(不發(fā)應(yīng)答信號(hào)),
          發(fā)完后請(qǐng)用應(yīng)答函數(shù)應(yīng)答從機(jī)。
          ********************************************************************/
          unsigned char RcvByte()
          {
          unsigned char retc;
          unsigned char BitCnt;

          retc=0;
          SDA=1; /*置數(shù)據(jù)線為輸入方式*/
          for(BitCnt=0;BitCnt<8;BitCnt++)
          {
          _Nop();
          SCL=0; /*置時(shí)鐘線為低,準(zhǔn)備接收數(shù)據(jù)位*/
          _Nop();
          _Nop(); /*時(shí)鐘低電平周期大于4.7μs*/
          _Nop();
          _Nop();
          _Nop();
          SCL=1; /*置時(shí)鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效*/
          _Nop();
          _Nop();
          retc=retc<<1;
          if(SDA==1)retc=retc+1; /*讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中 */
          _Nop();
          _Nop();
          }
          SCL=0;
          _Nop();
          _Nop();
          return(retc);
          }

          /********************************************************************
          應(yīng)答子函數(shù)
          函數(shù)原型: void Ack_I2c(bit a);
          功能: 主控器進(jìn)行應(yīng)答信號(hào)(可以是應(yīng)答或非應(yīng)答信號(hào),由位參數(shù)a決定)
          ********************************************************************/
          void Ack_I2c(bit a)
          {

          if(a==0)SDA=0; /*在此發(fā)出應(yīng)答或非應(yīng)答信號(hào) */
          else SDA=1;
          _Nop();
          _Nop();
          _Nop();
          SCL=1;
          _Nop();
          _Nop(); /*時(shí)鐘低電平周期大于4μs*/
          _Nop();
          _Nop();
          _Nop();
          SCL=0; /*清時(shí)鐘線,鉗住I2C總線以便繼續(xù)接收*/
          _Nop();
          _Nop();
          }

          #include
          #include

          #define PCF8591 0x90 //PCF8591 地址


          //else IO
          sbit LS138A=P2^2;
          sbit LS138B=P2^3;
          sbit LS138C=P2^4;

          //此表為 LED 的字模, 共陰數(shù)碼管 0-9 -
          unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

          unsigned char AD_CHANNEL;
          unsigned long xdata LedOut[8];
          unsigned int D[32];

          /*******************************************************************
          DAC 變換, 轉(zhuǎn)化函數(shù)
          *******************************************************************/
          bit DACconversion(unsigned char sla,unsigned char c, unsigned char Val)
          {
          Start_I2c(); //啟動(dòng)總線
          SendByte(sla); //發(fā)送器件地址
          if(ack==0)return(0);
          SendByte(c); //發(fā)送控制字節(jié)
          if(ack==0)return(0);
          SendByte(Val); //發(fā)送DAC的數(shù)值
          if(ack==0)return(0);
          Stop_I2c(); //結(jié)束總線
          return(1);
          }

          /*******************************************************************
          ADC發(fā)送字節(jié)[命令]數(shù)據(jù)函數(shù)
          *******************************************************************/
          bit ISendByte(unsigned char sla,unsigned char c)
          {
          Start_I2c(); //啟動(dòng)總線
          SendByte(sla); //發(fā)送器件地址
          if(ack==0)return(0);
          SendByte(c); //發(fā)送數(shù)據(jù)
          if(ack==0)return(0);
          Stop_I2c(); //結(jié)束總線
          return(1);
          }

          /*******************************************************************
          ADC讀字節(jié)數(shù)據(jù)函數(shù)
          *******************************************************************/
          unsigned char IRcvByte(unsigned char sla)
          { unsigned char c;

          Start_I2c(); //啟動(dòng)總線
          SendByte(sla+1); //發(fā)送器件地址,地址加一的原因是地址字的最后一位0為寫,1為讀
          if(ack==0)return(0);
          c=RcvByte(); //讀取數(shù)據(jù)0

          Ack_I2c(1); //發(fā)送非就答位
          Stop_I2c(); //結(jié)束總線
          return(c);
          }

          //******************************************************************/
          main()
          { char i,j;

          while(1)
          {/********以下AD-DA處理*************/
          switch(AD_CHANNEL)
          {
          case 0: ISendByte(PCF8591,0x41);
          D[0]=IRcvByte(PCF8591)*2; //ADC0 模數(shù)轉(zhuǎn)換1,乘以2的原因是把結(jié)果00~0xff換算成0~510,除以100就是實(shí)際采樣值了
          break;

          case 1: ISendByte(PCF8591,0x42);
          D[1]=IRcvByte(PCF8591)*2; //ADC1 模數(shù)轉(zhuǎn)換2
          break;

          case 2: ISendByte(PCF8591,0x43);
          D[2]=IRcvByte(PCF8591)*2; //ADC2模數(shù)轉(zhuǎn)換3
          break;

          case 3: ISendByte(PCF8591,0x40);
          D[3]=IRcvByte(PCF8591)*2; //ADC3 模數(shù)轉(zhuǎn)換4
          break;

          case 4: DACconversion(PCF8591,0x40, D[4]/4); //DAC 數(shù)模轉(zhuǎn)換
          break;
          }

          // D[4]=400; //數(shù)字--->>模擬輸出
          D[4]=D[3];
          if(++AD_CHANNEL>4) AD_CHANNEL=0;

          /********以下將AD的值送到LED數(shù)碼管顯示*************/

          LedOut[0]=Disp_Tab[D[1]%10000/1000];
          LedOut[1]=Disp_Tab[D[1]%1000/100];
          LedOut[2]=Disp_Tab[D[1]%100/10]|0x80;
          LedOut[3]=Disp_Tab[D[1]%10];

          LedOut[4]=Disp_Tab[D[0]%10000/1000];
          LedOut[5]=Disp_Tab[D[0]%1000/100];
          LedOut[6]=Disp_Tab[D[0]%100/10]|0x80;
          LedOut[7]=Disp_Tab[D[0]%10];


          for( i=0; i<8; i++)
          { P1 = LedOut[i];

          switch(i) //使用switch 語(yǔ)句控制138譯碼器 也可以是用查表的方式 學(xué)員可以試著自己修改
          {
          case 0:LS138A=0; LS138B=0; LS138C=0; break;
          case 1:LS138A=1; LS138B=0; LS138C=0; break;
          case 2:LS138A=0; LS138B=1; LS138C=0; break;
          case 3:LS138A=1; LS138B=1; LS138C=0; break;
          case 4:LS138A=0; LS138B=0; LS138C=1; break;
          case 5:LS138A=1; LS138B=0; LS138C=1; break;
          case 6:LS138A=0; LS138B=1; LS138C=1; break;
          case 7:LS138A=1; LS138B=1; LS138C=1; break;

          }

          for (j = 0 ; j<90 ;j++) { ;} //掃描間隔時(shí)間
          }

          P1 = 0;

          }
          }



          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉