STM32 UART DMA Circular Buffer ReceiveToIdle



Запись принятых по UART данных в Circular Buffer (круговой буфер) с использованием DMA (процессор не тратит свое время на заполнение массива с принятыми данными).
Запускаем HAL_UARTEx_ReceiveToIdle_DMA
Прерывания по Idle HAL_UARTEx_RxEventCallback

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
...
/* USER CODE BEGIN 0 */
#define UART1RxBufferLength 26
 
uint8_t UART1_RecieveBuffer[UART1RxBufferLength];
uint8_t UART2_TransmitBuffer[100];
 
uint8_t t_MakeUARTTransmit = 0;
 
volatile uint16_t t_UART_Errors_C = 0;
volatile uint32_t t_UARTRecieveCNT = 0;
volatile uint16_t t_CurrentUART1RxBufferPosition = 0;
 
void ResetUART1RxBuffer(void)
{
	uint16_t i = 0;
	while (i < UART1RxBufferLength)
	{
		UART1_RecieveBuffer[i] = 0;
		i++;
	}
}
 
void StartUART1RecieveToIdleDMA(void)
{
	ResetUART1RxBuffer();
	HAL_UARTEx_ReceiveToIdle_DMA(&huart1, UART1_RecieveBuffer, UART1RxBufferLength);
}
 
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
	if (huart->Instance == USART1)
	{
		StartUART1RecieveToIdleDMA();
		t_UART_Errors_C++;
	}
}
 
void  HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	t_UARTRecieveCNT++;
	t_CurrentUART1RxBufferPosition = Size;
	//t_UARTRecievedDataSize = Size;
 
	HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4);
 
}
/* USER CODE END 0 */
...
/* USER CODE BEGIN WHILE */
  StartUART1RecieveToIdleDMA();
  uint8_t TransferLength = 0;
  while (1)
  {
    if (t_MakeUARTTransmit == 1)
	{
		TransferLength = sprintf((char*)UART2_TransmitBuffer, "1234567890");
		HAL_UART_Transmit(&huart2, UART2_TransmitBuffer, TransferLength, 100);
		HAL_Delay(1);
		HAL_UART_Transmit(&huart2, UART2_TransmitBuffer, TransferLength, 100);
		HAL_UART_Transmit(&huart2, UART2_TransmitBuffer, TransferLength, 100);
 
		t_MakeUARTTransmit = 0;
	}
    /* USER CODE END WHILE */



Разбор данных UART из Circular Buffer (пример)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
...
/* USER CODE BEGIN 0 */
#define UART1RxBufferLength 24
 
uint8_t UART1_RecieveBuffer[UART1RxBufferLength];
uint8_t UART2_TransmitBuffer[100];
 
uint8_t t_MakeUARTTransmit = 0;
 
volatile uint16_t t_UART_Errors_C = 0;
volatile uint32_t t_UARTRecieveCNT = 0;
volatile uint16_t t_CurrentUART1RxBufferPosition = 0;
 
volatile uint16_t t_CurrentProcessedBufferPosition = 0;
 
volatile uint8_t t_CanMakeUARTBufferProcessing = 0;
volatile uint32_t t_UART1RecievedAt = 0;
 
uint8_t t_UARTExtractedData[10];
 
void ResetUART1RxBuffer(void)
{
	uint16_t i = 0;
	while (i < UART1RxBufferLength)
	{
		UART1_RecieveBuffer[i] = 0;
		i++;
	}
}
 
void ResetUARTExtractedDataBuffer(void)
{
	uint16_t i = 0;
	while (i < 10)
	{
		t_UARTExtractedData[i] = 0;
		i++;
	}
}
 
void StartUART1RecieveToIdleDMA(void)
{
	ResetUART1RxBuffer();
	HAL_UARTEx_ReceiveToIdle_DMA(&huart1, UART1_RecieveBuffer, UART1RxBufferLength);
}
 
void HAL_UART_ErrorCallback(UART_HandleTypeDef *husart)
{
	if (husart->Instance == USART1)
	{
		StartUART1RecieveToIdleDMA();
		t_UART_Errors_C++;
	}
}
 
void  HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *husart, uint16_t Size)
{
	t_UARTRecieveCNT++;
	t_CurrentUART1RxBufferPosition = Size;
	t_UART1RecievedAt = HAL_GetTick();
	t_CanMakeUARTBufferProcessing = 1;
}
 
uint8_t t_Value = 0;
uint16_t t_LengthToProcess = 0;
 
void ProcessUARTBuffer(void)
{
	uint16_t i = t_CurrentProcessedBufferPosition;
	uint16_t k = 0;
	uint16_t LengthToProcess = 0;
	uint16_t Processed_C = 0;
	uint8_t Started = 0;
	uint16_t CurrentUART1RxBufferPosition = t_CurrentUART1RxBufferPosition;
 
	ResetUARTExtractedDataBuffer();
 
	if (CurrentUART1RxBufferPosition >= t_CurrentProcessedBufferPosition)
	{
		LengthToProcess = CurrentUART1RxBufferPosition - t_CurrentProcessedBufferPosition;
	} else
	{
		if (t_CurrentProcessedBufferPosition > CurrentUART1RxBufferPosition)
		{
			LengthToProcess = (int)UART1RxBufferLength - t_CurrentProcessedBufferPosition + CurrentUART1RxBufferPosition;
		}
	}
 
	t_LengthToProcess = LengthToProcess;
	//HAL_Delay(2000);
 
	while (Processed_C < LengthToProcess)
	{
		if (Started == 1)
		{
			if (UART1_RecieveBuffer[i] == '_')
			{
				t_CurrentProcessedBufferPosition = i+1;
				if (t_CurrentProcessedBufferPosition >= UART1RxBufferLength)
				{
					t_CurrentProcessedBufferPosition = 0;
				}
				break;
			}
			t_UARTExtractedData[k] = UART1_RecieveBuffer[i];
			k++;
		}
 
		if (UART1_RecieveBuffer[i] == '$')
		{
			if (Started == 0)
			{
				Started = 1;
			} else
			{
				ResetUARTExtractedDataBuffer();
				break;
			}
		};
 
		LengthToProcess++;
		i++;
		if (i == UART1RxBufferLength)
		{
			i = 0;
		}
	}
}
/* USER CODE END 0 */
...
/* USER CODE BEGIN WHILE */
  StartUART1RecieveToIdleDMA();
  uint8_t TransferLength = 0;
  while (1)
  {
    if (t_MakeUARTTransmit == 1)
	{
		TransferLength = sprintf((char*)UART2_TransmitBuffer, "$1234567_");
		HAL_UART_Transmit(&huart2, UART2_TransmitBuffer, TransferLength, 100);
 
		t_MakeUARTTransmit = 0;
	}
 
    if (t_MakeUARTTransmit == 2)
	{
		TransferLength = sprintf((char*)UART2_TransmitBuffer, "$ABC_");
		HAL_UART_Transmit(&huart2, UART2_TransmitBuffer, TransferLength, 100);
 
		t_MakeUARTTransmit = 0;
	}
 
    /*if (t_CanMakeUARTBufferProcessing == 1)
    {
    	t_CanMakeUARTBufferProcessing = 0;
    	ProcessUARTBuffer();
    }*/
    if ((t_UART1RecievedAt > 0) && (HAL_GetTick() > (t_UART1RecievedAt + 10)))
    {
    	ProcessUARTBuffer();
    	t_UART1RecievedAt = 0;
    }
    /* USER CODE END WHILE */
...



1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (2 оценок, среднее: 5,00 из 5)

Загрузка...

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Optionally add an image (JPEG only)