Общая задача - реализовать RS485 на данной отладочной плате. В ходе выполнения столкнулись с такой проблемой, как зависание в HAL_Delay(500).
Алгоритм действий для получения зависания:
0. Имеется две платы, код у каждой свой, писали 2 человека, оба кода приведены далее;
1. На первой плате поочерёдно нажимаются кнопки S1, S2, S3;
2. На второй плате поочерёдно нажимаются те же кнопки;
3. На первой плате нажимается кнопка S1, после чего плата зависает и без reset дальше не работает.
Искали решение данной проблемы, в том числе на данном форуме, но ничего не помогло.
Просим подсказать, как решить данную проблему.
Код 1 платы:
Спойлер
Код: Выделить всё
#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_rcc.h"
#include "stm32f4xx_hal_gpio.h"
#include "stm32f4xx_hal_uart.h"
#include "string.h"
#include "stdint.h"
#include "stdio.h"
#include "stdbool.h"
#include "stm32f4xx_hal_conf.h"
#include "stm32f4xx.h"
#include "stm32f4xx_hal_usart.h"
#define RS485_DE_PIN GPIO_PIN_7
#define RS485_DE_GPIO_PORT GPIOD
#define RS45_DE_GPIO_CLK GPIOD_CLK_ENABLE
#define NUM_TICK_DELAY 500000
UART_HandleTypeDef huart;
uint8_t bufferR = 0xFF;
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
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_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}
void MX_GPIO_Init()
{
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
GPIO_InitTypeDef GPIO_Port5;
GPIO_Port5.Pin = GPIO_PIN_5 ;
GPIO_Port5.Mode = GPIO_MODE_AF_PP;
GPIO_Port5.Pull = GPIO_NOPULL;
GPIO_Port5.Alternate = GPIO_AF7_USART2;
GPIO_Port5.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOD, &GPIO_Port5);
GPIO_InitTypeDef GPIO_Port6;
GPIO_Port6.Pin = GPIO_PIN_6;
GPIO_Port6.Mode = GPIO_MODE_AF_PP;
GPIO_Port6.Pull = GPIO_NOPULL;
GPIO_Port6.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOD, &GPIO_Port6);
GPIO_InitTypeDef RSDE;
RSDE.Pin = RS485_DE_PIN;
RSDE.Mode= GPIO_MODE_OUTPUT_PP;
RSDE.Speed = GPIO_SPEED_FREQ_LOW;
RSDE.Pull = GPIO_NOPULL;
HAL_GPIO_Init(RS485_DE_GPIO_PORT, &RSDE);
GPIO_InitTypeDef Button1;
Button1.Pin = GPIO_PIN_10;
Button1.Mode= GPIO_MODE_INPUT;
Button1.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOE, &Button1);
GPIO_InitTypeDef Button2;
Button2.Pin = GPIO_PIN_11;
Button2.Mode= GPIO_MODE_INPUT;
Button2.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOE, &Button2);
GPIO_InitTypeDef Button3;
Button3.Pin = GPIO_PIN_12;
Button3.Mode= GPIO_MODE_INPUT;
Button3.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOE, &Button3);
GPIO_InitTypeDef LED;
LED.Pin = GPIO_PIN_13;
LED.Mode = GPIO_MODE_OUTPUT_PP;
LED.Pull = GPIO_NOPULL;
LED.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOE, &LED);
LED.Pin = GPIO_PIN_14;
LED.Mode = GPIO_MODE_OUTPUT_PP;
LED.Pull = GPIO_NOPULL;
LED.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOE, &LED);
LED.Pin = GPIO_PIN_15;
LED.Mode = GPIO_MODE_OUTPUT_PP;
LED.Pull = GPIO_NOPULL;
LED.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOE, &LED);
}
void USART2_IRQHandler()
{
HAL_UART_IRQHandler(&huart);
}
void RS485_Init()
{
__enable_irq();
huart.Instance = USART2;
huart.Init.BaudRate = 115200;
huart.Init.WordLength = UART_WORDLENGTH_9B;
huart.Init.StopBits = UART_STOPBITS_1;
huart.Init.Parity = UART_PARITY_EVEN;
huart.Init.Mode = UART_MODE_TX_RX;
huart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart);
NVIC_EnableIRQ(USART2_IRQn);
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
}
void RS485TX(UART_HandleTypeDef *huart, uint8_t* message, uint8_t messageSize)
{
HAL_StatusTypeDef status;
HAL_GPIO_WritePin(RS485_DE_GPIO_PORT, RS485_DE_PIN, GPIO_PIN_SET);
HAL_UART_Transmit(huart, message, messageSize,HAL_MAX_DELAY);
HAL_GPIO_WritePin(RS485_DE_GPIO_PORT, RS485_DE_PIN, GPIO_PIN_RESET);
}
int main()
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15, GPIO_PIN_SET);
RS485_Init();
uint8_t message1 = 0x00U;
uint8_t message2 = 0x01U;
uint8_t message3 = 0x02U;
uint8_t messageSENT1 = 0;
uint8_t messageSENT2 = 0;
uint8_t messageSENT3 = 0;
while(1)
{
if ((HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_10) == GPIO_PIN_RESET) && !messageSENT1){
RS485TX(&huart, (uint8_t*)&message1, sizeof(uint8_t));
messageSENT1 = 1;
HAL_Delay(500);
for(uint32_t i = 0; i<NUM_TICK_DELAY; i++);
}
if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_10) == GPIO_PIN_SET){
messageSENT1 = 0;
}
if ((HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_11) == GPIO_PIN_RESET) && !messageSENT2){
RS485TX(&huart, (uint8_t*)&message2, sizeof(uint8_t));
messageSENT2 = 1;}
if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_11) == GPIO_PIN_SET){
messageSENT2 = 0;}
if ((HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_12) == GPIO_PIN_RESET) && !messageSENT3){
RS485TX(&huart, (uint8_t*)&message3, sizeof(uint8_t));
messageSENT3 = 1;
}
if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_12) == GPIO_PIN_SET){
messageSENT3 = 0;
}
HAL_UART_Receive_IT(&huart, &bufferR, 1);
switch(bufferR) {
case 0x00U:
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_13, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_14, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_15, GPIO_PIN_SET);
break;
case 0x01U:
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_14, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_13, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_15, GPIO_PIN_SET);
break;
case 0x02U:
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_15, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_13, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_14, GPIO_PIN_SET);
break;
default:
break;}
}
}
void SysTick_Handler(void)
{
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
}
Спойлер
Код: Выделить всё
#include "stm32f4xx_hal.h" // Keil::Device:STM32Cube HAL:Common
#include "stm32f4xx_hal_rcc.h"
#include "stm32f4xx_hal_gpio.h"
#include "stm32f4xx_hal_uart.h"
#include "string.h"
#include "stdint.h"
#include "stdio.h"
#include "stdbool.h"
#include "stm32f4xx_hal_conf.h" // Keil::Device:STM32Cube Framework:Classic
#include "stm32f4xx.h" // Device header
#include "stm32f4xx_hal_usart.h"
#define RS485_DE_PIN GPIO_PIN_7
#define RS485_DE_GPIO_PORT GPIOD
#define RS45_DE_GPIO_CLK GPIOD_CLK_ENABLE
#define NUM_TICK_DELAY 250000
void rsTx (UART_HandleTypeDef *huart2, uint8_t* rsData, uint8_t messageSize);
void SystemClock_Config(void);
UART_HandleTypeDef huart2;
bool receiveON = false;
uint8_t rxData = 0xFFU;
void rsTx (UART_HandleTypeDef *huart2, uint8_t* rsData, uint8_t messageSize) //функция передачи
{
HAL_StatusTypeDef status;
HAL_GPIO_WritePin(RS485_DE_GPIO_PORT, RS485_DE_PIN, GPIO_PIN_SET);
HAL_UART_Transmit(huart2, rsData, messageSize,HAL_MAX_DELAY);
//for(uint32_t i = 0; i<(NUM_TICK_DELAY / 5); i++);
HAL_GPIO_WritePin(RS485_DE_GPIO_PORT, RS485_DE_PIN, GPIO_PIN_RESET);
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE(); //включение тактировнаия от внешнего кварца
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
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_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}
void USART2_IRQHandler()
{
HAL_UART_IRQHandler(&huart2);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart2) {
if (huart2->Instance == USART2) {
receiveON = true;
HAL_UART_Receive_IT(huart2, &rxData, 1);
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
__HAL_RCC_GPIOE_CLK_ENABLE(); //включение тактирования портов
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
GPIO_InitTypeDef RSTx_Pin; //описание Tx
RSTx_Pin.Pin = GPIO_PIN_5;
RSTx_Pin.Mode = GPIO_MODE_AF_PP;
RSTx_Pin.Speed = GPIO_SPEED_FREQ_HIGH;
RSTx_Pin.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOD,&RSTx_Pin); //инициализация Tx
GPIO_InitTypeDef RSRx_Pin;
RSRx_Pin.Pin = GPIO_PIN_6; //описание Rx
RSRx_Pin.Mode = GPIO_MODE_AF_PP;
RSRx_Pin.Pull = GPIO_NOPULL;
RSRx_Pin.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOD,&RSRx_Pin); //инициализация Rx
GPIO_InitTypeDef RSDe; //описание DE
RSDe.Pin = RS485_DE_PIN;
RSDe.Mode= GPIO_MODE_OUTPUT_PP;
RSDe.Speed = GPIO_SPEED_FREQ_LOW;
RSDe.Pull = GPIO_NOPULL;
HAL_GPIO_Init(RS485_DE_GPIO_PORT, &RSDe); //инициализация DE
__enable_irq();
huart2.Instance = USART2; //описание UART
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_9B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_EVEN;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart2); //инициализация UART
NVIC_EnableIRQ(USART2_IRQn);
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
GPIO_InitTypeDef BlinkLED; //описание переменной BlinkLED (настройка порта)
BlinkLED.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15; //номера пинов
BlinkLED.Mode = GPIO_MODE_OUTPUT_PP; //режим работы
BlinkLED.Pull = GPIO_NOPULL; //Pull режим
BlinkLED.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //частота сигнала на пине
GPIO_InitTypeDef Baton;
Baton.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
Baton.Mode = GPIO_MODE_IT_RISING;
Baton.Pull = GPIO_PULLUP;
Baton.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOE, &BlinkLED); // настройка вывода и порта
HAL_GPIO_Init(GPIOE, &Baton);
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_13,GPIO_PIN_SET); //отключение диодов
for(uint32_t i = 0; i<NUM_TICK_DELAY; i++);
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_14,GPIO_PIN_SET);
for(uint32_t i = 0; i<NUM_TICK_DELAY; i++);
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_15,GPIO_PIN_SET);
for(uint32_t i = 0; i<NUM_TICK_DELAY; i++);
bool sendMessage = false;
uint8_t rsMessage[3] = {0x00U, 0x01U, 0x02U};
uint16_t pins[3] = {GPIO_PIN_13, GPIO_PIN_14, GPIO_PIN_15};
uint8_t nMessage = 0xff;
bool transmitON = false;
while(1)
{
if((HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_10) == GPIO_PIN_RESET) && !sendMessage)
{
sendMessage = true;
nMessage = 0;
}
if((HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_11) == GPIO_PIN_RESET) && !sendMessage)
{
sendMessage = true;
nMessage = 1;
}
if((HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_12) == GPIO_PIN_RESET) && !sendMessage)
{
sendMessage = true;
nMessage = 2;
}
if (sendMessage && !transmitON)
{
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_13,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_14,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_15,GPIO_PIN_SET);
for(uint32_t i = 0; i<NUM_TICK_DELAY; i++);
HAL_GPIO_WritePin(GPIOE,pins[nMessage],GPIO_PIN_RESET);
rsTx(&huart2, (uint8_t*)&rsMessage[nMessage], sizeof(uint8_t));
for(uint32_t i = 0; i<NUM_TICK_DELAY; i++);
HAL_GPIO_WritePin(GPIOE,pins[nMessage],GPIO_PIN_SET);
transmitON = true;
}
if((HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_10) == GPIO_PIN_SET) && transmitON && nMessage == 0)
{
sendMessage = false;
transmitON = 0;
}
if((HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_11) == GPIO_PIN_SET) && transmitON && nMessage == 1)
{
sendMessage = false;
transmitON = 0;
}
if((HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_12) == GPIO_PIN_SET) && transmitON && nMessage == 2)
{
sendMessage = false;
transmitON = 0;
}
HAL_UART_Receive_IT(&huart2, &rxData, 1);
if (receiveON)
{
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_13,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_14,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_15,GPIO_PIN_SET);
if (rxData <= 0x02)
HAL_GPIO_WritePin(GPIOE,pins[rxData],GPIO_PIN_RESET);
receiveON = false;
}
}
}
void SysTick_Handler(void)
{
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
}




