STM32F103RCT6开发板M3单片机教程03--usart串口通信
首先了解编译调试硬件连接,查看原理图
STM32F103RCT6开发板用Jlink供电,USB转串口板电脑USB供电,那么连接只需3线
* TXD(PB9) -> USB转串口板RXD
* RXD(PB10) -> USB转串口T板XD
* GND -> USB转串口板GND
- 复制上节工程文件夹打开(这个方法比较方便)
- 新建源文件usart.c,添加usart.c到BSP(Grounp),并编辑
- STM32F103RCT6开发板M3单片机教程03--usart串口通信
- 首先了解编译调试硬件连接,查看原理图
- 复制上节工程文件夹打开(这个方法比较方便)
- 新建源文件usart.c,添加usart.c到BSP(Grounp),并编辑
- 新建源文件SysTick.h,并编辑
- 编辑main.c
- 编译调试
- /**********************************************************************************
- * 文件名 :usart.c
- * 描述 :usart1 应用函数库
- * 实验平台:SUN_STM32F1板
- * 硬件连接:TXD(PB9) -> USB转串口板RXD
- * RXD(PB10) -> USB转串口T板XD
- * GND -> USB转串口板GND
- * 库版本 :ST_v3.5
- * Version Date Auther Reversed History
- ----------------------------------------------------------------------------
- V1.0.0 2021-11-07 Lojam Fan Fisrt Created
-
- * (C) Sunshine Silicon Corporation
- * Website: http://www.sunsili.com http://sunsili.taobao.com http://bbs.sunsili.com
- * E-Mail : fan@sunsili.com
- **********************************************************************************/
- #include "usart.h"
-
- vu8 Usart1_R_Buff[USART1_REC_MAXLEN]; //串口1数据接收缓冲区
- vu8 Usart1_R_State=0; //串口1接收状态
- vu16 Usart1_R_Count=0; //当前接收数据的字节数
- /*******************************************************************************
- * 函数名 : USART1_Init_Config
- * 描述 : USART1初始化配置
- * 输入 : bound:波特率(常用:2400、4800、9600、19200、38400、115200等)
- * 输出 : 无
- * 返回 : 无
- * 说明 : 无
- *******************************************************************************/
- void USART1_Init_Config(u32 bound)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
-
- /*使能USART1和GPIOA外设时钟*/
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
- /*复位串口1*/
- USART_DeInit(USART1);
-
- /*USART1_GPIO初始化设置*/
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //USART1_TXD(PA.9)
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚输出最大速率为50MHz
- GPIO_Init(GPIOA, &GPIO_InitStructure); //调用库函数中的GPIO初始化函数,初始化USART1_TXD(PA.9)
-
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1_RXD(PA.10)
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
- GPIO_Init(GPIOA, &GPIO_InitStructure); //调用库函数中的GPIO初始化函数,初始化USART1_RXD(PA.10)
- /*USART1 初始化设置*/
- USART_InitStructure.USART_BaudRate = bound; //设置波特率
- USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8位数据格式
- USART_InitStructure.USART_StopBits = USART_StopBits_1; //1个停止位
- USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //工作模式设置为收发模式
- USART_Init(USART1, &USART_InitStructure); //初始化串口1
- /*Usart1 NVIC配置*/
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; //抢占优先级3
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级3
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
- NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
-
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能串口1接收中断
- USART_Cmd(USART1, ENABLE); //使能串口
- USART_ClearFlag(USART1, USART_FLAG_TC); //清除发送完成标志
- }
- /*******************************************************************************
- * 函数名 : USART_SendData
- * 描述 : USART1发送数据缓冲区数据
- * 输入 : *buff:数据缓冲区指针,len:发送数据长度
- * 输出 : 无
- * 返回 : 无
- * 说明 : 无
- *******************************************************************************/
- void USART1_SendData(u8* buff, u16 len)
- {
- u16 i;
- for(i=0; i
- {
- while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
- USART_SendData(USART1 ,buff[i]);
- }
- }
- /*******************************************************************************
- * 函数名 : USART1_IRQHandler
- * 描述 : 串口1中断服务程序
- * 输入 : 无
- * 返回 : 无
- * 说明 : 1)、只启动了USART1中断接收,未启动USART1中断发送。
- * 2)、接收到0x0d 0x0a(回车、"\r\n")代表帧数据接收完成
- *******************************************************************************/
- void USART1_IRQHandler(void)
- {
- u8 Res=0;
- if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
- {
- Res =USART_ReceiveData(USART1); //读取接收到的数据(USART1->DR)
-
- Usart1_R_Buff[Usart1_R_Count++] = Res;
- if(Usart1_R_State == 0)//数据接收未完成
- {
- if(Res == 0x0d)//接收到0x0d,下一个字节接收到0x0a则接收完成
- {
- Usart1_R_State =2;
- }
- }
- else if(Usart1_R_State == 2)
- {
- if(Res == 0x0a)//上一个字节接收到0x0d,这个字节接收到oxoa则接收完成
- {
- Usart1_R_State =1;//数据接收完成
- }
- else//接收错误
- {
- Usart1_R_State =0;
- Usart1_R_Count =0;
- }
- }
- if(Usart1_R_Count >= USART1_REC_MAXLEN)//接收数据长度走出接收数据缓冲区
- {
- if((Usart1_R_Buff[USART1_REC_MAXLEN-2] != 0x0d) || (Usart1_R_Buff[USART1_REC_MAXLEN-1] != 0x0a))
- {
- Usart1_R_Count =0;
- Usart1_R_State =0;
- }
- }
- }
- }
- /******************* (C) COPYRIGHT SUNSHINE SILICON **************************
- ******************** END OF FILE usart.c *******************/
复制代码
- 新建源文件usart.h,并编辑
- #ifndef __USART_H
- #define __USART_H
- #include "stm32f10x.h"
- #include
- #define USART1_REC_MAXLEN 200 //最大接收数据长度
- void USART1_Init_Config(u32 bound);
- void USART1_SendData(u8* buff, u16 len);
- //int fputc(int ch, FILE *f);
- //void USART1_printf(USART_TypeDef* USARTx, uint8_t *Data,...);
- #endif
- /******************* (C) COPYRIGHT SUNSHINE SILICON **************************
- ******************** END OF FILE usart.h *******************/
复制代码
- 编辑main.c
- /**********************************************************************************
- * Sun STM32 mini Demo
- * Description
-
- Uart Demo
-
- * Version Date Auther Reversed History
- ----------------------------------------------------------------------------
- V1.0.0 2021-11-07 Lojam Fan Fisrt Created
-
- * (C) Sunshine Silicon Corporation
- * Website: http://www.sunsili.com http://sunsili.taobao.com http://bbs.sunsili.com
- * E-Mail : fan@sunsili.com
- **********************************************************************************/
- #include "stm32f10x.h"
- #include "usart.h"
- #include "SysTick.h"
- #include "led.h"
- #include
- extern vu8 Usart1_R_Buff[USART1_REC_MAXLEN]; //串口1数据接收缓冲区
- extern vu8 Usart1_R_State; //串口1接收状态
- extern vu16 Usart1_R_Count; //当前接收数据的字节数
- /*******************************************************************************
- * 函数名 : main
- * 描述 : 主函数,用户程序从main函数开始运行
- * 输入 : 无
- * 输出 : 无
- * 返回值 : int:返回值为一个16位整形数
- * 说明 : 无
- *******************************************************************************/
- int main(void)
- {
- SysTick_Init_Config();
- USART1_Init_Config(115200);//USART1初始化配置
- LED_GPIO_Config();
- printf ("*===================================================*\n");
- printf ("* * Name: Sun STM32 mini Demo Code. *************\n");
- printf ("* * (C) Sunshine Silicon Corporation *************\n");
- printf ("* * Website: http://www.sunsili.com *************\n");
- printf ("* * E-Mail : fan@sunsili.com *************\n");
- printf ("*===================================================*\n");
- printf ("* Sun STM32 mini uart transmit the same data to PC .*\n");
- while (1)
- {
- if(Usart1_R_State == 1)//一帧数据接收完成
- {
- USART1_SendData((u8 *)Usart1_R_Buff, Usart1_R_Count); //USART1发送数据缓冲区数据(发送刚接收完成的一帧数据)
- Usart1_R_State =0;
- Usart1_R_Count =0;
- }
-
- printf("Hello Sunshine Silicon!\r");
- LED4_ON();
- Delay_nMs(500);
- LED4_OFF();
- Delay_nMs(500);
- }
- }
- /******************* (C) COPYRIGHT SUNSHINE SILICON **************************
- ******************** END OF FILE main.c *******************/
复制代码
- 编译调试
方法不再重复,经过前两节练习,大家应该是会了.
但发现程序不跑了,单调试发现程序卡在printf不动了。为什么呢?因为MCU不像电脑只要添加stdio.h, 就能用printf。MCU要重定向c库函数printf到USART1(不一定USART1,实际用哪个定义到哪个),标准库代码内容还会被优化掉,编译时不输出。如何让它跑起来了呢。
在usart.c中添加函数
- ///重定向c库函数printf到USART1
- int fputc(int ch, FILE *f)
- {
- /* 发送一个字节数据到USART1 */
- USART_SendData(USART1, (uint8_t) ch);
-
- /* 等待发送完毕 */
- while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
-
- return (ch);
- }
- ///重定向c库函数scanf到USART1
- int fgetc(FILE *f)
- {
- /* 等待串口1输入数据 */
- while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
- return (int)USART_ReceiveData(USART1);
- }
复制代码
设置编译时,加入MCU适用标准库函数
再次编译调试一切如愿。符合我们当初的设计。
工程源码
03STM32F103RCT6_UART1.zip
|