USART経由でデータを受信するのに問題があります。実際に達成したいのは、特定の長さ(可能な最大長のみ)なしでUSARTを介してコマンドを受信できることです。したがって、割り込みルーチンを使用して、受信した各文字をチェックしますが、どういうわけか自分が望むものを達成できません。このルーチンは、新しいキャラクターを受け取るたびに呼び出されますが、何らかの理由でHAL_UART_Receive_IT(&huart1、rx_data、buff_size_rx)がリアルタイムでアップグレードされず、rx_data [pointer]をチェックするときに受け取ったキャラクターが表示されませんが、しばらくするとrx_dataバッファーにあります。
私がこれまでに持っているもの:
int pointer =0;
...
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
if ( USART1->ISR & UART_IT_TXE) {
}
if ( USART1->ISR & UART_IT_RXNE) {
HAL_UART_Receive_IT(&huart1,rx_data,buff_size_rx);
if(rx_data[pointer]=='\0') {
pointer=0;
readCommand(rx_data);
clearBuffer(rx_data,buff_size_rx);
} else {
pointer++;
if(pointer>=buff_size_rx) {
pointer=0;
}
}
}
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
HAL_UART_Receive_IT()
は、そのように割り込みハンドラーから呼び出されるのではなく、割り込みを介してfixedバイト数の受信を開始するためのものです。
可能な回避策は、入力バッファーをチェックすることですafterHAL_UART_IRQHandler()
が完了した、つまり_/* USER CODE BEGIN USART1_IRQn 1 */
_セクションで。コマンドが処理されると、ハンドル構造内のpRxBuffPtr
とRxXferCount
を元の値にリセットして、バッファの先頭から再び開始できます。
別の 恐ろしい 考えられる回避策は、バッファサイズ1でHAL_UART_Receive_IT()
を呼び出し、毎回受信バイトをチェックし、HAL_UART_RxCpltCallback()
を再度呼び出すHAL_UART_Receive_IT()
ハンドラを設定することです。必要に応じて。
もちろん、PeterJや他の人(常に)が示唆しているように、HALなしでも実行できます。
UART->BRR
_値を計算するか、halから関連するコードをコピーします。UART->CR1=USART_CR1_RE|USART_CR1_TE|USART_CR1_UE|USART_CR1_RXNEIE;
_現在、割り込みが発生しています。UART->SR
_を一時変数に読み込んで調べます。UART->DR
_を読み取り、それ以外の場合は(後で)エラー処理を行います。組み込みアプリケーションでは、割り込み応答と処理時間はしばしばcriticalであり、HALはその多くを浪費します。
通常のHALライブラリは、長さの異なる連続受信やコマンドには役立ちません。
完全なHALパッケージがインストールされている場合、[〜#〜] l [〜#〜] ow [〜#〜] l [〜#〜 ]インターフェイスを開発します。
Projects\STM32F411RE-Nucleo\Examples_LL\USART\USART_Communication_Rx_IT_Continuous
主なことは、usartを継続的な受信に設定することです。
void Configure_USART(void) {
/* (1) Enable GPIO clock and configures the USART pins *********************/
/* Enable the peripheral clock of GPIO Port */
USARTx_GPIO_CLK_ENABLE();
/* Configure Tx Pin as : Alternate function, High Speed, Push pull, Pull up */
LL_GPIO_SetPinMode(USARTx_TX_GPIO_PORT, USARTx_TX_PIN, LL_GPIO_MODE_ALTERNATE);
USARTx_SET_TX_GPIO_AF();
LL_GPIO_SetPinSpeed(USARTx_TX_GPIO_PORT, USARTx_TX_PIN, LL_GPIO_SPEED_FREQ_HIGH);
LL_GPIO_SetPinOutputType(USARTx_TX_GPIO_PORT, USARTx_TX_PIN, LL_GPIO_OUTPUT_PUSHPULL);
LL_GPIO_SetPinPull(USARTx_TX_GPIO_PORT, USARTx_TX_PIN, LL_GPIO_PULL_UP);
/* Configure Rx Pin as : Alternate function, High Speed, Push pull, Pull up */
LL_GPIO_SetPinMode(USARTx_RX_GPIO_PORT, USARTx_RX_PIN, LL_GPIO_MODE_ALTERNATE);
USARTx_SET_RX_GPIO_AF();
LL_GPIO_SetPinSpeed(USARTx_RX_GPIO_PORT, USARTx_RX_PIN, LL_GPIO_SPEED_FREQ_HIGH);
LL_GPIO_SetPinOutputType(USARTx_RX_GPIO_PORT, USARTx_RX_PIN, LL_GPIO_OUTPUT_PUSHPULL);
LL_GPIO_SetPinPull(USARTx_RX_GPIO_PORT, USARTx_RX_PIN, LL_GPIO_PULL_UP);
/* (2) NVIC Configuration for USART interrupts */
/* - Set priority for USARTx_IRQn */
/* - Enable USARTx_IRQn */
NVIC_SetPriority(USARTx_IRQn, 0);
NVIC_EnableIRQ(USARTx_IRQn);
/* (3) Enable USART peripheral clock and clock source ***********************/
USARTx_CLK_ENABLE();
/* (4) Configure USART functional parameters ********************************/
/* TX/RX direction */
LL_USART_SetTransferDirection(USARTx_INSTANCE, LL_USART_DIRECTION_TX_RX);
/* 8 data bit, 1 start bit, 1 stop bit, no parity */
LL_USART_ConfigCharacter(USARTx_INSTANCE, LL_USART_DATAWIDTH_8B, LL_USART_PARITY_NONE, LL_USART_STOPBITS_1);
/* No Hardware Flow control */
/* Reset value is LL_USART_HWCONTROL_NONE */
// LL_USART_SetHWFlowCtrl(USARTx_INSTANCE, LL_USART_HWCONTROL_NONE);
/* Oversampling by 16 */
/* Reset value is LL_USART_OVERSAMPLING_16 */
// LL_USART_SetOverSampling(USARTx_INSTANCE, LL_USART_OVERSAMPLING_16);
/* Set Baudrate to 115200 using APB frequency set to 100000000/APB_Div Hz */
/* Frequency available for USART peripheral can also be calculated through LL RCC macro */
/* Ex :
Periphclk = LL_RCC_GetUSARTClockFreq(Instance); or
LL_RCC_GetUARTClockFreq(Instance); depending on USART/UART instance
In this example, Peripheral Clock is expected to be equal to
100000000/APB_Div Hz => equal to SystemCoreClock/APB_Div
*/
LL_USART_SetBaudRate(USARTx_INSTANCE, SystemCoreClock/APB_Div, LL_USART_OVERSAMPLING_16, 115200);
/* (5) Enable USART *********************************************************/
LL_USART_Enable(USARTx_INSTANCE);
}
USART ITハンドラーは次のようになります
void USARTx_IRQHandler(void)
{
/* Check RXNE flag value in SR register */
if(LL_USART_IsActiveFlag_RXNE(USARTx_INSTANCE) && LL_USART_IsEnabledIT_RXNE(USARTx_INSTANCE))
{
/* RXNE flag will be cleared by reading of DR register (done in call) */
/* Call function in charge of handling Character reception */
USART_CharReception_Callback();
}
else
{
/* Call Error function */
Error_Callback();
}
}
最後に設定するのはコールバックです
void USART_CharReception_Callback(void);
バイトをバッファに入れて、メインループまたは任意の場所で処理できる場所。