OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2170|回复: 0

关于STM32F串口通信的一些情况分析

[复制链接]

80

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
406
金钱
406
注册时间
2018-11-20
在线时间
25 小时
发表于 2019-8-21 14:50:07 | 显示全部楼层 |阅读模式
  在进行STM32F单片机学习中,楼主没有选择按照其他教材类的选用PA9,PA10串口1作为测试对象,也不选择超级电脑终端来进行串口收发。
  不选择串口1的理由如下:针对串口1的例程太多,照搬理解较少。选择串口3的理由在于USART3和PB口的时钟不在同一个总线上,比如分别在APB1,APB2总线上,在前面讲到,其实每个功能接口都可以创建一个.C文件和.H文件,在这里我们创建一个USART3.C和USART3.H文件其中,在USART3.C文件中代码如下:

  1.  void USART3_Config(void)

  2.   {

  3.   //定义结构体

  4.   GPIO_InitTypeDef GPIO_InitStructure;

  5.   USART_InitTypeDef USART_InitStructure;

  6.   //开启外部时钟

  7.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);

  8.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE );

  9.   // USART3 GPIO config

  10.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

  11.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  12.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  13.   GPIO_Init(GPIOB, &GPIO_InitStructure);

  14.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

  15.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOAtiNG;

  16.   GPIO_Init(GPIOB, &GPIO_InitStructure);

  17.   //USART3 mode config

  18.   USART_InitStructure.USART_BaudRate = 115200;

  19.   USART_InitStructure.USART_WordLength = USART_WordLength_8b;

  20.   USART_InitStructure.USART_StopBits = USART_StopBits_1;

  21.   USART_InitStructure.USART_Parity = USART_Parity_No;

  22.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  23.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  24.   USART_Init(USART3, &USART_InitStructure);

  25.   USART_Cmd(USART3, ENABLE);

  26.   }
复制代码

  在这个程序中,需要注意的是外部时钟配置这块,由于串口3和PB口不在同一条APB总线上,所以时钟配置这块需要分行写,不能用|并在一起,表示或关系,这一点尤其注意,虽然在实际运行中程序不会报错,但是实际中时钟没有开启,无法进行正常通信。
  虽然完成了初始化配置,但是在主函数编写通信收发函数,串口调试助手也不会显示任何接收信息,这是因为STM32没有直接调用的PRINTF函数。在这里我选用的是KEIL编程软件,因此需要编写PRINTF函数。具体函数为:

  1.  /禁用半主机模式/

  2.   #pragma import(__use_no_semihosting)

  3.   //标准库需要的支持函数

  4.   struct __FILE

  5.   {

  6.   int handle;

  7.   /* Whatever you require here. IF the only file you are using is */

  8.   /* standard output using printf() for debugging, no file handling */

  9.   /* is required. */

  10.   };

  11.   /* FILE is typedef’ d in stdio.h. */

  12.   FILE __stdout;

  13.   //定义SYS_EXIT()避免使用半主机模式

  14.   void _sys_exit(int x)

  15.   {

  16.   x = x;

  17.   }

  18.   int fputc(int ch,FILE *f)

  19.   {

  20.   while(USART_GetFlagStatus(USART3, USART_FLAG_TC) != SET); //等待上次发送结束

  21.   USART_SendData(USART3, (unsigned char)ch); //发送数据到串口

  22.   return (ch);

  23.   }

  24.   /*******************************************************************************

  25.   * Function Name : int fgetc(FILE *f)

  26.   * Description : Retargets the C library printf function to the USART.fgetc重定向

  27.   * Input : None

  28.   * Output : None

  29.   * Return : 读取到字符

  30.   *******************************************************************************/

  31.   int fgetc(FILE *f)

  32.   {

  33.   /* Loop until received a char */

  34.   while(!(USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == SET));

  35.   /* Read a character from the USART and RETURN */

  36.   return (USART_ReceiveData(USART3));

  37.   }
复制代码

  或者不需要禁用半主机模式函数,在keil中勾选那个USB MICROLIB选项,个人建议还是写禁用半主机模式函数比较好一些。完成PRINTF函数书写,才能在主函数中使用printf函数。如输入// printf("北京是中国人民共和国的首都"); 打开串口调试助手,并配置串口,将串口与电脑连接,运行即可在串口调试助手上打印北京是中国人民共和国的首都信息。
  在使用printf函数打印信息虽说是可行的,但是有时候我们需要显示对应的字符或者字符串,这时候需要在USART3.C中添加下列程序函数:

  1.  void USART3_Send_Byte(u8 Data) //发送字符;

  2.   {

  3.   while( USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET );

  4.   USART_SendData(USART3, Data);

  5.   }

  6.   void USART3_Send_String(u8 *Data, u8 len) //发送字符串

  7.   {

  8.   u8 i;

  9.   while(*Data)

  10.   USART3_Send_Byte(*Data++);

  11.   for (i = 0; i < len; ++i)

  12.   USART3_Send_Byte(Data);

  13.   }
复制代码

  添加完成这些后,然后在main函数中添加USART_SendData(USART3, 'k');USART3_Send_String("Hello", 5);即可以打印hello函数;需要说明的是在打印多个字符串时,注意在多个字符串之间增加延时时间,避免首字节字符被覆盖。

再给大家搞一些串口方面的资料供大家参考

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-11 23:12

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表