关于STM32F串口通信的分析

  在进行STM32F单片机学习中,楼主没有选择按照其他教材类的选用PA9,PA10串口1作为测试对象,也不选择超级电脑终端来进行串口收发。

  不选择串口1的理由如下:针对串口1的例程太多,照搬理解较少。选择串口3的理由在于USART3和PB口的时钟不在同一个总线上,比如分别在APB1,APB2总线上,在前面讲到,其实每个功能接口都可以创建一个.C文件和.H文件,在这里我们创建一个USART3.C和USART3.H文件其中,在USART3.C文件中代码如下:

 

 void USART3_Config(void)

  {

  //定义结构体

  GPIO_InitTypeDef GPIO_InitStructure;

  USART_InitTypeDef USART_InitStructure;

  //开启外部时钟

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE );

  // USART3 GPIO config

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOAtiNG;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  //USART3 mode config

  USART_InitStructure.USART_BaudRate = 115200;

  USART_InitStructure.USART_WordLength = USART_WordLength_8b;

  USART_InitStructure.USART_StopBits = USART_StopBits_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(USART3, &USART_InitStructure);

  USART_Cmd(USART3, ENABLE);

  }

  在这个程序中,需要注意的是外部时钟配置这块,由于串口3和PB口不在同一条APB总线上,所以时钟配置这块需要分行写,不能用|并在一起,表示或关系,这一点尤其注意,虽然在实际运行中程序不会报错,但是实际中时钟没有开启,无法进行正常通信。

  虽然完成了初始化配置,但是在主函数编写通信收发函数,串口调试助手也不会显示任何接收信息,这是因为STM32没有直接调用的PRINTF函数。在这里我选用的是KEIL编程软件,因此需要编写PRINTF函数。具体函数为:

 

 /禁用半主机模式/

  #pragma import(__use_no_semihosting)

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

  struct __FILE

  {

  int handle;

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

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

  /* is required. */

  };

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

  FILE __stdout;

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

  void _sys_exit(int x)

  {

  x = x;

  }

  int fputc(int ch,FILE *f)

  {

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

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

  return (ch);

  }

  /*******************************************************************************

  * Function Name : int fgetc(FILE *f)

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

  * Input : None

  * Output : None

  * Return : 读取到字符

  *******************************************************************************/

  int fgetc(FILE *f)

  {

  /* Loop until received a char */

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

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

  return (USART_ReceiveData(USART3));

  }

  或者不需要禁用半主机模式函数,在keil中勾选那个USB MICROLIB选项,个人建议还是写禁用半主机模式函数比较好一些。完成PRINTF函数书写,才能在主函数中使用printf函数。如输入// printf("北京是中国人民共和国的首都"); 打开串口调试助手,并配置串口,将串口与电脑连接,运行即可在串口调试助手上打印北京是中国人民共和国的首都信息。

  在使用printf函数打印信息虽说是可行的,但是有时候我们需要显示对应的字符或者字符串,这时候需要在USART3.C中添加下列程序函数:

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

  {

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

  USART_SendData(USART3, Data);

  }

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

  {

  u8 i;

  while(*Data)

  USART3_Send_Byte(*Data++);

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

  USART3_Send_Byte(Data);

  }

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

相应的资料

通信协议 - UART串口
http://www.makeru.com.cn/live/3576_1437.html?s=45051

stm32之SPI通信
http://www.makeru.com.cn/live/3523_1795.html?s=45051

(stm32串口应用)
http://www.makeru.com.cn/live/1392_1164.html?s=45051

(stm32直流电机驱动)
http://www.makeru.com.cn/live/1392_1218.html?s=45051

也可以加群交个朋友 830802928    可以多分享一些学习资料

猜你喜欢

转载自www.cnblogs.com/hqyj321/p/11388637.html