完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
此程序为STM32F103RCT6单片机UART1 与UART3两个个串口通讯实验,UART1与UART3互相收发信息。两个串口需要同时与电脑相连接。串口1利用STM32自身串口,串口3通过CH340模块与电脑USB通讯。
串口1给串口3发送数据,串口3接收后打印“串口1给串口3发送数据” 串口3给串口1发送数据,串口1接收后打印“串口1给串口3发送数据” 硬件连接图 实验结果图 串口初始化程序 串口初始化程序 #include "sys.h" #include "usart.h" #if SYSTEM_SUPPORT_OS #include "includes.h"//ucos 使用 #endif //加入以下代码,支持printf函数,而不需要选择use MicroLIB #if 1 #pragma import(__use_no_semihosting) //标准库需要的支持函数 struct __FILE { int handle; }; FILE __stdout; //定义_sys_exit()以避免使用半主机模式 void _sys_exit(int x) { x = x; } //重定义fputc函数 int fputc(int ch, FILE *f) { while((USART1->SR&0X40)==0);//循环发送,直到发送完毕 USART1->DR = (u8) ch; while((USART3->SR&0X40)==0);//循环发送,直到发送完毕 USART3->DR = (u8) ch; return ch; } #endif /******************** USART1 *******************/ #if EN_USART1_RX //如果使能了接收 //串口1中断服务程序 //注意,读取USARTx->SR能避免莫名其妙的错误 u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节. //接收状态 //bit15, 接收完成标志 //bit14, 接收到0x0d //bit13~0, 接收到的有效字节数目 u16 USART_RX_STA=0; //接收状态标记 u8 aRxBuffer[RXBUFFERSIZE];//HAL库使用的串口接收缓冲 UART_HandleTypeDef UART1_Handler; //UART句柄 //初始化IO 串口1 //bound:波特率 void uart_init(u32 bound) { //UART 初始化设置 UART1_Handler.Instance=USART1; //USART1 UART1_Handler.Init.BaudRate=bound; //波特率 UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式 UART1_Handler.Init.StopBits=UART_STOPBITS_1; //一个停止位 UART1_Handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位 UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控 UART1_Handler.Init.Mode=UART_MODE_TX_RX; //收发模式 HAL_UART_Init(&UART1_Handler); //HAL_UART_Init()会使能UART1 HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量 } //UART底层初始化,时钟使能,引脚配置,中断配置 //此函数会被HAL_UART_Init()调用 //huart:串口句柄 void HAL_UART_MspInit(UART_HandleTypeDef *huart) { //GPIO端口设置 GPIO_InitTypeDef GPIO_Initure; if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化 { __HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟 __HAL_RCC_USART1_CLK_ENABLE(); //使能USART1时钟 __HAL_RCC_AFIO_CLK_ENABLE(); GPIO_Initure.Pin=GPIO_PIN_9; //PA9 GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速 HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA9 GPIO_Initure.Pin=GPIO_PIN_10; //PA10 GPIO_Initure.Mode=GPIO_MODE_AF_INPUT; //模式要设置为复用输入模式! HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA10 #if EN_USART1_RX HAL_NVIC_EnableIRQ(USART1_IRQn); //使能USART1中断通道 HAL_NVIC_SetPriority(USART1_IRQn,3,3); //抢占优先级3,子优先级3 #endif } if(huart->Instance==USART3)//如果是串口3,进行串口1 MSP初始化 { __HAL_RCC_GPIOB_CLK_ENABLE(); //使能GPIOB时钟 __HAL_RCC_USART3_CLK_ENABLE(); //使能USART3时钟 __HAL_RCC_AFIO_CLK_ENABLE(); GPIO_Initure.Pin=GPIO_PIN_10; //PB10 GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速 HAL_GPIO_Init(GPIOB,&GPIO_Initure); //初始化PA9 GPIO_Initure.Pin=GPIO_PIN_11; //PB11 GPIO_Initure.Mode=GPIO_MODE_AF_INPUT; //模式要设置为复用输入模式! HAL_GPIO_Init(GPIOB,&GPIO_Initure); //初始化PB11 #if EN_USART3_RX HAL_NVIC_EnableIRQ(USART3_IRQn); //使能USART3中断通道 HAL_NVIC_SetPriority(USART3_IRQn,3,2); //抢占优先级3,子优先级2 #endif } } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance==USART1)//如果是串口1 { if((USART_RX_STA&0x8000)==0)//接收未完成 { if(USART_RX_STA&0x4000)//接收到了0x0d { if(aRxBuffer[0]!=0x0a)USART_RX_STA=0;//接收错误,重新开始 else USART_RX_STA|=0x8000; //接收完成了 } else //还没收到0X0D { if(aRxBuffer[0]==0x0d)USART_RX_STA|=0x4000; else { USART3_RX_BUF[USART_RX_STA&0X3FFF]=aRxBuffer[0] ; USART_RX_STA++; if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收 } } } } } //串口1中断服务程序 void USART1_IRQHandler(void) { u32 timeout=0; #if SYSTEM_SUPPORT_OS //使用OS OSIntEnter(); #endif HAL_UART_IRQHandler(&UART1_Handler); //调用HAL库中断处理公用函数 timeout=0; while (HAL_UART_GetState(&UART1_Handler) != HAL_UART_STATE_READY)//等待就绪 { timeout++;超时处理 if(timeout>HAL_MAX_DELAY) break; } timeout=0; while(HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)//一次处理完成之后,重新开启中断并设置RxXferCount为1 { timeout++; //超时处理 if(timeout>HAL_MAX_DELAY) break; } #if SYSTEM_SUPPORT_OS //使用OS OSIntExit(); #endif } #endif /******************** USART3 *******************/ #if EN_USART3_RX //如果使能了接收 //串口1中断服务程序 //注意,读取USARTx->SR能避免莫名其妙的错误 u8 USART3_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节. u16 USART3_RX_STA=0; //接收状态标记 //u8 aRxBuffer[RXBUFFERSIZE];//HAL库使用的串口接收缓冲 UART_HandleTypeDef UART3_Handler; //UART句柄 //初始化IO 串口1 //bound:波特率 void uart3_init(u32 bound) { //UART 初始化设置 UART3_Handler.Instance=USART3; //USART3 UART3_Handler.Init.BaudRate=bound; //波特率 UART3_Handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式 UART3_Handler.Init.StopBits=UART_STOPBITS_1; //一个停止位 UART3_Handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位 UART3_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控 UART3_Handler.Init.Mode=UART_MODE_TX_RX; //收发模式 HAL_UART_Init(&UART3_Handler); //HAL_UART_Init()会使能UART3 HAL_UART_Receive_IT(&UART3_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量 } //UART底层初始化,时钟使能,引脚配置,中断配置 //此函数会被HAL_UART_Init()调用 //huart:串口句柄 //串口3中断服务程序 void USART3_IRQHandler(void) { u8 Res; HAL_StatusTypeDef err; #if SYSTEM_SUPPORT_OS //使用OS OSIntEnter(); #endif if((__HAL_UART_GET_FLAG(&UART3_Handler,UART_FLAG_RXNE)!=RESET)) //接收中断(接收到的数据必须是0x0d 0x0a结尾) { Res=USART3->DR; if((USART3_RX_STA&0x8000)==0)//接收未完成 { if(USART3_RX_STA&0x4000)//接收到了0x0d { if(Res!=0x0a)USART3_RX_STA=0;//接收错误,重新开始 else USART3_RX_STA|=0x8000; //接收完成了 } else //还没收到0X0D { if(Res==0x0d)USART3_RX_STA|=0x4000; else { USART_RX_BUF[USART3_RX_STA&0X3FFF]=Res ; USART3_RX_STA++; if(USART3_RX_STA>(USART_REC_LEN3-1))USART3_RX_STA=0;//接收数据错误,重新开始接收 } } } } HAL_UART_IRQHandler(&UART3_Handler); #if SYSTEM_SUPPORT_OS //使用OS OSIntExit(); #endif } #endif 主函数 #include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "key.h" int main(void) { u8 len; u16 times=0; HAL_Init(); //初始化HAL库 Stm32_Clock_Init(RCC_PLL_MUL9); //设置时钟,72M delay_init(72); //初始化延时函数 uart_init(115200); //初始化串口 uart3_init(115200); //初始化串口 LED_Init(); //初始化LED KEY_Init(); //初始化按键 while(1) { if(USART3_RX_STA&0x8000) { len=USART3_RX_STA&0x3fff;//得到此次接收到的数据长度 HAL_UART_Transmit(&UART1_Handler,(uint8_t*)USART_RX_BUF,len,1000); //发送接收到的数据 while(__HAL_UART_GET_FLAG(&UART3_Handler,UART_FLAG_TC)!=SET); //等待发送结束 printf("rnrn");//插入换行 USART3_RX_STA=0; } if(USART_RX_STA&0x8000) { len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度 HAL_UART_Transmit(&UART3_Handler,(uint8_t*)USART3_RX_BUF,len,1000); //发送接收到的数据 while(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_TC)!=SET); //等待发送结束 printf("rnrn");//插入换行 USART_RX_STA=0; } } } |
|
|
|
只有小组成员才能发言,加入小组>>
3323 浏览 9 评论
3000 浏览 16 评论
3497 浏览 1 评论
9072 浏览 16 评论
4093 浏览 18 评论
1192浏览 3评论
613浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
603浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2341浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1899浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-29 03:27 , Processed in 1.046794 second(s), Total 48, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号