乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      基于51單片機(jī)的PCF8591電壓測(cè)量

       新用戶5228KeDY 2021-10-10

      基于51單片機(jī)的PCF8591電壓測(cè)量

      這個(gè)筆記記錄好久了。因?yàn)橄胪黄艫DS1115在STC89下的使用,但一直沒(méi)有太清晰的眉目和充裕的時(shí)間。不知道為什么各種資料里,ADS1115很少有介紹差分的,而都是單端的。這幾天忙時(shí)也無(wú)暇琢磨,于是輪到了PCF8591。

      STC89系列芯片不能直接測(cè)電壓,也就是這個(gè)系列的芯片沒(méi)有AD/DA轉(zhuǎn)換的本領(lǐng)。想測(cè)量電壓,就必須得借助PCF8591來(lái)幫忙。這一點(diǎn)上STC89跟ATTiny沒(méi)法比,實(shí)際ATTiny13/85都可以直接AD轉(zhuǎn)換。不過(guò)STC后期的STC8/12/15系列都自帶ADC引腳,可以直接使用的,價(jià)格可能也要貴一些。

      在STC89系列下使用PCF8591本質(zhì)就是IIC讀寫(xiě),然后轉(zhuǎn)換。但是說(shuō)起來(lái),實(shí)現(xiàn)起來(lái)也不容易。

      接線圖:

      代碼很混亂,不拆分,也不依賴外部其他文件,但是對(duì)PCF8591的使用流程則一目了然:

      #include<reg52.h>
      #include<intrins.h>
      #include <stdio.h>
      #include <stdlib.h>

      #define uchar unsigned char
      #define uint unsigned int
      uchar dat[8];
      uchar code char_temp[8] = {'\r''\n'};

      sbit SCL = P2 ^ 0;
      sbit SDA = P2 ^ 1;

      void IIC_Start(void)
      {
          SDA = 1;
          SCL = 1;
          _nop_();
          _nop_();
          SDA = 0;
          _nop_();
          _nop_();
          SCL = 0;
      }
      void IIC_Stop(void)
      {
          SDA = 0;
          SCL = 1;
          _nop_();
          _nop_();
          SDA = 1;
      }
      void IIC_Ack(unsigned char ackbit)
      {
          if(ackbit)
          {
              SDA = 0;
          }
          else
          {
              SDA = 1;
          }

          _nop_();
          _nop_();
          SCL = 1;
          _nop_();
          _nop_();
          SCL = 0;
          SDA = 1;
          _nop_();
          _nop_();
      }

      bit IIC_WaitAck(void)
      {
          SDA = 1;
          _nop_();
          _nop_();
          SCL = 1;
          _nop_();
          _nop_();

          if(SDA)
          {
              SCL = 0;
              IIC_Stop();
              return 0;
          }
          else
          {
              SCL = 0;
              return 1;
          }
      }

      void IIC_SendByte(unsigned char byt)
      {
          unsigned char i;

          for(i = 0; i < 8; i++)
          {
              if(byt & 0x80)
              {
                  SDA = 1;
              }
              else
              {
                  SDA = 0;
              }

              _nop_();
              _nop_();
              SCL = 1;
              byt <<= 1;
              _nop_();
              _nop_();
              SCL = 0;
          }

      }

      unsigned char IIC_RecByte(void)
      {
          unsigned char da;
          unsigned char i;

          for(i = 0; i < 8; i++)
          {
              SCL = 1;
              _nop_();
              _nop_();
              da <<= 1;

              if(SDA)
              da |= 0x01;
              SCL = 0;
              _nop_();
              _nop_();
          }
          return da;
      }

      void init_pcf8591(void)
      {
          IIC_Start();
          IIC_SendByte(0x90);    //PCF8591里的地址
          IIC_WaitAck();
          IIC_SendByte(0x00);  //選擇ADC通道,0x00電位器,0x01光敏,0x02熱敏
          IIC_WaitAck();
          IIC_Stop();
      }

      //接收PCF8591轉(zhuǎn)換過(guò)的采樣電壓值
      unsigned char adc_pcf8591(void)
      {
          unsigned char temp;
          IIC_Start();
          IIC_SendByte(0x91);
          IIC_WaitAck();
          temp = IIC_RecByte();
          IIC_Ack(0);
          IIC_Stop();
          return temp;
      }

      /**
       * 串口初始化函數(shù)
       * 波特率為9600
       */
      void UartConfigurationInit()
      {
          TMOD = 0x20; //設(shè)置定時(shí)器1工作方式為方式2
          TH1 = 0xfd;    //波特率9600
          TL1 = 0xfd;
          TR1 = 1;    //啟動(dòng)定時(shí)器1
          SM0 = 0;
          SM1 = 1;    //串口方式1
          REN = 1;    //允許接收
          PCON = 0x00; //關(guān)倍頻
          ES = 1;     //開(kāi)串口中斷
          EA = 1;     //開(kāi)總中斷
      }

      /**
       * 延時(shí)函數(shù)
       * 延時(shí)count毫秒
       */

      void delay(uint count)
      {
          uint cycle;
          while(count)
          {
              cycle = 120;
              while(cycle > 0) cycle--;
              count--;
          }
      }

      /**
       * 字符發(fā)送函數(shù)
       */
      void PostChar(uchar character)
      {
          SBUF = character; //發(fā)送單個(gè)字符
          while(!TI);
          TI = 0; //發(fā)送完成標(biāo)志
      }

      /**
       * 字符串發(fā)送函數(shù)
       * 通過(guò)調(diào)用字符發(fā)送函數(shù)來(lái)實(shí)現(xiàn)
       */
      void  PostString(uchar *p)
      {
          while(*p)      //若指針指向的地址為空,則跳出循環(huán)
          {
              PostChar(*p); //指針第一次默認(rèn)指向首地址
              delay(20);  //延時(shí),作用為提高發(fā)送準(zhǔn)確度
              p++;
          }
      }

      void main()
      {
          uint adNum;
          float value;
          UartConfigurationInit(); //初始化串口

          while(1)
          {
              init_pcf8591();
              PostString(char_temp); //發(fā)送字符串
              adNum = adc_pcf8591();
              value = adNum * 0.01953; //轉(zhuǎn)為電壓值
              adNum = value * 100;    //保留兩位小數(shù)
              dat[0] = adNum / 1000 + '0'; //加上'0'是表示數(shù)字轉(zhuǎn)換成字符
              dat[1] = adNum % 1000 / 100 + '0';
              dat[2] = '.';
              dat[3] = adNum % 100 / 10 + '0';
              dat[4] = adNum % 10 + '0';
              dat[5] = 'V';
              PostString(dat); //發(fā)送字符串
              delay(1000);
          }
      }

        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多