Other Parts Discussed in Thread: ADS8166, ADS8866
Hi,I have some problems when developing with ADS8867.I can not get the correct ADC value in GPIO mode and SPI mode.
1/In GPIO mode.
Solution 1.
GPIO configuration:
DIN:Output Push Pull Mode, Max speed 50M,High
CONVEST:Output Push Pull Mode, Max speed 50M
SCLK:Output Push Pull Mode, Max speed 50M
DOUT:Input Mode,Floating input
void bsp_adc_ads8867_init(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStructure.Pin = ADC_ADS867_PIN_SCK | ADC_ADS867_PIN_CNV; HAL_GPIO_Init(ADC_ADS867_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.Mode = GPIO_MODE_INPUT; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStructure.Pull = GPIO_PULLDOWN; GPIO_InitStructure.Pin = ADC_ADS867_PIN_SDO; HAL_GPIO_Init(ADC_ADS867_GPIO_PORT, &GPIO_InitStructure); TCNV(0);//CONVEST Low TSCK(0);//SCLK Low } uint16_t bsp_adc_ads8867_read(void) { uint8_t i; uint16_t temp = 0; GPIO_InitTypeDef GPIO_InitStructure; TCNV(0);//CONVEST Low ADC_ADS867_CONV_LOW_DELAY();//CONVEST Low delay about 16ns TCNV(1);//CONVEST High and enter a conversion phase. ADC_ADS867_CONV_HIGH_DELAY();//CONVEST High delay about 6000ns or 12000ns TCNV(0);//CONVEST Low for(i=0;i<16;i++) { temp <<= 1; TSCK(1);//SCLK High ADC_ADS867_SCLK_HIGH_DELAY();//SCLK High delay 48ns. F(SCLK)< 16MHz. TSCK(0);//SCLK Low if(TSDO==1)//Read DOUT { temp |= 0x0001; } ADC_ADS867_SCLK_LOW_DELAY();//SCLK Low delay 48ns.F(SCLK)< 16MHz. } return temp; }
The bsp_adc_ads8867_read() function called in timer 2 isr function,the period of timer 2 is 1ms.
If the CONVEST High delay about 6000ns,I can not get the correct ADC Value,all the ADC value are zero.
If the CONVEST High delay about 12000ns,I can get the correct ADC Value,but the ADC value is zero sometimes.
I view the timing diagram on the oscilloscope,It seems only the falling edge of SCLK,the data is vaild and start output.
So I change the code as below,but still can not solve the problem.
Solution 2.
uint16_t bsp_adc_ads8867_read(void) { uint8_t i; uint16_t temp = 0; TCNV(0);//CONVST Low ADC_ADS867_CONV_LOW_DELAY();//CONVST Low delay about 16ns TCNV(1);//CONVST High ADC_ADS867_CONV_HIGH_DELAY();//CONVST High delay about 12000ns /***** Falling for data start output******/ TSCK(1);//SCLK High ADC_ADS867_SCLK_HIGH_DELAY();//SCLK High delay about 48ns.f(SCLK) < 16MHz. /***** Falling for data start output******/ TCNV(0);//SCLK Low ADC_ADS867_CONV_LOW_DELAY();//SCLK Low about 48ns. f(SCLK) < 16MHz. /***** Falling for data start output******/ TSCK(0); ADC_ADS867_SCLK_LOW_DELAY(); /***** Falling for data start output******/ for(i=0;i<16;i++) { temp <<= 1; TSCK(1);//SCLK Low if(TSDO==1)//Read DOUT { temp |= 0x0001; } ADC_ADS867_SCLK_HIGH_DELAY();//SCLK High delay about 48ns.f(SCLK) < 16MHz. TSCK(0);//SCLK Low ADC_ADS867_SCLK_LOW_DELAY();//SCLK Low delay about 48ns.f(SCLK) < 16MHz. } return temp; }
This solution I can get the correct ADC Value,but the ADC value is zero sometimes.
I wonder if I miss anything in GPIO mode?
2/SPI Mode
static void MX_SPI2_Init(void) { /* SPI1 parameter configuration*/ hspi2.Instance = SPI2; hspi2.Init.Mode = SPI_MODE_MASTER; hspi2.Init.Direction = SPI_DIRECTION_2LINES_RXONLY; hspi2.Init.DataSize = SPI_DATASIZE_16BIT; //hspi2.Init.DataSize = SPI_DATASIZE_8BIT; hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH; //hspi2.Init.CLKPolarity = SPI_POLARITY_LOW; hspi2.Init.CLKPhase = SPI_PHASE_2EDGE; //hspi2.Init.CLKPhase = SPI_PHASE_1EDGE; hspi2.Init.NSS = SPI_NSS_SOFT; //hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;//SPI = 8M hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi2.Init.TIMode = SPI_TIMODE_DISABLE; hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi2.Init.CRCPolynomial = 7; if (HAL_SPI_Init(&hspi2) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) { GPIO_InitTypeDef GPIO_InitStruct; #if 1//FOR_AD_SPI if(hspi->Instance==SPI2) { /* USER CODE BEGIN SPI1_MspInit 0 */ /* USER CODE END SPI1_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_SPI2_CLK_ENABLE(); /**SPI2 GPIO Configuration PB12 ------> SPI2_NSS PB13 ------> SPI2_SCK PB14 ------> SPI2_MISO PB15 ------> SPI2_MOSI */ GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_14; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* USER CODE BEGIN SPI1_MspInit 1 */ /* USER CODE END SPI1_MspInit 1 */ } #endif } void bsp_adc_ads8867_init(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStructure.Pin = ADC_ADS867_PIN_CNV | ADC_ADS867_PIN_DIN; HAL_GPIO_Init(ADC_ADS867_GPIO_PORT, &GPIO_InitStructure); TCNV(0); TDIN(1); } uint16_t bsp_adc_ads8867_read(void) { uint8_t i; uint16_t temp = 0; GPIO_InitTypeDef GPIO_InitStructure; HAL_StatusTypeDef err_code = HAL_OK; uint8_t data[2]; TCNV(0); ADC_ADS867_CONV_LOW_DELAY(); TCNV(1); ADC_ADS867_CONV_HIGH_DELAY(); TCNV(0); err_code = HAL_SPI_Receive(&hspi2, data, 1, 1000);//SPI receive if(err_code != HAL_OK) { DEBUG_BY_LUOGF_PRINTF(0,"[%d][%s][err_code = %d]\r\n",__LINE__,__FUNCTION__,err_code); } temp = (uint16_t)((data[0]<<8)|(data[1]<<0)); return temp; }
The bsp_adc_ads8867_read() function called in timer 2 isr function,the period of timer 2 is 1ms.
In SPI mode 0 and SPI mode 3, the ADC Value is not correct and ADC value is not equal to zero.
I wonder if I miss anything in SPI mode?
Best regards.