参照ADS1118的说明书,我使用CC2530的串口1的SPI方式向ADS1118连接写入4个字节的命令,我想问一下我如何才从ADS1118中读回命令寄存器中的值呢。意思就是在我写入命令字之后,我应该怎样操作才能读回这些值,我现在直接读U1DBUF的值完全与我写进去的不一样啊。谢谢
green lenerd:
我现在是这样子写的:
void InitialADS(void)//初始化ADS1118,写入默认的0x8583
{
uint8 cmd[4]={0x85,0x83,0x00,0x00};
//拉低SSN,片选信号使能
SSN = 0;
//写入命令字初始化ADS1118工作方式
while(!U1TX_BYTE);
for(int i=0;i<4;i++)//写入两次命令字
{
U1DBUF = cmd[i];
while(!U1TX_BYTE);
}
SSN = 1;
}
然后读取的时候
void ReadVoltage(uint8 *voltage)//读取电压数据
{
//开启转换
uint8 cmd[8]={0xD5,0x83,0x00,0x00};
SSN = 0;
//写入命令字初始化ADS1118工作方式
for(int i=0;i<4;i++)//写入命令字,0xD5,0x83
{
U1DBUF = cmd[i];
while(!U1TX_BYTE);
}
//需要延时吗?
uint8 *p = voltage;
for(int i=0;i<4;i++)
{
U1DBUF = 0x00;
while(!U1TX_BYTE);
p[i] = U1DBUF;
}
SSN = 1;
}
但是这样子读出来的数据是不对的啊
HaiTao Li:
回复 green lenerd:
你也可以把与SPI相关的程序完整的贴出来,我这儿也有CC2530和ADS1118,如果有时间的话可以调一下。
另外,我建议你点击一下你问题左下角的“编辑标签“,并加入ADS1118和SPI,然后保存。这样以后其他人遇到类似问题,以ADS1118和SPI为关键字进行检索,可以检索的你的这一篇。重在分享么,我是这么理解的。同样,问题也是可以不断编辑的,所以,后续的问题你可以在原有问题里面接着写,用分割线隔开加上日期即可。
green lenerd:
回复 HaiTao Li:
好的,我自己试一下,太谢谢了,因为是第一次做这个,有点纠结,如果有问题我再贴出来,谢谢你呀
green lenerd:
回复 HaiTao Li:
我的代码是这样子写的:
#define SSN P1_3#define MISO P1_7#define MOSI P1_6#define SCLK P1_5
uint8 voltage[4]={0,0,0,0};uint8 counter = 0;
void InitialUBARTSPI(void)//初始化SPI{ //引脚绑定设置 PERCFG |=0x02;//选择UBART1作为SPI模式 P1SEL |=0xE0;//P1_7,P1_6,P1_5 P1SEL &=~0x08;//P1_3为通用IO口(SSN) P1DIR |=0x08;//SSN的方向设为输出 //SCLK频率设置,设置波特率11520,U1BAUD_M=216,U1GCR_E=11,波特率115200 U1BAUD = 0xD8; U1GCR |= 0x0B; //操作模式,设置为Master模式 U1CSR &= ~0xA0; //配置CPOL与CPHA,ADS1118要求CPOL=0,CPHA=1 U1GCR &=~0x80; U1GCR |=0x40; //配置传输先后顺序,ADS1118要求先传高再传低 U1GCR |=0x20; //设置P1_7中断模式 P1DIR &=~0x80; P1IEN |=0x080;//使能P1_7中断 PICTL |= 0x02; //下降沿触发 IEN2 |=0x10;//端口1中断使能 P1IFG &= ~0x80; EA = 1;//开启所有的中断}
#pragma vector = P1INT_VECTOR__interrupt void P1_ISR(void){ P1IFG &=~0x80;//清除中断标志 voltage[counter] = U1DBUF; counter++; if(counter>3) counter =0; P1IF = 0;}
void InitialADS(void)//初始化ADS1118,写入默认的0x8583{ uint8 cmd[4]={0x85,0x83,0x85,0x83}; //拉低SSN,片选信号使能 SSN = 0; //写入命令字初始化ADS1118工作方式 while(!U1TX_BYTE); for(int i=0;i<4;i++)//写入两次命令字 { U1DBUF = cmd[i]; while(!U1TX_BYTE); U1TX_BYTE =0;//清除状态字 }SSN = 1;}
void StartConvert(void)//启动转换,写入命令字0xD593{ uint8 cmd[8]={0xD5,0x83,0xD5,0x83}; //拉低SSN,片选信号使能SSN = 0; //写入命令字初始化ADS1118工作方式 for(int i=0;i<4;i++)//写入命令字,0xD5,0xE2 { U1DBUF = cmd[i]; while(!U1TX_BYTE); U1TX_BYTE = 0; }SSN = 1;}
green lenerd:
回复 HaiTao Li:
现在的疑问就是在读取数据的时候,怎样才能读取到4个字节的数据,是一次读呢,还是每次触发的时候读一个字节组成四个字节呢,因为看DataSheet上看得我有点迷惑。现在的情况好点了,因为写进命令字之后读出来的数据中有命令字了,就是顺序很乱,我感觉还是我读取的时候有问题。程序里我用的是用的ADS1118的AN1路来采集电压的
HaiTao Li:
回复 green lenerd:
从程序和命令字看没什么问题,而且也得到返回值了。下来是数据的问题,答案主要集中在手册的16和17页上。因为你使用的是默认值,关于最终数据结果的计算还要注意下面两部分的内容。(我也看了一下CC2530的手册,发现程序中已经注意到了模式设置和中断打开。)
1、bit11-bit9,从这部分的描述看,ADS1118转换AD值是有量程的(其他人或许会有别的表述方式,我在这里用量程来表述),默认设定是把信号放大两倍,即输入量程除2。具体对应关系如下:
000~0: 2/3倍,实际输入量程-6.114~+6.114;001~1: 1,倍,实际输入范围(实际量程)-4.096~+4.096……共2/3~16六个放大级别。
要根据设定在换算过程中除以不同的放大倍率并进行格式转换才能还原到输入值;如果采集值是被后续电路处理的,且符合要求,就不用换算了,但是要根据设定值的意义告诉电路设计人员采集值的意义。
2、bit7-bit5,这个与数据换算本身无关,但是与采集速率有关系,因为存在一个采样和准备好的过程,个人感觉与此处有关。
另外,ADS1118是可以用来采集电压信号,但是它是带有内部温度补偿的AD芯片,如果仅仅是电压采集的话,不必如此,使用ADS1115或者ADS1110不是也可以么,IIC接口。
最后,是测试相关的,注意检查供电电压,信号发生器与ADS1118线缆的连接,MCU与AD的连接线,如果确信这些都没问题,可以给一个正值按照上述规则计算。计算测试结果可能有偏差甚至错误,通常与上述检查项有关。如果器件是已经焊接在做好的实验板上的话,情况会好很多。
HaiTao Li:
回复 green lenerd:
关于读取,是与写入有关的:写入——产生时钟信号——(如果数据准备好)驱动返回值。所以,如果一次写入8位,就会有8个连续时钟信号产生,并驱动返回8位值,那么当中断产生时,SPI寄存器里就会有8位值。
HaiTao Li:
搞定了?