代码分析 再写这里之前,应该已经学过模块化编程了,STM32的每个XXX.c 和xxx.h 这都是模块化编程。良好的程序,与其好的代码风格有关。你的代码风格跟你接触教你写代码的有很大关系。以前刚刚学习单片机编程,我还不信,现在我承认,跟教我单片机的老师风格有些像。 这里我做的是一个串口发送数据到PC机的例子: 要让STM32能够顺利发出数据,要进行如下配置 PA9,PA10管脚要配置, USART也需要配置波特率,数据有几位,停止位,数据流等。 USART和uart有什么区别 USART在做串口时,两者并不区别,但是USART有SPI的功能。还有串口通信为什么要配置波特率,停止位,硬件数据留这些,以前我也没想过,现在只觉得协议这个东西,是一个好的标准。 建立一个usart_debug.c的文本,内容如下 #include"usart_debug.h" void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能UASRT的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA的时钟,开始的时候,我没用这句话,调了两天,跟源码一句一句比才知道 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Pin =GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz; //波特率较高,IO翻转需较高频率 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出;我看网上有人说设置成GPIO_Mode_Out_PP普通推挽输出也行,但实践出真知,我试了发送是乱码。; GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin =GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //配置成浮空输入,既然是输入所以就不用配置IO口的频率了 GPIO_Init(GPIOA,&GPIO_InitStructure); } void USART1_config(void) { USART_InitTypeDef USART_InitStructure; 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(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); } //这段很重要,如果要使用printf函数打印信息,需要加fputc函数,就需要对printf函数重定向到串口,以前工作中他们老是提重定向,什么串口重定向,USB重定向什么的,我也是云里雾里,如今给我的感觉就是将上层函数实现对底层硬件的操作 int fputc(int ch, FILE*f){ while(USART_GetFlagStatus(USART1, USART_FLAG_TC) !=SET); //网上的一些函数里面是没有这一句代码,如果不加的话,打印时第一个字符就会没有,原因据说是硬件复位后,USART_FLAG_TC被置一了,而要发送数据必须让其为底才可以,一表示数据发送发出的标志,也可以用这样一句USART_ClearFlag(USART2,USART_FLAG_TC);清楚标准位。可是我没这样做一样发成功了,这个疑惑以后再想明白。 USART_SendData(USART1, (uint16_t)ch); while(USART_GetFlagStatus(USART1, USART_FLAG_TC) !=SET); return ch; } void usart_debug_config(void) //提供给main函数调用的串口配置函数 { GPIO_Configuration(); //IO口配置 USART1_config(); //串口配置 } 还就是usart_debug.h #ifndef __usart_debug_H #define __usart_debug_H #include "stm32f10x.h" #include void usart_debug_config(void); int fputc(int ch, FILE *f); #endif // __USART1_H main函数: 这里使用两种方式一种是 使用普通的方式发送,另一种使用printf函数 其实还有一种USART_printf函数来实现,这里不做介绍。有空看看区别一下printf和usart_printf,据说是支持格式多少的问题 #include"stm32f10x.h" #include"usart_debug.h" //包含main函数里的调用函数 int main(void) { unsigned char TxBuf1[100] ={"发送字符串!!!"}; int i; SystemInit(); usart_debug_config(); for( i = 0; TxBuf1 != ''; i++) { while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);//这里跟分析fputc时是一样的 USART_SendData(USART1 , TxBuf1);//发送字符数组里的单个字符 while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET); } printf("hello world! 世界你好! "); //调用printf函数 while(1) { ; } } |