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

 
 
> 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
 
Start new topic
Ответов
remixx
сообщение May 10 2018, 07:15
Сообщение #2


Участник
*

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



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

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



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

 


RSS Текстовая версия Сейчас: 23rd June 2025 - 21:09
Рейтинг@Mail.ru


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