C语言 如何仅使用键盘填充值从一个整数数组复制到另一个整数数组中?



我正在尝试存储从非阻塞UART协议接收的值。我从键盘输入字符,它们存储在一个称为缓冲区的数组中,该数组保存该值。然后,我想使用缓冲区数组中的值填充一个名为 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 个字节,而数组缓冲区的大小为 2 个字节?

这句话:newbuffer[i] = buffer[0];只是复制第一个字节。

如果您从键盘读取,您可能会收到扫描代码。扫描码不全是一个字节,而是很多字节。根据密钥的不同,它们最多可以有三个字节:https://en.wikipedia.org/wiki/Scancode。

我解决了这个问题。问题在于将逻辑置于 for 循环中。由于 newbuffer 的大小为 256,除非输入了所有字符并且 newbuffer 已满,否则程序不会退出 for 循环。通过将我的逻辑从 for 循环中取出,该函数可以完成并返回到 main,以便在输入下一个字符时在主循环中调用。

我还添加了一个标志变量,以便我可以打印用户键入回车按钮时输入的字符串。

接收回调例程:

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("nrEnter 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);
}

最新更新