如何仅使用键盘将值从一个整数数组复制到另一个整数数组来填充它们?
How do I copy values from one integer array into another integer array using only the keyboard to fill them?
我正在尝试存储从非阻塞 UART 协议接收到的值。我从键盘输入字符,它们存储在一个名为 buffer 的数组中,该数组保存值。然后我想使用缓冲区数组中的值填充一个名为 newbuffer 的新数组,然后清除缓冲区数组中的值,以便它准备好从键盘接收另一个值。
这是我的初始化:
uint8_t buffer[2] = {0}; //initialize array for receiving keyboard input
uint8_t newbuffer[256] = {0}; //initialize array to store keyboard input from buffer array
int i = 0; //array index variable
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_9B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_EVEN;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
这是我输入第一个字符后的回调例程。这部分我真的需要一些帮助!!!
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//Prevent unused argument(s) compilation warning
UNUSED(huart);
for (i = 0; i < sizeof(newbuffer); i++)
{
newbuffer[i] = buffer[0]; //put value entered from keyboard into newbuffer array
memset(buffer, 0, sizeof(buffer)); //clear buffer array for next value
HAL_UART_Receive_IT (&UartHandle, buffer, 1); //call interrupt that handles entering keyboard values
}
printf("%d", newbuffer);
}
这是获取键盘值的中断函数,以备不时之需。
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
uint16_t *tmp;
/* Check that a Rx process is ongoing */
if (huart->RxState == HAL_UART_STATE_BUSY_RX)
{
if (huart->Init.WordLength == UART_WORDLENGTH_9B)
{
tmp = (uint16_t *) huart->pRxBuffPtr;
if (huart->Init.Parity == UART_PARITY_NONE)
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
huart->pRxBuffPtr += 2U;
}
else
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
huart->pRxBuffPtr += 1U;
}
}
else
{
if (huart->Init.Parity == UART_PARITY_NONE)
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
}
else
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
}
}
if (--huart->RxXferCount == 0U)
{
/* Disable the UART Data Register not empty Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
/* Disable the UART Parity Error Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
/* Rx process is completed, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx complete callback*/
huart->RxCpltCallback(huart);
#else
/*Call legacy weak Rx complete callback*/
HAL_UART_RxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
return HAL_OK;
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
提前致谢:)
您是否意识到您在 HAL_UART_RxCpltCallback 内的 for 循环中恰好复制了 1 个字节,而数组缓冲区的大小是两个字节?
这句话:newbuffer[i] = buffer[0];
只是复制第一个字节。
如果您通过键盘阅读,您可能会收到扫描码。扫描码不都是一个字节,而是很多个。根据键的不同,它们最多可以是三个字节:https://en.wikipedia.org/wiki/Scancode.
我解决了这个问题。问题在于将逻辑置于 for 循环中。由于 newbuffer 的大小为 256,程序不会退出 for 循环,除非所有字符都已输入且 newbuffer 已满。通过将我的逻辑从 for 循环中取出,该函数可以完成,并且 return 到 main 在输入下一个字符时在主循环中被调用。
我还添加了一个标志变量,以便在用户键入回车 return 按钮时打印输入的字符串。
接收回调例程:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//Prevent unused argument(s) compilation warning
UNUSED(huart);
newbuffer[i] = buffer[0] //put value entered from keyboard into newbuffer array
if (newbuffer[i] == '\r') //if user enters a carriage return the input will be flagged and trigger the while loop to print the string
{
flag = 1;
}
else
{
flag = 0;
}
memset(buffer, 0, sizeof(buffer)); //clear buffer array to receive next keyboard value
i++; //increment newbuffer index
HAL_UART_Receive_IT (&UartHandle, buffer, 1); //call interrupt that handles entering keyboard values
主要:
int main(void)
{
HAL_Init();
/* Configure the system clock to 180 MHz */
SystemClock_Config();
/* Initialize BSP Led for LED2 */
BSP_LED_Init(LED2);
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_9B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_EVEN;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&UartHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
NVIC_SetPriority(USART3_IRQn, (1u << __NVIC_PRIO_BITS) - 5u); //set interrupt priority
NVIC_EnableIRQ(USART3_IRQn);
/*INTERRUPT METHOD*/
HAL_UART_Receive_IT (&UartHandle, buffer, 1); //call UART receive interrupt to get keyboard input
//Infinite loop
while (1)
{
//output a message in Hyperterminal requesting keyboard input
printf("\n\rEnter your string: ");
NVIC_DisableIRQ(USART3_IRQn);
if (flag == 1)
{
printf("%s", newbuffer); //string is printed if user enters a carriage return
flag = 0; //reset flag so the interrupt routine can look for another carriage return
memset(newbuffer, 0, sizeof(newbuffer)); //clear newbuffer so it is ready to store a new string
i = 0; //reset index so newbuffer begins storing its new string starting at newbuffer[0]
}
NVIC_EnableIRQ(USART3_IRQn);
HAL_Delay (1000);
}
我正在尝试存储从非阻塞 UART 协议接收到的值。我从键盘输入字符,它们存储在一个名为 buffer 的数组中,该数组保存值。然后我想使用缓冲区数组中的值填充一个名为 newbuffer 的新数组,然后清除缓冲区数组中的值,以便它准备好从键盘接收另一个值。
这是我的初始化:
uint8_t buffer[2] = {0}; //initialize array for receiving keyboard input
uint8_t newbuffer[256] = {0}; //initialize array to store keyboard input from buffer array
int i = 0; //array index variable
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_9B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_EVEN;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
这是我输入第一个字符后的回调例程。这部分我真的需要一些帮助!!!
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//Prevent unused argument(s) compilation warning
UNUSED(huart);
for (i = 0; i < sizeof(newbuffer); i++)
{
newbuffer[i] = buffer[0]; //put value entered from keyboard into newbuffer array
memset(buffer, 0, sizeof(buffer)); //clear buffer array for next value
HAL_UART_Receive_IT (&UartHandle, buffer, 1); //call interrupt that handles entering keyboard values
}
printf("%d", newbuffer);
}
这是获取键盘值的中断函数,以备不时之需。
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
uint16_t *tmp;
/* Check that a Rx process is ongoing */
if (huart->RxState == HAL_UART_STATE_BUSY_RX)
{
if (huart->Init.WordLength == UART_WORDLENGTH_9B)
{
tmp = (uint16_t *) huart->pRxBuffPtr;
if (huart->Init.Parity == UART_PARITY_NONE)
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
huart->pRxBuffPtr += 2U;
}
else
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
huart->pRxBuffPtr += 1U;
}
}
else
{
if (huart->Init.Parity == UART_PARITY_NONE)
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
}
else
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
}
}
if (--huart->RxXferCount == 0U)
{
/* Disable the UART Data Register not empty Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
/* Disable the UART Parity Error Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
/* Rx process is completed, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx complete callback*/
huart->RxCpltCallback(huart);
#else
/*Call legacy weak Rx complete callback*/
HAL_UART_RxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
return HAL_OK;
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
提前致谢:)
您是否意识到您在 HAL_UART_RxCpltCallback 内的 for 循环中恰好复制了 1 个字节,而数组缓冲区的大小是两个字节?
这句话:newbuffer[i] = buffer[0];
只是复制第一个字节。
如果您通过键盘阅读,您可能会收到扫描码。扫描码不都是一个字节,而是很多个。根据键的不同,它们最多可以是三个字节:https://en.wikipedia.org/wiki/Scancode.
我解决了这个问题。问题在于将逻辑置于 for 循环中。由于 newbuffer 的大小为 256,程序不会退出 for 循环,除非所有字符都已输入且 newbuffer 已满。通过将我的逻辑从 for 循环中取出,该函数可以完成,并且 return 到 main 在输入下一个字符时在主循环中被调用。
我还添加了一个标志变量,以便在用户键入回车 return 按钮时打印输入的字符串。
接收回调例程:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//Prevent unused argument(s) compilation warning
UNUSED(huart);
newbuffer[i] = buffer[0] //put value entered from keyboard into newbuffer array
if (newbuffer[i] == '\r') //if user enters a carriage return the input will be flagged and trigger the while loop to print the string
{
flag = 1;
}
else
{
flag = 0;
}
memset(buffer, 0, sizeof(buffer)); //clear buffer array to receive next keyboard value
i++; //increment newbuffer index
HAL_UART_Receive_IT (&UartHandle, buffer, 1); //call interrupt that handles entering keyboard values
主要:
int main(void)
{
HAL_Init();
/* Configure the system clock to 180 MHz */
SystemClock_Config();
/* Initialize BSP Led for LED2 */
BSP_LED_Init(LED2);
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_9B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_EVEN;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&UartHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
NVIC_SetPriority(USART3_IRQn, (1u << __NVIC_PRIO_BITS) - 5u); //set interrupt priority
NVIC_EnableIRQ(USART3_IRQn);
/*INTERRUPT METHOD*/
HAL_UART_Receive_IT (&UartHandle, buffer, 1); //call UART receive interrupt to get keyboard input
//Infinite loop
while (1)
{
//output a message in Hyperterminal requesting keyboard input
printf("\n\rEnter your string: ");
NVIC_DisableIRQ(USART3_IRQn);
if (flag == 1)
{
printf("%s", newbuffer); //string is printed if user enters a carriage return
flag = 0; //reset flag so the interrupt routine can look for another carriage return
memset(newbuffer, 0, sizeof(newbuffer)); //clear newbuffer so it is ready to store a new string
i = 0; //reset index so newbuffer begins storing its new string starting at newbuffer[0]
}
NVIC_EnableIRQ(USART3_IRQn);
HAL_Delay (1000);
}