本帖最后由 聪聪哥哥 于 2024-7-8 20:27 编辑
一:实验目的 利用板载的CH340串口芯片完成单片机的串口通讯功能,实现基本的发送接收功能,并且将PC端发送来的数据,返回至串口中断。 通用异步收发器(UART)可以灵活地与外部设备进行全双工数据交换。通过分数波特率发生器, UART可以选择宽范围的波特率。异步单向通信和半双工单线通信,以及调制解调器( CTS/RTS)操作、 IrDA 红外功能也能够被支持。另外, UART 也支持多处理器之间的通信。对于高速数据通信,可以通过使用多缓冲器配置的 DMA 方式来实现。 二:硬件部分: 通过官方提供的原理图,得知需要使用的硬件引脚为PA9,PA10;查阅一下手册引脚定义: 可以配置为uart1 或者是usar1 两种不同的串口通讯模式,这里我选用的是uart1的通讯方式: 串口的基本配置流程如下: 步骤1:串口时钟使能,GPIO时钟使能,使能串口时钟: 步骤2:GPIO端口模式设置: //此处注意使用的IO口是否正常,是否需要映射。 步骤3:串口参数初始化://初始化,波特率,停止位,校验位等信息 步骤4:开启中断并且初始化NVIC(需要开启接收中断,否则不能正常接收PC端发来的数据) 步骤5:使能串口: 三:软件代码部分: { GPIO_InitTypeDef GPIO_InitStruct; NVIC_InitTypeDef NVIC_InitStruct; UART_InitTypeDef UART_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB2Periph_UART1, ENABLE);
UART_StructInit(&UART_InitStruct); UART_InitStruct.BaudRate = Baudrate; UART_InitStruct.WordLength = UART_WordLength_8b; UART_InitStruct.StopBits = UART_StopBits_1; UART_InitStruct.Parity = UART_Parity_No; UART_InitStruct.HWFlowControl = UART_HWFlowControl_None; UART_InitStruct.Mode = UART_Mode_Rx | UART_Mode_Tx; UART_Init(UART1, &UART_InitStruct);
UART_ITConfig(UART1, UART_IT_RX, ENABLE); UART_ITConfig(UART1, UART_IT_RXIDLE, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7);
GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = UART1_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct);
UART_Cmd(UART1, ENABLE); } /*********************************************************************************************************************** * @brief This function handles UART2 Handler * @param none * @retval none *********************************************************************************************************************/ void UART1_IRQHandler(void) { uint8_t i = 0;
if (SET == UART_GetITStatus(UART1, UART_IT_RX)) { UART_RxBuffer[UART_RxLength++] = UART_ReceiveData(UART1);
UART_ClearITPendingBit(UART1, UART_IT_RX); }
if (SET == UART_GetITStatus(UART1, UART_IT_RXIDLE)) { UART_ClearITPendingBit(UART1, UART_IT_RXIDLE);
for (i = 0; i < UART_RxLength; i++) { UART_SendData(UART1, UART_RxBuffer);
while (RESET == UART_GetFlagStatus(UART1, UART_FLAG_TXC)) { } }
UART_RxLength = 0; } }
实现效果截图: 上位机以1000ms的周期向单片机发送数据,下位机接收到数据后,将数据全部返回。 实际测试并无发现数据传输异常的现象。 在调试的过程中,需要注意串口的引脚,复用功能是否正常,开启串口中断和清接收和发送的标志位。 |