remixx 0 11 апреля, 2018 Опубликовано 11 апреля, 2018 (изменено) · Жалоба Пытаюсь подключить 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 бита один за другим), результат такой же. Не понимаю в чем проблема, не правильная инициализация или схема? Изменено 11 апреля, 2018 пользователем remixx Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
inventor 0 12 апреля, 2018 Опубликовано 12 апреля, 2018 (изменено) · Жалоба SPI вы правильно настроили? 1) для начала соединить MISO с MOSI что приходит ну и саму настройку SPI - правильно ноги затактированы 2) Проверьте фазу SPI - там 4 возможных режима 3) Проверьте чтобы CS начинался до транзакций и заканчивался после них через небольшую задержку Изменено 12 апреля, 2018 пользователем Сергей Борщ Бездумное цитирование! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
remixx 0 13 апреля, 2018 Опубликовано 13 апреля, 2018 · Жалоба 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****/ Проблема походу не в коде. На схеме отсутствует кварц, а в дш он есть. Детали уже приобрел, во вторник протестирую вместе с ним. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
inventor 0 13 апреля, 2018 Опубликовано 13 апреля, 2018 · Жалоба Проблема походу не в коде. На схеме отсутствует кварц, а в дш он есть. Детали уже приобрел, во вторник протестирую вместе с ним. можно с ноги контроллера протактировать Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
remixx 0 7 мая, 2018 Опубликовано 7 мая, 2018 · Жалоба Вернулся к работе, но после всех корректировок так ничего и не изменилось) Может быть я неправильно настраиваю CPOL и CPHA? Приложил картинку передачи сигналов из ДШ. По-моему в настройках SPI нужно устанавливать CPOL - 0, CPHA - 1Edge. Еще кстати заметил, что в настройках выводов SCK и MOSI заданы как AF, а MISO как Input. А разве MISO не должен тоже задаваться как AF? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 7 мая, 2018 Опубликовано 7 мая, 2018 · Жалоба Может быть я неправильно настраиваю CPOL и CPHA? Приложил картинку передачи сигналов из ДШ. Фазировку шины проверьте осциллографом, и сравните картинку с даташитом. А также (я работал с ADS1247, ADS131E04): 1. Проверьте, что тактовая частота SPI укладывается в допустимые. 2. Проверьте, что сигнал CS удерживается в низком уровне на время передачи кода команды и её аргументов (некоторые МК дёргают CS после передачи каждого байта, так работать не будет). 3. Считайте значения регистров по-умолчанию из АЦП, по ним можно сразу проверить, работает ли шина или нет. Я таким образом детектирую наличие АЦП на шине, и его косвенную исправность. 4. Проверьте, что CS опускается в ноль чуть раньше передачи данных по шине, и поднимается в 1 - чуть позже. Эти времена уточнить по даташиту. Я просто сделал 1 мс с большим запасом. 5. Ну и банально: проверьте уровни всхем питаний, доходят ли сигналы шины до АЦП и т.п. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Stanislav_S 0 7 мая, 2018 Опубликовано 7 мая, 2018 · Жалоба В общем случае надо смотреть такие вещи: - правильно настроить SPI - режим 1 - очень внимательно прочитать ДШ на АЦП на предмет команд, работы SPI и особенно важно не упустить задержки, коих там много и без их соблюдения нормальной работы не будет! - выбросить HAL и написать нормально - это самый лучший путь, АЦП достаточно сложный в плане работы (для новичка конечно). А так могу сказать, что АЦП работает - у меня в текущем проекте их 3 штуки на плате и все прекрасно работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
remixx 0 8 мая, 2018 Опубликовано 8 мая, 2018 (изменено) · Жалоба Фазировку шины проверьте осциллографом, и сравните картинку с даташитом. А также (я работал с 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 поста. Нужно ли кроме этого что-то настраивать еще? 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. Как мне казалось внутри этих функций есть проверка флагов окончания передачи, попробую добавить задержки после них. Изменено 8 мая, 2018 пользователем remixx Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 8 мая, 2018 Опубликовано 8 мая, 2018 · Жалоба 1. Насколько я понимаю рабочая частота АЦП определяется кварцем? В таком случае она равна 8 МГц. Частоту SPI беру с очень большим запасом (1.125 МГц, картинка ниже). Кварцем определяется работа микроконтроллера. Частота АЦП - совсем другая, см. даташит. Единственое чего не делаю, это задержек после отправки и получения SPI. Как мне казалось внутри этих функций есть проверка флагов окончания передачи, попробую добавить задержки после них. Если у вас нет осциллографа, либо логического анализатора, то отладить обмен на шине конечно можно методом проб и ошибок, но лучше найдите один из этих приборов. Иначе можно долго отлаживать. Кстати, думаю, что публиковать длиннющие куски кода смысла нет, т.к. реализация либы spi чуть ли не индивидуальная у каждого микроконтроллера, и версии. Поэтому лучше приведите диаграммы с шины. Но для этого нужен осциллограф, либо анализатор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
remixx 0 10 мая, 2018 Опубликовано 10 мая, 2018 (изменено) · Жалоба Есть отдельный кварц на АЦП. Все заработало! Похоже проблема была именно в режиме SPI (0, 2Edge). Всем спасибо. Изменено 10 мая, 2018 пользователем remixx Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 10 мая, 2018 Опубликовано 10 мая, 2018 · Жалоба Есть отдельный кварц на АЦП. В следующий раз приводите вместе с кодом и полную схему подключения, т.к. на вашей УГО АЦП неполное. Все заработало! Похоже проблема была именно в режиме SPI (0, 2Edge). Странно. Либо вы редко занимались отладкой, либо проблема была не только в этом, т.к. времени прошло несколько дней с того времени, как вам посоветовали проверить режим. Ну, а слово "похоже" говорит, что логического анализатора у вас нет. Заведите. На алиэксресс купите самый недорогой. Он вам сэкономит кучу времени при отладке интерфейсов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться