微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 基于MSP430的ADS7841驱动程序

基于MSP430的ADS7841驱动程序

时间:11-13 来源:互联网 点击:
师姐(博士)反向设计了ADS7841芯片。为了测试其稳定性和精度,所以帮忙写了这个驱动程序。最初是师兄用FPGA写的,但读出来的数据差距太大,所以我就用430单片机帮忙搞了一个!但这个程序调试的并不顺利,简直就是痛苦,我昨天中午和晚上都没吃饭!首先碰到I/O口坏的情况,还有就是这个芯片的 DATASHEET关于读数的说明是错的,害人不浅!据datasheet解释是等待busy信号为低才开始读数,其实这个时候已经晚了,会漏掉一位。所有上面这些问题我是借助逻辑分析仪看出来的,把抓出来的时序一点点的分析,终于发现了读数方面DATASHEET的漏洞。还有就是她没提写数据和读数据分别应该在时钟的什么沿触发。实在让人郁闷~!~正常应该在下降沿写指令,上升沿读数据!
折腾了一天才有结果,如果不是逻辑分析仪的帮忙,我估计死都不知道怎么死的。。
好了,情况说明了,下面是代码部分。
*****************************************************************************
** 函数原型:unsigned int ADS7841_Read_Data(unsigned char Channel);
** 功 能:SPI总线的A/D ADS7841 驱动程序
** 入口参数:unsigned char Channel 表示选择读取通道
** 出口参数:unsigned int 返回所读取得12位数据。
** 说 明:ADS7841为12位A/D,先对其进行设置:数据位D0---D7,其中D0---D1是
** 设置ADC的功耗模式,D2是模拟输入通道设置,H为4个单通道,L为两个
** 差分输入,D3为mode,当mode(pin)接地时为12位采样方式,接高电平时
** mode为1时8位采集,为0时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端选择直接接高电平,此位不用设置
#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 //时钟置1
#define ADS_CLK_0 P4OUT&=~BIT4 //时钟置0
#define DIR_BUSY P4DIR&=~BIT0
//#define DATA_IN ((P4IN>>2 & 0x01)
#define DATA_IN (P2IN & 0x01)
#define BUSY_IN (P4IN & 0x01) //读输入数据
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; //;片选信号
//SPI_WR(COMMAND); //SPI总线写命令子程序
//ADS_DIR_IN; //端口定义为输出模式,上升沿发送,下降沿接受
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串行接口 发送数据
}
delay(5);
ADS_CLK_0;
Check_busy();
//delay(5);
for(i=0;i<12;i++)
{ //上升沿读出数据
ADS_CLK_0;
delay(4);
if( DATA_IN==0x01 )
{
TempBit=1;
}
else
{
TempBit=0;
}
ADS_CLK_1;
ADCResult=((ADCResult<1)|TempBit); //模拟SPI串行接口,接收数据
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; //端口设置为输入方式
ADS_CLK_1;
temp=BUSY_IN;
ADS_CLK_0;
while( (temp&0x01)==0) //检测到高电平就开始读数。。不然会丢一位
{
ADS_CLK_1; //读端口状态....
temp=BUSY_IN;
//delay(5); //
ADS_CLK_0;
}
//
/* do
{
ADS_CLK_0; //读端口状态....
temp=BUSY_IN;
delay(5); //
ADS_CLK_1;
}while((temp&0x01)!=0); //高位为1为忙信号*/
}
void SPI_WR(uchar DATA)
{
uint i;
ADS_DIR_IN; //端口定义为输出模式,上升沿发送,下降沿接受
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串行接口 发送数据
}
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; //关看门狗
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;
}

}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top