реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> STM32F107RCT6 + ADS1256
remixx
сообщение Apr 11 2018, 04:14
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 19-10-16
Пользователь №: 93 818



Пытаюсь подключить 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 бита один за другим), результат такой же.

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

Прикрепленное изображение


Прикрепленное изображение


Сообщение отредактировал remixx - Apr 11 2018, 04:16
Go to the top of the page
 
+Quote Post
inventor
сообщение Apr 12 2018, 10:31
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748



SPI вы правильно настроили?
1) для начала соединить MISO с MOSI что приходит ну и саму настройку SPI - правильно ноги затактированы
2) Проверьте фазу SPI - там 4 возможных режима
3) Проверьте чтобы CS начинался до транзакций и заканчивался после них через небольшую задержку

Сообщение отредактировал Сергей Борщ - Apr 12 2018, 11:31
Причина редактирования: Бездумное цитирование!
Go to the top of the page
 
+Quote Post
remixx
сообщение Apr 13 2018, 02:46
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 19-10-16
Пользователь №: 93 818



Цитата(inventor @ Apr 12 2018, 10:31) *
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****/


Проблема походу не в коде. На схеме отсутствует кварц, а в дш он есть. Детали уже приобрел, во вторник протестирую вместе с ним.
Go to the top of the page
 
+Quote Post
inventor
сообщение Apr 13 2018, 11:51
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748



Цитата(remixx @ Apr 13 2018, 05:46) *
Проблема походу не в коде. На схеме отсутствует кварц, а в дш он есть. Детали уже приобрел, во вторник протестирую вместе с ним.


можно с ноги контроллера протактировать
Go to the top of the page
 
+Quote Post
remixx
сообщение May 7 2018, 08:43
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 19-10-16
Пользователь №: 93 818



Вернулся к работе, но после всех корректировок так ничего и не изменилось)
Может быть я неправильно настраиваю CPOL и CPHA?
Приложил картинку передачи сигналов из ДШ.
По-моему в настройках SPI нужно устанавливать CPOL - 0, CPHA - 1Edge.
Еще кстати заметил, что в настройках выводов SCK и MOSI заданы как AF, а MISO как Input. А разве MISO не должен тоже задаваться как AF?
Прикрепленное изображение
Go to the top of the page
 
+Quote Post
haker_fox
сообщение May 7 2018, 09:16
Сообщение #6


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (remixx @ May 7 2018, 16:43) *
Может быть я неправильно настраиваю CPOL и CPHA?
Приложил картинку передачи сигналов из ДШ.

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

А также (я работал с ADS1247, ADS131E04):
1. Проверьте, что тактовая частота SPI укладывается в допустимые.
2. Проверьте, что сигнал CS удерживается в низком уровне на время передачи кода команды и её аргументов (некоторые МК дёргают CS после передачи каждого байта, так работать не будет).
3. Считайте значения регистров по-умолчанию из АЦП, по ним можно сразу проверить, работает ли шина или нет. Я таким образом детектирую наличие АЦП на шине, и его косвенную исправность.
4. Проверьте, что CS опускается в ноль чуть раньше передачи данных по шине, и поднимается в 1 - чуть позже. Эти времена уточнить по даташиту. Я просто сделал 1 мс с большим запасом.
5. Ну и банально: проверьте уровни всхем питаний, доходят ли сигналы шины до АЦП и т.п.


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
Stanislav_S
сообщение May 7 2018, 10:19
Сообщение #7


извечный пессимист
*****

Группа: Свой
Сообщений: 1 113
Регистрация: 9-10-06
Из: Днепропетровск
Пользователь №: 21 125



В общем случае надо смотреть такие вещи:
- правильно настроить SPI - режим 1
- очень внимательно прочитать ДШ на АЦП на предмет команд, работы SPI и особенно важно не упустить задержки, коих там много и без их соблюдения нормальной работы не будет!
- выбросить HAL и написать нормально - это самый лучший путь, АЦП достаточно сложный в плане работы (для новичка конечно).
А так могу сказать, что АЦП работает - у меня в текущем проекте их 3 штуки на плате и все прекрасно работает.


--------------------
Slaves are those of this world
Given freedom to lay chains upon The Master
The wolf is no longer free
Release the chains and come for me
Go to the top of the page
 
+Quote Post
remixx
сообщение May 8 2018, 04:14
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 19-10-16
Пользователь №: 93 818



Цитата(haker_fox @ May 7 2018, 09:16) *
Фазировку шины проверьте осциллографом, и сравните картинку с даташитом.

А также (я работал с ADS1247, ADS131E04):
1. Проверьте, что тактовая частота SPI укладывается в допустимые.
2. Проверьте, что сигнал CS удерживается в низком уровне на время передачи кода команды и её аргументов (некоторые МК дёргают CS после передачи каждого байта, так работать не будет).
3. Считайте значения регистров по-умолчанию из АЦП, по ним можно сразу проверить, работает ли шина или нет. Я таким образом детектирую наличие АЦП на шине, и его косвенную исправность.
4. Проверьте, что CS опускается в ноль чуть раньше передачи данных по шине, и поднимается в 1 - чуть позже. Эти времена уточнить по даташиту. Я просто сделал 1 мс с большим запасом.
5. Ну и банально: проверьте уровни всхем питаний, доходят ли сигналы шины до АЦП и т.п.


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

Цитата(Stanislav_S @ May 7 2018, 10:19) *
В общем случае надо смотреть такие вещи:
- правильно настроить SPI - режим 1
- очень внимательно прочитать ДШ на АЦП на предмет команд, работы SPI и особенно важно не упустить задержки, коих там много и без их соблюдения нормальной работы не будет!
- выбросить HAL и написать нормально - это самый лучший путь, АЦП достаточно сложный в плане работы (для новичка конечно).
А так могу сказать, что АЦП работает - у меня в текущем проекте их 3 штуки на плате и все прекрасно работает.


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

Прикрепленное изображение


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 - May 8 2018, 04:20
Go to the top of the page
 
+Quote Post
haker_fox
сообщение May 8 2018, 06:13
Сообщение #9


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



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

Кварцем определяется работа микроконтроллера. Частота АЦП - совсем другая, см. даташит.
QUOTE (remixx @ May 8 2018, 12:14) *
Единственое чего не делаю, это задержек после отправки и получения SPI. Как мне казалось внутри этих функций есть проверка флагов окончания передачи, попробую добавить задержки после них.

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


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


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
remixx
сообщение May 10 2018, 07:15
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 19-10-16
Пользователь №: 93 818



Есть отдельный кварц на АЦП.
Все заработало! Похоже проблема была именно в режиме SPI (0, 2Edge).
Всем спасибо.

Сообщение отредактировал remixx - May 10 2018, 07:16
Go to the top of the page
 
+Quote Post
haker_fox
сообщение May 10 2018, 08:45
Сообщение #11


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (remixx @ May 10 2018, 15:15) *
Есть отдельный кварц на АЦП.

В следующий раз приводите вместе с кодом и полную схему подключения, т.к. на вашей УГО АЦП неполное.
QUOTE (remixx @ May 10 2018, 15:15) *
Все заработало! Похоже проблема была именно в режиме SPI (0, 2Edge).

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


--------------------
Выбор.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th April 2024 - 02:47
Рейтинг@Mail.ru


Страница сгенерированна за 0.0153 секунд с 7
ELECTRONIX ©2004-2016