ADS1118控制命令写不进去
uint32_t SPI_RW_Reg(uint16_t CofigReg)
{
delay(10);
readata1=SPIx_ReadWriteByte((uint8_t)(CofigReg>>8));
readata2=SPIx_ReadWriteByte((uint8_t)CofigReg);
readata3=SPIx_ReadWriteByte((uint8_t)(CofigReg>>8));
readata4=SPIx_ReadWriteByte((uint8_t)CofigReg);
readata= (uint32_t)readata4|((uint32_t)readata3<<8)|((uint32_t)readata2<<16)|((uint32_t)readata1<<24);
delay(1000);
//ads_cs_1();
return readata;
}
这个函数我不知道那里有问题 帮忙看一下 谢谢
Hi
可以直接通过接口时序来确认看写入是否正确,再调整程序。
从这个函数看你是在读数据?写入命令的时序图用示波器看了没有
Fubo你好,
请问CS拉高拉低是在哪个函数里面实现的?
我在ADS1118的datasheet里面只看到了有16位与32位数据的读写。你的SPIx_ReadWriteByte函数是针对一个8位的数据进行操作的,ADS1118并不支持这样的读写方式。
请检查。祝一切顺利!
您好,我的思路如下:
#define AD_SPI1_CS PBout(3)// PB3
#define AD_SPI1_SCLK PBout(13)// PB13
#define AD_SPI1_MISO PBout(14)// PB14
#define AD_SPI1_MOSI PBout(15)// PB15
SCLK,MISO,MOSI 3个角的定义和初始化 还有SPI通信的参数设定
SPI_InitTypeDef SPI_InitStructure;
void SPIx_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB1Periph_SPI2, ENABLE );
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //时钟,我用的是GPIOA,和GPIOB,所以时钟GPIOA和GPIOB时钟开启,IO口复用AFIO时钟开启,我用的是SPI2,所以SPI2时钟开启
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIOB13为SCLK,GPIOB14为MISO,GPIOB15为MOSI
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //¸´ÓÃÍÆÍìÊä³ö
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; //SPI发送接收16位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行同步时钟的空闲状态为低电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //第二个跳变沿数据被采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号为软件控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //预分频256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
SPI_Init(SPI2, &SPI_InitStructure); //根据制定的参数初始化
SPI_Cmd(SPI2, ENABLE); //SPI2使能
SPIx_ReadWriteByte(0x85eb);
}
CS片选信号的定义初始化
void SPI_ADS_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //SPI CS
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_4);
SPIx_Init(); //SPI初始化
}
int main(void)
{
u8 a=0;
ADS_InitTypeDef ADS_InitStructure;
GPIO_Configuration(); //GPIO初始化
USART1_Configuration(); //串口初始化
SPIx_Init(); //SCLK,MISO,MOSI 3个角的定义和初始化 还有SPI通信的参数设定
SPI_ADS_Init(); //CS片选信号的定义初始化
while(1)
{
SPI2->CR2 |= SPI_I2S_IT_RXNE;
// SPI2->DR = V2In2_3ADC;
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)) //loop until DOUT/DRDY set low
{
printf("\n\r The Value is no ready \r");
}
AD_SPI1_CS=0; //CS信号片选为0
a=SPIx_ReadWriteByte(0xc9eb); //read data
delay(20);
AD_SPI1_CS=1//CS信号片选为1
printf("\n\r The Value is %08x \r",a);
}
}
//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
uint32_t SPIx_ReadWriteByte(uint16_t TxData) 函数说明
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存非空标志位
{
retry++;
if(retry>200)return 0;
}
SPI_I2S_SendData(SPI1, TxData); //通过外设SPIX发送一个数据(ST官方库提供的函数)
retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
{
retry++;
if(retry>200)return 0;
}
return SPI_I2S_ReceiveData(SPI1); //·返回通过SPIX最近接收的数据 (ST官方库提供的函数)
}
大哥 我不知道我的问题出在那个地方 帮我分析一下 谢谢 我用的是STM32单片机的硬件SPI (意法半导体)
程序我大概看了一下,怎么没发现你关于拉高CS脚的操作?
你用示波器测一下CS、CLK、DATA这几个引脚的波形看一看?
刘工,我把程序中CS拉高了 程序中我标了颜色
AD_SPI1_CS=0;
a=SPIx_ReadWriteByte(0xc9eb); //read data
delay(20);
AD_SPI1_CS=1;
CS有波形,很明显的矩形方波,但CLK,和DATA这些角都是没有波形的,数据没有写进去
Hi Fubo,
我花了好久好久仔细检查了一下你的代码。累死了,下次贴代码的时候最好稍微花点时间排下版这样别人也会更愿意去花时间看。
发现了这几个问题:
第一,你的SPI的寄存器设置为第二个跳变沿数据被采样,而实际上因为默认CLK为低电平,而你看Datasheet中,CLK上升沿的时候数据被读入ADS1118中,所以应该是第一个跳变沿数据被采样。请确认。
第二,也是最关键的是,你在初始化的时候都是对SPI2做的操作,而在程序的最下方,SPIx_ReadWriteByte这个函数在实现的时候,里面n多操作都是对SPI进行的。这应该是导致你看不到CLK以及DATA的数据的关键。请检查。
如果有最新的进展,或者调试成功,记得来这里更新一下进度哦~期待你的好消息
SCK,MISO,MOSI定义,SPI通信参数设定 ADS1118 SCK时序 是第一个上升沿获取数据
void SPIx_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1, ENABLE );
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //使能IO口复用时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; //16位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //时钟悬空高
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第一个时钟延
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //软件管理
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //波特率预分频256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC计算的多项式
SPI_Init(SPI1, &SPI_InitStructure); //初始化SPI寄存器
SPI_Cmd(SPI1, ENABLE); //SPI使能
}
片选信号CS定义和初始化
void SPI_ADS_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //SPI CS
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //复用推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_3);
SPIx_Init(); //初始化SPI
}
/*配置寄存器,将指令写入配置寄存器,采样转换完成*/
void ADS1118_ADS_Config(unsigned int temp_config_value)
{
unsigned int Config_Value;
Config_Value = temp_config_value;
AD_SPI1_CS=0; // Set CS low
delay(20); // Wait for slave to initialize
ADS1118_WriteSPI(Config_Value,1);// 0为连续模式,转换的数据放入寄存器
delay(20); // Wait for slave to initialize
AD_SPI1_CS=1; // Set CS high
}
/*转换,写入config寄存器*/
void ADS1118_WriteSPI(uint config,unsigned char mode)
{
uint temp;
uchar bit_ctr;
AD_SPI1_CS=0;
// MOSI_L;//DINÀ拉低,到clk为高(低)时输入
if(mode==1)temp = config | 0x8000;//mode==1,读数据并开始下次转换(OS位置为高)
// __delay_cycles(20);//等待OS置高后数据的转换(860sps)
// temp &=0x7FFF;//OS置0转换完成
for(bit_ctr=0;bit_ctr<16;bit_ctr++) // 16位配置写入config,DIN后开始转换
{
AD_SPI1_SCLK=0; // ..then set SCK low again
delay(20);
if(temp&0x8000)
AD_SPI1_MOSI=1;
else
AD_SPI1_MOSI=0;
AD_SPI1_SCLK=1; // Set SCK high..
delay(20);
temp = (temp << 1);
// if(MISO) temp++;
}
AD_SPI1_SCLK=0;
delay(20);
AD_SPI1_CS=1;
delay(20);
}
/*将数据读出(DOUT)*/
uint ADS1118_ADS_Read(void)
{
unsigned int Data=0;
int i;
int a[16];
AD_SPI1_SCLK=1;
if(!AD_SPI1_MISO)
{//如果DRDY为低,转换完成,则开始读取
for(i=0;i<16;i++)
{
AD_SPI1_SCLK=0;
delay(50);//clk高延时
if(AD_SPI1_MISO) a[i]=1;
else a[i]=0;
AD_SPI1_SCLK=1;
delay(20);//clk低延时
Data=Data*2+a[i];
}
}
//__delay_cycles(1600);
//CS_H;
return Data;
}
main函数中如下:
int main(void)
{
uint a;
ADS_InitTypeDef ADS_InitStructure;
RCC_Configuration();
NVIC_Configuration();
USART1_Configuration();
SPIx_Init();
SPI_ADS_Init();
LED_Init();
while(1)
{
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}//等待发送区为空
ADS1118_ADS_Config(0xd5eb); //read data
delay(10);
a=ADS1118_ADS_Read();
delay(20);
printf("\n\r The Value is %08x \r",a);
}
}
刘工,u8 SPIx_ReadWriteByte(u8 TxData) 这个函数也不能用,是8位的,我重新写了几个函数,奇怪的是始终没有波形,数据也一直是0,我用JLINK在线调试,始终发现返回值a一直是0,百思不得其解
您好,在ADS1118_ADS_Read函数中,你是想使用软件模拟SPI总线的时许吗?如果是,那么在初始化的时候应该将对应的引脚初始化为普通的IO
刘工,我采集到了数据000055eb
是正确的数据吗?还是一直保持这个数据不变?
好像一直是这个数据000055eb 不变,这是什么原因
请问你现在使用的读取ADC的代码是软件读取还是硬件读取?要不把现在使用的代码再贴上来?
//SPIx 读写一个字节
//TxData:要写入的字节
//·µ»ØÖµ:读取到的字节
u8 SPIx_ReadWriteByte(u8 TxData)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否,发送缓存空标志位
{
retry++;
if(retry>200)return 0;
}
SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据
retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); //检查指定的SPI标志位设置与否,接收缓存空标志位
{
retry++;
if(retry>200)return 0;
}
return SPI_I2S_ReceiveData(SPI1); //返回通过SPIX最近接收的数据
}
while(1)
{
//SPIx_ReadWriteByte(0x85eb); //read data
delay(10);
a=SPIx_ReadWriteByte(0x85eb);
delay(20);
printf("\n\r The Value is %08x \r",a);
}
The Value is 000000b1
The Value is 000005ea
The Value is 000000c3
The Value is 000005ea
The Value is 0000008d
The Value is 000005ea
The Value is 000000a8
The Value is 000005ea
The Value is 000000ad
The Value is 000005ea
The Value is 00000097
The Value is 000005ea
The Value is 000000aa
The Value is 000005ea
The Value is 00000087
The Value is 000005ea
The Value is 000000b7
The Value is 000005ea
The Value is 00000075
The Value is 000005ea
The Value is 000000a1
把第一行注释掉后 出来的数据又乱跳
Hi Fubo,
我应该对你说恭喜你,你的SPI驱动已经调出来了。
为什么呢,因为你看ADS1118的datasheet的第21页,关于bit15的说明里面有一句话:
Always reads back as '0' (default).
所以,当你写入0x85eb时,因为bit15不管你写入什么,总会返回0,所以返回值就变成了0x05eb。
bit0也是类似,总是读回1。
如果还有什么问题欢迎继续回帖^_^
你的这个回复我没太看懂。。。
while(1)
{
//SPIx_ReadWriteByte(0x85eb); //read data
delay(10);
a=SPIx_ReadWriteByte(0x85eb);
delay(20);
printf("\n\r The Value is %08x \r",a);
}
The Value is 000000b1
The Value is 000005ea
The Value is 000000c3
The Value is 000005ea
The Value is 0000008d
The Value is 000005ea
The Value is 000000a8
The Value is 000005ea
The Value is 000000ad
原来的while
while(1)
{
SPIx_ReadWriteByte(0x85eb); //read data
delay(10);
a=SPIx_ReadWriteByte(0x85eb);
delay(20);
printf("\n\r The Value is %08x \r",a);
}
注释了第一行之后
while(1)
{
//SPIx_ReadWriteByte(0x85eb); //read data
delay(10);
a=SPIx_ReadWriteByte(0x85eb);
delay(20);
printf("\n\r The Value is %08x \r",a);
}
数据就变成了这个样子 不稳定 数据好像在跳
The Value is 00000bd6
The Value is 00000186
The Value is 00000bd6
The Value is 00000186
The Value is 00000bd6
The Value is 00000186
The Value is 00000bd6
The Value is 00000186
The Value is 00000bd6
The Value is 00000186
刘工 如果不注释第一行
while(1)
{
SPIx_ReadWriteByte(0x85eb); //read data
delay(10);
a=SPIx_ReadWriteByte(0x85eb);
delay(20);
printf("\n\r The Value is %08x \r",a);
}
返回值
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
第15位 读状态 0 设备正在转换 1设备未转换
第0位 1正在转换
00005eb 就是0000 0101 1110 1011 确实是ADS1118正在转换 但为什么值老是00005eb呢 恒定数值不变
不知道是我眼瞎还是你没把代码贴完整,我在你最新的程序里面仍然没发现你对CS拉高拉低的操作。是不是把这个给忘记啦?
刘工 不好意思 我搞忘了 我按照时序加进去
while(1)
{
AD_SPI1_CS=1;
delay(1);
AD_SPI1_CS=0;
SPIx_ReadWriteByte(0x85eb); //read data
delay(10);
a=SPIx_ReadWriteByte(0x85eb);
delay(20);
printf("\n\r The Value is %08x \r",a);
}
刘工 你说我的ADS1118设备也在正常转换数据,为什么读到的数据一直是
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
那你期望的输出的数据是什么呢?
天不早了我先去睡觉了哈~
睡前提醒一下,在16位的模式下,写入的是16位的控制命令,读出来的是ADC的采样数据。
32位的模式下才能读出写入的控制命令,参见下图:
刘工,因为我这里ADS1118是外接一个温度传感器,我把传感器放在手上,这个检测数据会随着温度变化,我写入的控制命令是0x85eb,我不明白为什么我读出来的一直是一个恒定的数据,而且ADS1118还在不停的转换数据,所以刘工帮忙看一下,谢谢
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
The Value is 000005eb
Hi Fubo,
你把第一据ReadWrite注释掉,输出的就是ADC当前采集到的值了。
如下所示:
while(1)
{
AD_SPI1_CS=1;
delay(1);
AD_SPI1_CS=0;
// SPIx_ReadWriteByte(0x85eb); //read data
delay(10);
a=SPIx_ReadWriteByte(0x85eb);
delay(20);
printf("\n\r The Value is %08x \r",a);
}
The Value is 000001b0
The Value is 000005ea
The Value is 000001af
The Value is 000005ea
The Value is 000001bc
The Value is 000005ea
The Value is 00000180
The Value is 000005ea
The Value is 000001b2
The Value is 000005ea
The Value is 0000018a
The Value is 000005ea
The Value is 000001a9
The Value is 000005ea
The Value is 000001b6
The Value is 000005ea
The Value is 000001be
The Value is 000005ea
The Value is 000001c5
刘工,我看了一下 ,1b6,1c5,1be这些数据应该都是有效数据,5ea是什么数据,这个数据明显无效,我是不是应该用软件滤波把它滤掉
这个是你注释掉了第一句ReadWrite函数之后得到的结果么?
是的
楼主你好,你看你放不方便用示波器或者逻辑分析仪分析一下,当CS拉低的时候,CLK引脚有多少个时钟出现?
如果交替出现寄存器的值与ADC的采集的值的话,CLK不应该是16个。
四通道示波器 测量波形上传分析。
楼主你好,请问问题解决了吗?
刘工,您好,我也用ADS1118作为温度AD,代码如下,
for(;;)
{
//SPI发送 给 ADS1118
GpioDataRegs.GPACLEAR.bit.GPIO19 = 0; //先 Set SPI STE=0
Spi_Txmit(AD_CH1CMD); //发送命令,读取通道1温度AD_CH1CMD = 0x8591;
//AIN0,AIN1差分输入,温度传感器模式
i=0;
while(i<10000)i++; //延时
Spi_Rx(&SPiaCh1RxBuf);
GpioDataRegs.GPACLEAR.bit.GPIO19 = 1;
}
SPiaCh1RxBuf 读取到的数据大部分情况下是0,有个别是0x058B,按照datasheet,转换成温度是44.34375°C,不知道这种情况算是通了没有?请您帮忙看看,多谢。。