Перейти к содержанию
    

STM32F107RCT6 + ADS1256

Пытаюсь подключить ADS1256 (АЦП) к 107-мому по SPI .

Схему подключения, настройки МК и SPI, даташит АЦП - приложил.

Ну и собственно сам код:

/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
** This notice applies to any and all portions of this file
* that are not between comment pairs USER CODE BEGIN and
* USER CODE END. Other portions of this file, whether
* inserted by the user or by software development tools
* are owned by their respective copyright owners.
*
* COPYRIGHT© 2018 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f1xx_hal.h"

/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "math.h"
#include <string.h>
#include <errno.h>

#define CS_ON() HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET) // Vkluchenie ADC
#define CS_OFF() HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET) // Vikluchenie ADC
#define ADS_DRDY (HAL_GPIO_ReadPin(DRDY_GPIO_Port, DRDY_Pin)==GPIO_PIN_SET) // Proverka gotovnosti ADC
/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi3;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
uint8_t aTxBuffer[1]={0}; // Buffer dlya otpravlyaemih dannih
uint8_t aRxBuffer[3]={0,0,0}; // Buffer dlya prinimaemih dannih
uint32_t result;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI3_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/

/* Funkciya inicializacii ADC */
void ADS1256_Init(void)
{
CS_ON(); // Aktiviruem ADC
HAL_Delay(100);
aTxBuffer[0]=0xFE; // Ukazivaem adres commandi RESET
HAL_SPI_Transmit(&hspi3, (uint8_t*)aTxBuffer, 1, 50); // Posilaem komandy RESET (sbrasivaem ADC k defoltnim nastroykam)
HAL_Delay(100);

aTxBuffer[0]=0xFC;// Ukazivaem adres commandi SYNC
HAL_SPI_Transmit(&hspi3, (uint8_t*)aTxBuffer, 1, 50); // Posilaem komandy SYNC (sinhronizaciya ADC s signalom na vivode SCLK)
aTxBuffer[0]=0x00; // Ukazivaem adres commandi WAKEUP
HAL_SPI_Transmit(&hspi3, (uint8_t*)aTxBuffer, 1, 50); // Posilaem komandy WAKEUP (v sootvetstvii s datasheet)

aTxBuffer[0]=0x50 | 0x00; // Ukazivaem adress registra s kotorogo nachinaetsa zapis (STATUS)
HAL_SPI_Transmit(&hspi3, (uint8_t*)aTxBuffer, 1, 50); // Peredaem adress pervogo registra
aTxBuffer[0]=3; // Ukazivaem kolichestvo registrov v kotorie budem zapisivat (zapisivaetsa 1 + TO KOLICHESTVO KOTOROE UKAZIVAEM, V DANOM SLUCHAE POLUCHAETSA 1+3=4)
HAL_SPI_Transmit(&hspi3, (uint8_t*)aTxBuffer, 1, 50); // Peredaem kolichesto registrov

aTxBuffer[0]=0x04; // Ukazivaem dannie, kotorie neobhodimo zapisat v pervyi registr (STATUS) - ustanavlivaem poryadok chteniya so starshego bayta (MSB), vkluchaem avto-kalibrovky, vikluchaem analogovyi buffer, dubliruem vivod DRDY
HAL_SPI_Transmit(&hspi3, (uint8_t*)aTxBuffer, 1, 50); // Peredaem dannie v registr STATUS
/* while(ADS_DRDY) {}; // Vozmojno nujno dlya ojidaniya zaversheniya avtokalibrovki */

aTxBuffer[0]=0x00 | 0x01; // Ukazivaem dannie, kotorie neobhodimo zapisat vo vtoroy registr (MUX) - vkluchaem vhod AIN0 kak POSITIVE, AIN1 kak NEGATIVE
HAL_SPI_Transmit(&hspi3, (uint8_t*)aTxBuffer, 1, 50); // Peredaem dannie v registr MUX

aTxBuffer[0]=0x00; // Ukazivaem dannie, kotorie neobhodimo zapisat v tretyi registr (ADCON) - otkluchaem CLK0/CLK1, otkluchaem datchik opredeleniya istochnika toka, ustanavlivaem vnutrennyi usilitel v 64 raza
HAL_SPI_Transmit(&hspi3, (uint8_t*)aTxBuffer, 1, 50); // Peredaem dannie v registr ADCON

aTxBuffer[0]=0x82; // Ukazivaem dannie, kotorie neobhodimo zapisat v chetvertyi registr (DRATE) - zadaem skorost raboti ADC (kolichestvo viborok v sekundu), v dannom sluchae 100 SPS
HAL_SPI_Transmit(&hspi3, (uint8_t*)aTxBuffer, 1, 50); // Peredaem dannie v registr DRATE

HAL_Delay(100); //min=50*(1/fCLKIN)=50*(1/7.68MHZ)=6500ns;max=whatever

CS_OFF(); // Vikluchaem ADC
HAL_Delay(100);
}

/* Funkciya polucheniya rezultata ODNOGO preobrazovaniya */
uint32_t ADS1256ReadData(void)
{
uint32_t sum=0;

CS_ON(); // Aktiviruem ADC

aTxBuffer[0]=0x01; // Ukazivaem adres commandi READ DATA
HAL_SPI_Transmit(&hspi3, (uint8_t*)aTxBuffer, 1, 50); // Posilaem komandy READ DATA (chtenie rezultata ODNOGO preobrazovaniya)
HAL_SPI_Receive(&hspi3, (uint8_t*)aRxBuffer, 3, 50); // Schitivaem poluchennyi rezultat (3 bayta)

sum = aRxBuffer[0];
sum = sum << 8; // Poetomy, posle kajdogo poluchennogo bayta provodim smeshenie na 8
sum |= aRxBuffer[1];
sum = sum << 8;
sum |= aRxBuffer[2];

CS_OFF(); // Vikluchaem ADC
return sum; // Vozvrashaem znachenie poluchennogo rezultata
}
/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
* @brief The application entry point.
*
* @retval None
*/
int main(void)
{
/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/* MCU Configuration----------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */
SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */
MX_GPIO_Init();

MX_SPI3_Init();
/* USER CODE BEGIN 2 */
HAL_Delay(100);
ADS1256_Init();
HAL_Delay(100);
/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
result = ADS1256ReadData();
while (ADS_DRDY) {}
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

}
/* USER CODE END 3 */

}

/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{

RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;

/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;
RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL8;
RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV5;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

/**Configure the Systick interrupt time
*/
__HAL_RCC_PLLI2S_ENABLE();

/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

/* SPI3 init function */
static void MX_SPI3_Init(void)
{

/* SPI3 parameter configuration*/
hspi3.Instance = SPI3;
hspi3.Init.Mode = SPI_MODE_MASTER;
hspi3.Init.Direction = SPI_DIRECTION_2LINES;
hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
hspi3.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi3.Init.NSS = SPI_NSS_SOFT;
hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi3.Init.TIMode = SPI_TIMODE_DISABLE;
hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi3.Init.CRCPolynomial = 7;
if (HAL_SPI_Init(&hspi3) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

}

/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
static void MX_GPIO_Init(void)
{

GPIO_InitTypeDef GPIO_InitStruct;

/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();

/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);

/*Configure GPIO pin : DRDY_Pin */
GPIO_InitStruct.Pin = DRDY_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(DRDY_GPIO_Port, &GPIO_InitStruct);

/*Configure GPIO pin : CS_Pin */
GPIO_InitStruct.Pin = CS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(CS_GPIO_Port, &GPIO_InitStruct);
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
* @brief This function is executed in case of error occurrence.
* @param file: The file name as string.
* @param line: The line in file as a number.
* @retval None
*/
void _Error_Handler(char *file, int line)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
while(1)
{
}
/* USER CODE END Error_Handler_Debug */
}

#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/**
* @}
*/

/**
* @}
*/

/************************ © COPYRIGHT STMicroelectronics *****END OF FILE****/

 

В итоге во входной буфер приходят только нулевые значения.

Если посылать команду RDATAC (т.е. выполнять не единичное преобразование, а сделать так, чтобы АЦП постоянно слал 24 бита один за другим), результат такой же.

 

Не понимаю в чем проблема, не правильная инициализация или схема?

 

post-93818-1523420010_thumb.jpg

 

post-93818-1523420003_thumb.jpg

Изменено пользователем remixx

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

SPI вы правильно настроили?

1) для начала соединить MISO с MOSI что приходит ну и саму настройку SPI - правильно ноги затактированы

2) Проверьте фазу SPI - там 4 возможных режима

3) Проверьте чтобы CS начинался до транзакций и заканчивался после них через небольшую задержку

Изменено пользователем Сергей Борщ
Бездумное цитирование!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

SPI вы правильно настроили?

1) для начала соединить MISO с MOSI что приходит ну и саму настройку SPI - правильно ноги затактированы

2) Проверьте фазу SPI - там 4 возможных режима

3) Проверьте чтобы CS начинался до транзакций и заканчивался после них через небольшую задержку

GPIO для SPI3 куб настраивает в файле stm32f1xx_hal_msp.c, включенном в проект. Его содержимое:

/**
  ***************************************************************************
***
  * File Name          : stm32f1xx_hal_msp.c
  * Description        : This file provides code for the MSP Initialization 
  *                      and de-Initialization codes.
  ***************************************************************************
***
  ** This notice applies to any and all portions of this file
  * that are not between comment pairs USER CODE BEGIN and
  * USER CODE END. Other portions of this file, whether 
  * inserted by the user or by software development tools
  * are owned by their respective copyright owners.
  *
  * COPYRIGHT(c) 2018 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ***************************************************************************
***
  */
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"

extern void _Error_Handler(char *, int);
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */
/**
  * Initializes the Global MSP.
  */
void HAL_MspInit(void)
{
  /* USER CODE BEGIN MspInit 0 */

  /* USER CODE END MspInit 0 */

  __HAL_RCC_AFIO_CLK_ENABLE();

  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

  /* System interrupt init*/
  /* MemoryManagement_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0);
  /* BusFault_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0);
  /* UsageFault_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0);
  /* SVCall_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SVCall_IRQn, 0, 0);
  /* DebugMonitor_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0);
  /* PendSV_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(PendSV_IRQn, 0, 0);
  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

    /**ENABLE: Full SWJ (JTAG-DP + SW-DP): Reset State 
    */
  __HAL_AFIO_REMAP_SWJ_ENABLE();

  /* USER CODE BEGIN MspInit 1 */

  /* USER CODE END MspInit 1 */
}

void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(hspi->Instance==SPI3)
  {
  /* USER CODE BEGIN SPI3_MspInit 0 */

  /* USER CODE END SPI3_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_SPI3_CLK_ENABLE();
  
    /**SPI3 GPIO Configuration    
    PC10     ------> SPI3_SCK
    PC11     ------> SPI3_MISO
    PC12     ------> SPI3_MOSI 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    __HAL_AFIO_REMAP_SPI3_ENABLE();

  /* USER CODE BEGIN SPI3_MspInit 1 */

  /* USER CODE END SPI3_MspInit 1 */
  }

}

void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
{

  if(hspi->Instance==SPI3)
  {
  /* USER CODE BEGIN SPI3_MspDeInit 0 */

  /* USER CODE END SPI3_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_SPI3_CLK_DISABLE();
  
    /**SPI3 GPIO Configuration    
    PC10     ------> SPI3_SCK
    PC11     ------> SPI3_MISO
    PC12     ------> SPI3_MOSI 
    */
    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12);

  /* USER CODE BEGIN SPI3_MspDeInit 1 */

  /* USER CODE END SPI3_MspDeInit 1 */
  }

}

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

 

Проблема походу не в коде. На схеме отсутствует кварц, а в дш он есть. Детали уже приобрел, во вторник протестирую вместе с ним.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проблема походу не в коде. На схеме отсутствует кварц, а в дш он есть. Детали уже приобрел, во вторник протестирую вместе с ним.

 

можно с ноги контроллера протактировать

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вернулся к работе, но после всех корректировок так ничего и не изменилось)

Может быть я неправильно настраиваю CPOL и CPHA?

Приложил картинку передачи сигналов из ДШ.

По-моему в настройках SPI нужно устанавливать CPOL - 0, CPHA - 1Edge.

Еще кстати заметил, что в настройках выводов SCK и MOSI заданы как AF, а MISO как Input. А разве MISO не должен тоже задаваться как AF?

post-93818-1525682583_thumb.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может быть я неправильно настраиваю CPOL и CPHA?

Приложил картинку передачи сигналов из ДШ.

Фазировку шины проверьте осциллографом, и сравните картинку с даташитом.

 

А также (я работал с ADS1247, ADS131E04):

1. Проверьте, что тактовая частота SPI укладывается в допустимые.

2. Проверьте, что сигнал CS удерживается в низком уровне на время передачи кода команды и её аргументов (некоторые МК дёргают CS после передачи каждого байта, так работать не будет).

3. Считайте значения регистров по-умолчанию из АЦП, по ним можно сразу проверить, работает ли шина или нет. Я таким образом детектирую наличие АЦП на шине, и его косвенную исправность.

4. Проверьте, что CS опускается в ноль чуть раньше передачи данных по шине, и поднимается в 1 - чуть позже. Эти времена уточнить по даташиту. Я просто сделал 1 мс с большим запасом.

5. Ну и банально: проверьте уровни всхем питаний, доходят ли сигналы шины до АЦП и т.п.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В общем случае надо смотреть такие вещи:

- правильно настроить SPI - режим 1

- очень внимательно прочитать ДШ на АЦП на предмет команд, работы SPI и особенно важно не упустить задержки, коих там много и без их соблюдения нормальной работы не будет!

- выбросить HAL и написать нормально - это самый лучший путь, АЦП достаточно сложный в плане работы (для новичка конечно).

А так могу сказать, что АЦП работает - у меня в текущем проекте их 3 штуки на плате и все прекрасно работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Фазировку шины проверьте осциллографом, и сравните картинку с даташитом.

 

А также (я работал с ADS1247, ADS131E04):

1. Проверьте, что тактовая частота SPI укладывается в допустимые.

2. Проверьте, что сигнал CS удерживается в низком уровне на время передачи кода команды и её аргументов (некоторые МК дёргают CS после передачи каждого байта, так работать не будет).

3. Считайте значения регистров по-умолчанию из АЦП, по ним можно сразу проверить, работает ли шина или нет. Я таким образом детектирую наличие АЦП на шине, и его косвенную исправность.

4. Проверьте, что CS опускается в ноль чуть раньше передачи данных по шине, и поднимается в 1 - чуть позже. Эти времена уточнить по даташиту. Я просто сделал 1 мс с большим запасом.

5. Ну и банально: проверьте уровни всхем питаний, доходят ли сигналы шины до АЦП и т.п.

 

1. Насколько я понимаю рабочая частота АЦП определяется кварцем? В таком случае она равна 8 МГц. Частоту SPI беру с очень большим запасом (1.125 МГц, картинка ниже).

2. А такое наблюдается даже если дергаешь CS программно?

3. Попробую.

4. По задержкам ниже представил код с исправлениями.

5. Проверил, по питанию все уровне в норме.

 

В общем случае надо смотреть такие вещи:

- правильно настроить SPI - режим 1

- очень внимательно прочитать ДШ на АЦП на предмет команд, работы SPI и особенно важно не упустить задержки, коих там много и без их соблюдения нормальной работы не будет!

- выбросить HAL и написать нормально - это самый лучший путь, АЦП достаточно сложный в плане работы (для новичка конечно).

А так могу сказать, что АЦП работает - у меня в текущем проекте их 3 штуки на плате и все прекрасно работает.

 

1. Настройку SPI выполняю только в кубе, ниже рисунок с параметрами из 1 поста. Нужно ли кроме этого что-то настраивать еще?

 

post-93818-1525752896_thumb.jpg

 

2. После доработок получился вот такой код с учетом задержек:

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI3_Init();
  /* USER CODE BEGIN 2 */
      DWT_Delay_Init();

      CS_ON(); // Enable CS
      DWT_Delay_us(10); // Задержка t3. По ДШ её может и не быть (0 нс), но небольшую все-таки сделал - 10 мкс. Пробовал и больше (1 мс).
      spiTxBuf[0]=0xFE; // Set RESET command address
      HAL_SPI_Transmit(&hspi3, spiTxBuf, 1, 50); // Transmit buffer via SPI
      CS_OFF(); // Disable CS

      CS_ON(); // Enable CS
      DWT_Delay_us(10); // Задержка t3.
      spiTxBuf[0]=0x0F; // Set SDATAC command address
      HAL_SPI_Transmit(&hspi3, spiTxBuf, 1, 50); // Transmit buffer via SPI
      CS_OFF(); // Disable CS

      CS_ON(); // Enable CS
      DWT_Delay_us(10); // Задержка t3.
      spiTxBuf[0]=0x50; // Set WREG command address + address of STATUS register
      HAL_SPI_Transmit(&hspi3, spiTxBuf, 1, 50); // Transmit buffer via SPI
      spiTxBuf[0]=3; // Set number of registers to be written
      HAL_SPI_Transmit(&hspi3, spiTxBuf, 1, 50); // Transmit buffer via SPI
      spiTxBuf[0]=0x02; // STATUS - MSB; Disable auto-calibration; Disable buffer; DRDY
      spiTxBuf[1]=0x01; // MUX - AIN0 as POSITIVE, AIN1 as NEGATIVE
      spiTxBuf[2]=0x00; // ADCON - Clock out disable; Sensor detect disable; PGA = 1
      spiTxBuf[3]=0xF0; // DRATE - 30000 SPS
      HAL_SPI_Transmit(&hspi3, spiTxBuf, 4, 50); // Transmit buffer via SPI
      CS_OFF(); // Disable CS
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
      CS_ON(); // Enable CS
      DWT_Delay_us(10); // Задержка t3.
      spiTxBuf[0]=0xFC; // Set SYNC command address
      HAL_SPI_Transmit(&hspi3, spiTxBuf, 1, 50); // Transmit buffer via SPI
      CS_OFF(); // Disable CS

      CS_ON(); // Enable CS
      DWT_Delay_us(10); // Задержка t3.
      spiTxBuf[0]=0x00; // Set WAKEUP command address
      HAL_SPI_Transmit(&hspi3, spiTxBuf, 1, 50);
      CS_OFF(); // Disable CS

      while(HAL_GPIO_ReadPin(DRDY_GPIO_Port, DRDY_Pin)==GPIO_PIN_SET) {} // Read level of DRDY pin, if it's set to HIGH - wait

      CS_ON(); // Enable CS
      DWT_Delay_us(10); // Задержка t3.
      spiTxBuf[0]=0x01; // Set RDATA command address
      HAL_SPI_Transmit(&hspi3, spiTxBuf, 1, 50); // Transmit buffer via SPI
      DWT_Delay_us(10);  // Задержка t6. По Дш = 50/fCLK. У меня fCLK = 8 МГц, откуда t6 = 6,25 мкс. Беру с запасом - 10 мкс.
      HAL_SPI_Receive(&hspi3, spiRxBuf, 3, 50); // Receive result of conversion via SPI
      CS_OFF(); // Disable CS

      result = spiRxBuf[0];
      result = result << 8;
      result |= spiRxBuf[1];
      result = result << 8;
      result |= spiRxBuf[2];

      LCD_PrintInt(result);
  }
  /* USER CODE END 3 */

}

 

Единственное чего не делаю, это задержек после отправки и получения SPI. Как мне казалось внутри этих функций есть проверка флагов окончания передачи, попробую добавить задержки после них.

Изменено пользователем remixx

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. Насколько я понимаю рабочая частота АЦП определяется кварцем? В таком случае она равна 8 МГц. Частоту SPI беру с очень большим запасом (1.125 МГц, картинка ниже).

Кварцем определяется работа микроконтроллера. Частота АЦП - совсем другая, см. даташит.

Единственое чего не делаю, это задержек после отправки и получения SPI. Как мне казалось внутри этих функций есть проверка флагов окончания передачи, попробую добавить задержки после них.

Если у вас нет осциллографа, либо логического анализатора, то отладить обмен на шине конечно можно методом проб и ошибок, но лучше найдите один из этих приборов. Иначе можно долго отлаживать.

 

 

Кстати, думаю, что публиковать длиннющие куски кода смысла нет, т.к. реализация либы spi чуть ли не индивидуальная у каждого микроконтроллера, и версии. Поэтому лучше приведите диаграммы с шины. Но для этого нужен осциллограф, либо анализатор.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть отдельный кварц на АЦП.

Все заработало! Похоже проблема была именно в режиме SPI (0, 2Edge).

Всем спасибо.

Изменено пользователем remixx

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть отдельный кварц на АЦП.

В следующий раз приводите вместе с кодом и полную схему подключения, т.к. на вашей УГО АЦП неполное.

Все заработало! Похоже проблема была именно в режиме SPI (0, 2Edge).

Странно. Либо вы редко занимались отладкой, либо проблема была не только в этом, т.к. времени прошло несколько дней с того времени, как вам посоветовали проверить режим. Ну, а слово "похоже" говорит, что логического анализатора у вас нет. Заведите. На алиэксресс купите самый недорогой. Он вам сэкономит кучу времени при отладке интерфейсов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...