中级会员
 
- 积分
- 406
- 金钱
- 406
- 注册时间
- 2018-11-20
- 在线时间
- 25 小时
|
在进行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函数;需要说明的是在打印多个字符串时,注意在多个字符串之间增加延时时间,避免首字节字符被覆盖。
再给大家搞一些串口方面的资料供大家参考
|
|