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

          新聞中心

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

          基于MSP430的ADS7841驅(qū)動(dòng)程序

          作者: 時(shí)間:2016-11-13 來(lái)源:網(wǎng)絡(luò) 收藏
          師姐(博士)反向設(shè)計(jì)了ADS7841芯片。為了測(cè)試其穩(wěn)定性和精度,所以幫忙寫(xiě)了這個(gè)驅(qū)動(dòng)程序。最初是師兄用FPGA寫(xiě)的,但讀出來(lái)的數(shù)據(jù)差距太大,所以我就用430單片機(jī)幫忙搞了一個(gè)!但這個(gè)程序調(diào)試的并不順利,簡(jiǎn)直就是痛苦,我昨天中午和晚上都沒(méi)吃飯!首先碰到I/O口壞的情況,還有就是這個(gè)芯片的 DATASHEET關(guān)于讀數(shù)的說(shuō)明是錯(cuò)的,害人不淺!據(jù)datasheet解釋是等待busy信號(hào)為低才開(kāi)始讀數(shù),其實(shí)這個(gè)時(shí)候已經(jīng)晚了,會(huì)漏掉一位。所有上面這些問(wèn)題我是借助邏輯分析儀看出來(lái)的,把抓出來(lái)的時(shí)序一點(diǎn)點(diǎn)的分析,終于發(fā)現(xiàn)了讀數(shù)方面DATASHEET的漏洞。還有就是她沒(méi)提寫(xiě)數(shù)據(jù)和讀數(shù)據(jù)分別應(yīng)該在時(shí)鐘的什么沿觸發(fā)。實(shí)在讓人郁悶~!~正常應(yīng)該在下降沿寫(xiě)指令,上升沿讀數(shù)據(jù)!
          折騰了一天才有結(jié)果,如果不是邏輯分析儀的幫忙,我估計(jì)死都不知道怎么死的。。
          好了,情況說(shuō)明了,下面是代碼部分。
          *****************************************************************************
          ** 函數(shù)原型:unsigned int ADS7841_Read_Data(unsigned char Channel);
          ** 功 能:SPI總線的A/D ADS7841 驅(qū)動(dòng)程序
          ** 入口參數(shù):unsigned char Channel 表示選擇讀取通道
          ** 出口參數(shù):unsigned int 返回所讀取得12位數(shù)據(jù)。
          ** 說(shuō) 明:ADS7841為12位A/D,先對(duì)其進(jìn)行設(shè)置:數(shù)據(jù)位D0---D7,其中D0---D1是
          ** 設(shè)置ADC的功耗模式,D2是模擬輸入通道設(shè)置,H為4個(gè)單通道,L為兩個(gè)
          ** 差分輸入,D3為mode,當(dāng)mode(pin)接地時(shí)為12位采樣方式,接高電平時(shí)
          ** mode為1時(shí)8位采集,為0時(shí)12位采集,D4---D6為輸入通道選擇,D7為起始位
          ** 作  者: 沉思的魚(yú)
          ** 日  期: 2007年11月06日
          **-----------------------------------------------------------------------------
          ** 修 改 人:
          ** 日  期:
          *******************************************************************************/
          #include <msp430x14x.h>
          #define uint unsigned int
          #define uchar unsigned char
          #define ADS_S 0x80 //命令起始位
          #define ADS_MODE 0x08 //模式選擇。MODE端選擇直接接高電平,此位不用設(shè)置
          #define ADS_S_D 0x04 //輸入方式選擇
          #define ADS_POWER 0x00 //是否允許掉電
          #define DIR_CS P3DIR|=BIT0
          #define ADS_CS_1 P3OUT|=BIT0
          #define ADS_CS_0 P3OUT&=~BIT0 //片選
          #define ADS_DIR_IN P3DIR|=BIT1 //端口輸出模式
          #define ADS_DIN_1 P3OUT|=BIT1 //命令寫(xiě)入AD
          #define ADS_DIN_0 P3OUT&=~BIT1
          #define ADS_DIR_OT P2DIR&=~BIT0 //端口為輸入模式
          #define ADS_CLK_DIR P4DIR|=BIT4 //端口為輸出模式
          #define ADS_CLK_1 P4OUT|=BIT4 //時(shí)鐘置1
          #define ADS_CLK_0 P4OUT&=~BIT4 //時(shí)鐘置0
          #define DIR_BUSY P4DIR&=~BIT0
          //#define DATA_IN ((P4IN>>2 & 0x01)
          #define DATA_IN (P2IN & 0x01)
          #define BUSY_IN (P4IN & 0x01) //讀輸入數(shù)據(jù)
          void Check_busy(void);
          void SPI_WR(uchar DATA);
          void Init_Port(void);
          void delay(uint temp);
          uint ADS7841_Read_Data(uchar Channel);
          uint temp_DATA[100];
          void delay(uint temp1)
          {
          int i;
          for(i=temp1;i>0;i--)
          {
          ;
          }
          }
          uint ADS7841_Read_Data(uchar Channel) //Channel=0:CH0;1:CH1;2:CH2;3:CH3;
          {
          uint ADCResult=0;
          uchar i,ADS_CHANNEL;
          uint TempBit =0;
          uchar COMMAND=0;
          switch (Channel)
          {
          case 0:ADS_CHANNEL=0x10;break; //通道選擇
          case 1:ADS_CHANNEL=0x50;break;
          case 2:ADS_CHANNEL=0x20;break;
          case 3:ADS_CHANNEL=0x60;break;
          default:ADS_CHANNEL=0x10;break;
          }
          COMMAND=(ADS_S|ADS_CHANNEL|ADS_S_D|ADS_POWER);
          ADS_CLK_0;
          ADS_DIN_0; ///DIN先置0
          ADS_CS_0; //;片選信號(hào)
          //SPI_WR(COMMAND); //SPI總線寫(xiě)命令子程序
          //ADS_DIR_IN; //端口定義為輸出模式,上升沿發(fā)送,下降沿接受
          for(i=0;i<8;i++)
          {
          ADS_CLK_1;
          if( (COMMAND & 0x80) ==0x80)
          {
          ADS_DIN_1; //寫(xiě)入指令
          }
          else
          {
          ADS_DIN_0;
          }
          COMMAND<<=1; //左移
          delay(5);
          ADS_CLK_0;
          delay(5); //模擬SPI串行接口 發(fā)送數(shù)據(jù)
          }
          delay(5);
          ADS_CLK_0;
          Check_busy();
          //delay(5);
          for(i=0;i<12;i++)
          { //上升沿讀出數(shù)據(jù)
          ADS_CLK_0;
          delay(4);
          if( DATA_IN==0x01 )
          {
          TempBit=1;
          }
          else
          {
          TempBit=0;
          }
          ADS_CLK_1;
          ADCResult=((ADCResult<<1)|TempBit); //模擬SPI串行接口,接收數(shù)據(jù)
          delay(5);
          }
          ADS_CLK_0;
          for(i=0;i<4;i++)
          {
          ADS_CLK_1;
          delay(5);
          ADS_CLK_0;
          delay(5);
          }
          ADS_CS_1; //屏蔽片選
          return ADCResult;
          }
          void Check_busy(void)
          {
          int temp;
          //DIR_BUSY; //端口設(shè)置為輸入方式
          ADS_CLK_1;
          temp=BUSY_IN;
          ADS_CLK_0;
          while( (temp&0x01)==0) //檢測(cè)到高電平就開(kāi)始讀數(shù)。。不然會(huì)丟一位
          {
          ADS_CLK_1; //讀端口狀態(tài)....
          temp=BUSY_IN;
          //delay(5); //
          ADS_CLK_0;
          }
          //
          /* do
          {
          ADS_CLK_0; //讀端口狀態(tài)....
          temp=BUSY_IN;
          delay(5); //
          ADS_CLK_1;
          }while((temp&0x01)!=0); //高位為1為忙信號(hào)*/
          }
          void SPI_WR(uchar DATA)
          {
          uint i;
          ADS_DIR_IN; //端口定義為輸出模式,上升沿發(fā)送,下降沿接受
          for(i=0;i<8;i++)
          {
          ADS_CLK_1;
          if( (DATA & 0x80) ==0x80)
          {
          ADS_DIN_1; //寫(xiě)入指令
          }
          else
          {
          ADS_DIN_0;
          }
          DATA<<=1; //左移
          ADS_CLK_0;
          delay(5); //模擬SPI串行接口 發(fā)送數(shù)據(jù)
          }
          delay(5);
          ADS_CLK_0;
          }
          void Init_Port(void)
          {
          P3SEL=0X00;
          P4SEL=0X00;
          ADS_DIR_IN;
          ADS_DIR_OT;
          ADS_CLK_DIR;
          DIR_BUSY;
          DIR_CS;
          ADS_CLK_0;
          //delay(5);
          ADS_CS_1;
          // ADS_CLK_1;
          }
          void main(void)
          {
          WDTCTL = WDTPW+WDTHOLD; //關(guān)看門(mén)狗
          Init_Port(); //端口初始化
          uint flag=0;
          uint i;
          while(1)
          {
          for(i=0;i<5;i++)
          {
          temp_DATA[i]=ADS7841_Read_Data(0);
          delay(10);
          }
          flag=1;
          }

          }


          評(píng)論


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

          關(guān)閉