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

 
 
> Не получается передать по spi1 на плате Nucleo_L053R8, Проблем с передачей и приемом байта на модуле SPI1
kray
сообщение Nov 30 2015, 09:05
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 14-08-12
Пользователь №: 73 115



Здравствуйте,
в процессе обучения программированию SPI на плате Nucleo-L053R8
возникли проблемы с передачей байта.

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

Для этого нужно кинуть перемычку между MISO и MOSI в SPI1 (в моей плате соединяются PA6, PA7).

Перемычку кинул, инициализацию провел в Cube.
Передаю и принимаю байт с помощью:

CODE

HAL_SPI_Transmit(&hspi1, transmitBuffer, 1, 20);
HAL_SPI_Receive_IT(&hspi1, receiveBuffer, 1);


соответственно.

Однако когда программа доходит до while(1)
в переменной receiveBuffer - пусто. А должен быть символ "v".

В чем может быть проблема ?







CODE


*/
/* Includes ------------------------------------------------------------------*/
#include "stm32l0xx_hal.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
uint8_t transmitBuffer[1] = "v";
uint8_t receiveBuffer[1];
/* USER CODE END PV */

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

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

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

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();

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

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

/* USER CODE BEGIN 2 */

HAL_SPI_Transmit(&hspi1, transmitBuffer, 1, 20);
HAL_SPI_Receive_IT(&hspi1, receiveBuffer, 1);
/* USER CODE END 2 */

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

/* USER CODE BEGIN 3 */

}
/* USER CODE END 3 */

}

/** System Clock Configuration
*/
void SystemClock_Config(void)
{

RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;

__PWR_CLK_ENABLE();

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);

HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

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

/* SPI1 init function */
void MX_SPI1_Init(void)
{

hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLED;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
hspi1.Init.CRCPolynomial = 7;
HAL_SPI_Init(&hspi1);

}

/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
void MX_GPIO_Init(void)
{

GPIO_InitTypeDef GPIO_InitStruct;

/* GPIO Ports Clock Enable */
__GPIOC_CLK_ENABLE();
__GPIOH_CLK_ENABLE();
__GPIOA_CLK_ENABLE();
__GPIOB_CLK_ENABLE();

/*Configure GPIO pin : B1_Pin */
GPIO_InitStruct.Pin = B1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);

/*Configure GPIO pins : USART_TX_Pin USART_RX_Pin */
GPIO_InitStruct.Pin = USART_TX_Pin|USART_RX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/*Configure GPIO pin : LD2_Pin */
GPIO_InitStruct.Pin = LD2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

#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,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */

}

#endif
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 7)
Jury093
сообщение Nov 30 2015, 09:41
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 959
Регистрация: 11-01-06
Из: Санкт-Петербург
Пользователь №: 13 050



Цитата(kray @ Nov 30 2015, 12:05) *
Для этого нужно кинуть перемычку между MISO и MOSI в SPI1 (в моей плате соединяются PA6, PA7).
В чем может быть проблема ?

потыкайте осциллом в "кинутую перемычку" - бегают ли там сигналы SPI..
ну и проверьте, что у вас инициализированны пины "PA6, PA7", видимо по подобию:
Код
GPIO_InitStruct.Pin = USART_TX_Pin|USART_RX_Pin;
Go to the top of the page
 
+Quote Post
kray
сообщение Nov 30 2015, 11:07
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 14-08-12
Пользователь №: 73 115



Цитата(Jury093 @ Nov 30 2015, 12:41) *
потыкайте осциллом в "кинутую перемычку" - бегают ли там сигналы SPI..
ну и проверьте, что у вас инициализированны пины "PA6, PA7", видимо по подобию:
Код
GPIO_InitStruct.Pin = USART_TX_Pin|USART_RX_Pin;


Определенные импульсы там есть, когда компилятор проходит через строку (в режиме отладки)

Код
HAL_SPI_Transmit(&hspi1, transmitBuffer, 1, 20);


PA6, PA7 инициализированы в файле stm32l0xx_hal_msp.c

CODE

/* Includes ------------------------------------------------------------------*/
#include "stm32l0xx_hal.h"

/* 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 */

__SYSCFG_CLK_ENABLE();

/* System interrupt init*/
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

/* USER CODE BEGIN MspInit 1 */

/* USER CODE END MspInit 1 */
}

void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{

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

/* USER CODE END SPI1_MspInit 0 */
/* Peripheral clock enable */
__SPI1_CLK_ENABLE();

/**SPI1 GPIO Configuration
PA4 ------> SPI1_NSS
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
PB3 ------> SPI1_SCK
*/
GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* Peripheral interrupt init*/
HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI1_IRQn);
/* USER CODE BEGIN SPI1_MspInit 1 */

/* USER CODE END SPI1_MspInit 1 */
}

}

void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
{

if(hspi->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspDeInit 0 */

/* USER CODE END SPI1_MspDeInit 0 */
/* Peripheral clock disable */
__SPI1_CLK_DISABLE();

/**SPI1 GPIO Configuration
PA4 ------> SPI1_NSS
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
PB3 ------> SPI1_SCK
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_7);

HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3);

/* Peripheral interrupt DeInit*/
HAL_NVIC_DisableIRQ(SPI1_IRQn);

}
/* USER CODE BEGIN SPI1_MspDeInit 1 */

/* USER CODE END SPI1_MspDeInit 1 */

}



Сообщение отредактировал IgorKossak - Dec 1 2015, 08:25
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
kray
сообщение Nov 30 2015, 12:45
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 14-08-12
Пользователь №: 73 115



Выяснилось ,что при соединенных перемычках после строки

HAL_SPI_Transmit(&hspi1, transmitBuffer, 1, 20);

значение transmitBuffer передается в регистр
DR, а после выполнения

HAL_SPI_Receive_IT(&hspi1, receiveBuffer, 1);

регистр DR обнуляется.

Если же перемычку между РА6 и РА7 (MISO и MOSI) убрать,
то в этом случае в DR уже ничего не передается и он остается пустым.

Т.е. прием данных происходит, но почему-то данные из регистра DR
не заносятся потом в переменную receiveBuffer.
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Nov 30 2015, 19:20
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



"Прикол" SPI заключается в том, что (если интерфейс запрограммирован на полный дуплекс) прием происходит ВСЕГДА, независимо от того, есть ли перемычка, или нет. Причина в том, что SPI - не асинхронный UART, где тактирование запускается сигналом данных (стартовым битом на входе RX). В SPI тактирование синхронное: сигнал SCLK. И регистр DR не может быть пустым после 8 тактов SPI. Другое дело, какие именно данные втянутся в регистр SPI после выдачи 8 тактов. Если вход MISO не подключен в выходу MOSI, то втянутся либо все нули, либо все единицы в зависимости от того, имеет вход pull down или pull up.

Найдите место в программе (в приеме), где происходит ожидание установки бита RXNE. Если бит установился, все нормально, прием состоялся, SPI работает. Но помните, что при работе под отладчиком может происходить "разрушение" битов и данных регистров. В идеале так быть не должно, поскольку отладочные интерфейсы обязаны быть non intrusive, но реальность железа такова, что это требование может не соблюдаться. Ставьте точки останова не внутри циклов ожидания тех или иных битов, а после. В случае RXNE и DR - только после чтения из DR.
Go to the top of the page
 
+Quote Post
kray
сообщение Dec 1 2015, 08:54
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 14-08-12
Пользователь №: 73 115



Цитата(KnightIgor @ Nov 30 2015, 22:20) *
"Прикол" SPI заключается в том, что (если интерфейс запрограммирован на полный дуплекс) прием происходит ВСЕГДА, независимо от того, есть ли перемычка, или нет. Причина в том, что SPI - не асинхронный UART, где тактирование запускается сигналом данных (стартовым битом на входе RX). В SPI тактирование синхронное: сигнал SCLK. И регистр DR не может быть пустым после 8 тактов SPI. Другое дело, какие именно данные втянутся в регистр SPI после выдачи 8 тактов. Если вход MISO не подключен в выходу MOSI, то втянутся либо все нули, либо все единицы в зависимости от того, имеет вход pull down или pull up.

Найдите место в программе (в приеме), где происходит ожидание установки бита RXNE. Если бит установился, все нормально, прием состоялся, SPI работает. Но помните, что при работе под отладчиком может происходить "разрушение" битов и данных регистров. В идеале так быть не должно, поскольку отладочные интерфейсы обязаны быть non intrusive, но реальность железа такова, что это требование может не соблюдаться. Ставьте точки останова не внутри циклов ожидания тех или иных битов, а после. В случае RXNE и DR - только после чтения из DR.


KnightIgor,

1) Спасибо, теперь понятно, что данные были с TX буфера переданы в DR регистр. А дальше из DR передаются в RX буфер.
2) Раз со спаенным проводом и без него DR ведет себя по разному, значит скорее всего контакт есть, т.е.
дело, будем так говорить, не в электрике, а в самой программе, скорее всего.
3) Прошерстил программу, ни в какой из точек не было установлен флаг RXNE.
4) В точке while(1) устанавливаются флаг TXE. Данные передаются в сдвиговый регистр из TX буфера.
5) В функции HAL_SPI_TransmitReceive_IT

CODE
HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
{

if((hspi->State == HAL_SPI_STATE_READY) || \
((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->State == HAL_SPI_STATE_BUSY_RX)))
{
if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0))
{
return HAL_ERROR;
}

/* Check the parameters */
assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));

/* Process locked */
__HAL_LOCK(hspi);

/* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
if(hspi->State != HAL_SPI_STATE_BUSY_RX)
{
hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
}

/* Configure communication */
hspi->ErrorCode = HAL_SPI_ERROR_NONE;

hspi->TxISR = &SPI_TxISR;
hspi->pTxBuffPtr = pTxData;
hspi->TxXferSize = Size;
hspi->TxXferCount = Size;

hspi->RxISR = &SPI_2LinesRxISR;
hspi->pRxBuffPtr = pRxData;
hspi->RxXferSize = Size;
hspi->RxXferCount = Size;

/* Reset CRC Calculation */
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
SPI_RESET_CRC(hspi);
}

/* Enable TXE, RXNE and ERR interrupt */
__HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));

/* Process Unlocked */
__HAL_UNLOCK(hspi);

/* Check if the SPI is already enabled */
if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
{
/* Enable SPI peripheral */
__HAL_SPI_ENABLE(hspi);
}

return HAL_OK;
}
else
{
return HAL_BUSY;
}
}


В строке __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
устанавливаются флаги TXEIE, RXNEIE
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Dec 1 2015, 12:24
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



До сих пор я не использовал HAL, все более SPL. Однако мне кажется, Вы не все проинициализировали или привели код не полностью. Как я понимаю, функция HAL_SPI_Receive_IT() возвращает в буфер приема данные, полученные ПО ПРЕРЫВАНИЮ. Прием (и передача) по прерыванию готовится функцией HAL_SPI_TransmitReceive_IT(), которая прописывает структуры, где буферы лежат, сколько принять надо, и взводит флаги. Но где же сам вектор прерывания от SPI, и где инициализация NVIC для вектора SPI? Похоже, проблема в том, что у Вас этого ничего нет, прерывания не срабатывают, обработчика принимаемого потока нет, неоткуда заполнить буфер приема, и функция приема ждет до бесконечности.

Предполагаю, что есть HAL_SPI_Receive(), без _IT. Попробуйте чисто синхронную (без прерываний) приемо-передачу. SPI - самый простой и детерминированный интерфейс, должно сразу все завестись.
Go to the top of the page
 
+Quote Post
kray
сообщение Dec 2 2015, 08:23
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 14-08-12
Пользователь №: 73 115



Цитата(KnightIgor @ Dec 1 2015, 15:24) *
До сих пор я не использовал HAL, все более SPL. Однако мне кажется, Вы не все проинициализировали или привели код не полностью. Как я понимаю, функция HAL_SPI_Receive_IT() возвращает в буфер приема данные, полученные ПО ПРЕРЫВАНИЮ. Прием (и передача) по прерыванию готовится функцией HAL_SPI_TransmitReceive_IT(), которая прописывает структуры, где буферы лежат, сколько принять надо, и взводит флаги. Но где же сам вектор прерывания от SPI, и где инициализация NVIC для вектора SPI? Похоже, проблема в том, что у Вас этого ничего нет, прерывания не срабатывают, обработчика принимаемого потока нет, неоткуда заполнить буфер приема, и функция приема ждет до бесконечности.

Предполагаю, что есть HAL_SPI_Receive(), без _IT. Попробуйте чисто синхронную (без прерываний) приемо-передачу. SPI - самый простой и детерминированный интерфейс, должно сразу все завестись.


KnightIgor,
с обработчиками все нормально, Cube его сам прописывает, нужно только галочку поставить,
чтобы включить обработчик.

Код обработчика:
CODE
/**
* @brief This function handles SPI1 global interrupt.
*/
void SPI1_IRQHandler(void)
{
/* USER CODE BEGIN SPI1_IRQn 0 */

/* USER CODE END SPI1_IRQn 0 */
HAL_SPI_IRQHandler(&hspi1);
/* USER CODE BEGIN SPI1_IRQn 1 */

/* USER CODE END SPI1_IRQn 1 */
}


Код функции HAL_SPI_IRQHandler:

CODE
/**
* @brief This function handles SPI interrupt request.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval HAL status
*/
void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
{
/* SPI in mode Receiver and Overrun not occurred ---------------------------*/
if((__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_RXNE) != RESET) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE) != RESET) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_OVR) == RESET))
{
hspi->RxISR(hspi);
return;
}

/* SPI in mode Tramitter ---------------------------------------------------*/
if((__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_TXE) != RESET) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE) != RESET))
{
hspi->TxISR(hspi);
return;
}

if(__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_ERR) != RESET)
{
/* SPI CRC error interrupt occurred ---------------------------------------*/
if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
__HAL_SPI_CLEAR_CRCERRFLAG(hspi);
}
/* SPI Mode Fault error interrupt occurred --------------------------------*/
if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_MODF) != RESET)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF);
__HAL_SPI_CLEAR_MODFFLAG(hspi);
}

/* SPI Overrun error interrupt occurred -----------------------------------*/
if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_OVR) != RESET)
{
if(hspi->State != HAL_SPI_STATE_BUSY_TX)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
__HAL_SPI_CLEAR_OVRFLAG(hspi);
}
}

/* SPI Frame error interrupt occurred -------------------------------------*/
if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_FRE) != RESET)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE);
__HAL_SPI_CLEAR_FREFLAG(hspi);
}

/* Call the Error call Back in case of Errors */
if(hspi->ErrorCode!=HAL_SPI_ERROR_NONE)
{
__HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR);
hspi->State = HAL_SPI_STATE_READY;
HAL_SPI_ErrorCallback(hspi);
}
}
}




Без обработчика тоже пробовал, все также TXE срабатывает на while(1);, а RXNE не хочет срабатывать,
естественно и в переменной receiveBuffer - пусто.
Код программы:

CODE

*/
/* Includes ------------------------------------------------------------------*/
#include "stm32l0xx_hal.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

/* USER CODE END PV */

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

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
uint8_t transmitBuffer[1] = "p";
uint8_t receiveBuffer[1];
/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

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();

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

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

/* USER CODE BEGIN 2 */
HAL_SPI_Transmit(&hspi1, transmitBuffer, 1, 20);
HAL_SPI_Receive(&hspi1, receiveBuffer, 1,20);
/* USER CODE END 2 */

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

/* USER CODE BEGIN 3 */

}
/* USER CODE END 3 */

}

/** System Clock Configuration
*/
void SystemClock_Config(void)
{

RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;

__PWR_CLK_ENABLE();

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);

HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

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

/* SPI1 init function */
void MX_SPI1_Init(void)
{

hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLED;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
hspi1.Init.CRCPolynomial = 7;
HAL_SPI_Init(&hspi1);

}

/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
void MX_GPIO_Init(void)
{

GPIO_InitTypeDef GPIO_InitStruct;

/* GPIO Ports Clock Enable */
__GPIOC_CLK_ENABLE();
__GPIOH_CLK_ENABLE();
__GPIOA_CLK_ENABLE();
__GPIOB_CLK_ENABLE();

/*Configure GPIO pin : B1_Pin */
GPIO_InitStruct.Pin = B1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);

/*Configure GPIO pins : USART_TX_Pin USART_RX_Pin */
GPIO_InitStruct.Pin = USART_TX_Pin|USART_RX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/*Configure GPIO pin : LD2_Pin */
GPIO_InitStruct.Pin = LD2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

#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,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */

}

#endif

Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 07:31
Рейтинг@Mail.ru


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