单片机SPI驱动ADS869读到的数据和发送不一致怎么回事
Kailyn Chen:
您好,很抱歉,没有提供ADS8689的程序可供参考。
或者建议您可到英文e2e论坛上咨询一下:e2e.ti.com/…/73
user4762775:
回复 Kailyn Chen:
问题以解决贴上STM32驱动代码
uint8_t busy_flag = IDLE_STATUS;
/*** @briefadc spi GPIO配置 * @paramNone* @paramNone* @return None*/
void adc_spi_gpio(void)
{GPIO_InitTypeDef GPIO_InitStructure;
/* 配置 SPI引脚SCK、MISO 和 MOSI为复用推挽模式 */GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = PIN_SCK|PIN_MISO|PIN_MOSI; GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*** @briefadc 外设配置 * @paramNone* @paramNone* @return None*/void adc_spi_init(void)
{SPI_InitTypeDefSPI_InitStructure;
SPI_Cmd(SPI1, DISABLE);/* 先禁止SPI*//* 配置SPI硬件参数 */SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; /* 数据方向:2线全双工 */SPI_InitStructure.SPI_Mode = SPI_Mode_Master;/* STM32的SPI工作模式 :主机模式 */SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; /* 数据位长度 : 8位 */SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;/* 时钟上升沿采样数据 */SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;/* 时钟的第1个边沿采样数据 */SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;/* 片选控制方式:软件控制 */
/* 设置波特率预分频系数 SPI_BaudRatePrescaler_8 ,实测SCK周期 96ns, 10.4MHz */SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; /* 数据位传输次序:高位先传 */SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &SPI_InitStructure);SPI_Cmd(SPI1, ENABLE);/* 使能SPI*/SPI_I2S_ClearITPendingBit(SPI1, SPI_I2S_IT_TXE);SPI_I2S_ClearITPendingBit(SPI1, SPI_I2S_IT_RXNE);
}/*** @briefads8689_read_write(uint16_t ch)* @paramdata :要发送的数据 * @return 返回收到的数据*/
uint16_t ads8689_read_write(uint16_t data)
{/* 等待发送缓冲区为空,TXE 事件 */while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);SPI_I2S_SendData(SPI1, data);while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);return SPI_I2S_ReceiveData(SPI1);
}
/*** @briefads8689_int()* @param8689的初始化* @return */
void ads8689_int(void)
{adc_spi_gpio();adc_spi_init();
}
/*** @briefdelay_5us()* @paramcount :要延迟的时间* @retval */
void delay_us(uint16_t count)
{ uint16_t i=72*count;while(i–){__ASM("NOP");}
}
/*** @briefads8689_write_cmd(uint16_t cmd_hi,uint16_t cmd_li)* @paramli_data :要发送的低位数据* @paramhi_data :要发送的高位数据* @return 返回收到的数据*/
uint8_tads889_busy_set(uint8_t busy)
{uint8_t ret = 0;switch(busy){/*空闲状态*/case IDLE_STATUS:busy_flag = IDLE_STATUS;ADS8689_DISABLE;break;/*忙状态*/case BUSY_STATUS:busy_flag = BUSY_STATUS;ADS8689_ENABLE;break;default:ret = 1;break;}return ret;
}
/*** @briefuint8_t get_busy_status(void)* @param无* @return 返回 busy_flag IDLE_STATUS / BUSY_STATUS*/
uint8_t get_busy_status(void)
{return busy_flag;
}
/*** @briefads8689_write_cmd(uint16_t cmd_hi,uint16_t cmd_li)* @paramli_data :要发送的低位数据* @paramhi_data :要发送的高位数据* @return 成功与失败 0:设置成功 1:设置失败*/
uint8_t ads8689_write_cmd(uint16_t cmd_hi,uint16_t cmd_li)
{
uint8_t ret;/*ADS8986使能*/if(ads889_busy_set(BUSY_STATUS)) //设置成功为 0{ret = 1;return ret;}else{ads8689_read_write(cmd_hi);ads8689_read_write(cmd_li);ret = 0;}if(ads889_busy_set(IDLE_STATUS)) //设置成功为 0{ret = 1;return ret;}
return ret;
}
/*** @briefconv_state(void)* @param无* @param无* @return 成功与失败 0:设置成功 1:设置失败*/
uint8_t conv_state(void)
{uint8_t ret;/*ADS8986使能*/if(ads889_busy_set(BUSY_STATUS)) //设置成功为 0{ret = 1;return ret;}else{ret =0;delay_us(5);}if(ads889_busy_set(IDLE_STATUS)) //设置成功为 0{ret = 1;return ret;}
return ret;
}
/*** @briefads8689_read_data(uint16_t hi_data,uint16_t li_data,uint32_t * result)* @paramli_data :要发送的低位数据* @paramhi_data :要发送的高位数据* @paramresult :寄存器读到的结果通过指针传出* @return 成功与失败 0:设置成功 1:设置失败*/
uint8_t ads8689_read_data(uint16_t hi_data,uint16_t li_data,uint32_t * result)
{uint8_t ret;uint32_t value;/*ADS8986使能*/if(ads889_busy_set(BUSY_STATUS)) //设置成功为 1{ret = 1;return ret;}else{value = ads8689_read_write(hi_data);value =value<<16;value += ads8689_read_write(li_data);*result = value;ret = 0;}if(ads889_busy_set(IDLE_STATUS)) //设置成功为 0{ret = 1;return ret;}
return ret;
}/*** @briefuint8_t device_id(uint16_t *id)* @paramid :寄存器读到的结果通过指针传出* @return 成功与失败 0:设置成功 1:设置失败*/
uint8_t device_id(uint16_t *id)
{uint8_t ret = 0;uint32_t reslut;if(ads8689_write_cmd(0xc800,0x0000)){ret =1;return ret;}if(ads8689_read_data(0,0,&reslut)){ret =1;return ret;}*id = (reslut>>16);return ret;
}/*** @briefuint8_t measured_value(uint32_t *reslut)* @paramreslut :寄存器读到的结果通过指针传出* @paramnum :采集次数* @return 成功与失败 0:设置成功 1:设置失败*/
uint8_t measured_value(uint32_t *reslut,uint16_t num)
{
// uint16_t set_value = PAR_EN | RANGE_INC | IN_ACTIVE_ALARM_INCL
//|VDD_ACTIVE_ALARM_INCL|DEVICE_ADDR_INCL;uint16_t get_reslut[255]={0};uint32_t value =0;uint8_t ret =0;uint16_t i = 0;for(i = 0; i < num; i ++){if(ads8689_write_cmd(0x0000,0)){ret =1;return ret;}if ( ads8689_read_data(0,0,&value)){ret =1;return ret;}value = ((value >>16) & 0x0000ffff);get_reslut[i] = value;}value =0;for(i = 0; i < num;i ++){value += get_reslut[i]; }*reslut = value/num;return ret;
}
/*** @briefuint8_t in_rang_select(uint16_t cmd)* @paramcmd :INT_30VREF (3*vref ) INT_25VREF (2.5*vref )INT_15VREF (1.5*vref ) INT_125VREF (1.25*vref )* @return 成功与失败 0:设置成功 1:设置失败*/
uint8_t in_rang_select(uint16_t cmd)
{uint8_t ret =0;uint32_t reslut;if(ads8689_write_cmd(0xd014,cmd)){ret =1;return ret;}if(ads8689_write_cmd(0xc814,0)){ret =1;return ret;}if ( ads8689_read_data(0,0,&reslut)){ret =1;return ret;}else{if ((reslut>>16) == cmd){ret =0;return ret;}else{ret =1;return ret;}}return ret;
}