新聞中心

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)定性和精度,所以幫忙寫了這個(gè)驅(qū)動(dòng)程序。最初是師兄用FPGA寫的,但讀出來(lái)的數(shù)據(jù)差距太大,所以我就用430單片機(jī)幫忙搞了一個(gè)!但這個(gè)程序調(diào)試的并不順利,簡(jiǎn)直就是痛苦,我昨天中午和晚上都沒吃飯!首先碰到I/O口壞的情況,還有就是這個(gè)芯片的 DATASHEET關(guān)于讀數(shù)的說明是錯(cuò)的,害人不淺!據(jù)datasheet解釋是等待busy信號(hào)為低才開始讀數(shù),其實(shí)這個(gè)時(shí)候已經(jīng)晚了,會(huì)漏掉一位。所有上面這些問題我是借助邏輯分析儀看出來(lái)的,把抓出來(lái)的時(shí)序一點(diǎn)點(diǎn)的分析,終于發(fā)現(xiàn)了讀數(shù)方面DATASHEET的漏洞。還有就是她沒提寫數(shù)據(jù)和讀數(shù)據(jù)分別應(yīng)該在時(shí)鐘的什么沿觸發(fā)。實(shí)在讓人郁悶~!~正常應(yīng)該在下降沿寫指令,上升沿讀數(shù)據(jù)!
折騰了一天才有結(jié)果,如果不是邏輯分析儀的幫忙,我估計(jì)死都不知道怎么死的。。
好了,情況說明了,下面是代碼部分。
*****************************************************************************
** 函數(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ù)。
** 說 明: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為起始位
** 作  者: 沉思的魚
** 日  期: 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 //命令寫入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總線寫命令子程序
//ADS_DIR_IN; //端口定義為輸出模式,上升沿發(fā)送,下降沿接受
for(i=0;i<8;i++)
{
ADS_CLK_1;
if( (COMMAND & 0x80) ==0x80)
{
ADS_DIN_1; //寫入指令
}
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è)到高電平就開始讀數(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; //寫入指令
}
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)看門狗
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ù)專區(qū)

關(guān)閉