STM32F407ZGT6串口学习笔记

1、RS485:半双工通信方式。

2、RS232C:对应DB25接口,要注意RS232才对应DB9接口(采用负逻辑:普遍记为“高电平-3~-15”、“低电平+3~+15”;但是根据我的实践来看,采用以上范围记忆的办法,到你真正需要使用然后回忆起来的时候往往会记混,所以只需要记为:负逻辑、高-9、低+9)。电脑上位机使用RS232电平时需要通过max3232芯片转换成TTL电平接入单片机中。

  另外,原本只是知道网线有分直连线和交叉线,原来RS232也有。。。RS232通信线两端分别为:一公一母(直连线:电脑主机和单片机通信(也就是不同类型机器之间通信))、两头相同(交叉线:两台电脑主机间通信(也就是同类型机器之间通信));

  说到这里还想起了一开始认VGA接口的时候头脑里没有印象,实际上可以看看电脑主机背后三排针脚的那个接口就是(实际对应连接电脑屏幕线)。

3、串口通信只使用TX、RX、GND的情况下,一般就是异步串行通信了,因为没有使用时钟线将通信双方进行连接,构不成同步通信,这也就是为什么异步情况下必须规定好两端波特率要一致的缘故了。

4、串口通信配置步骤:

1)使能端口和串口时钟:

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

2)设置引脚复用映射:GPIO_PinAFConfig();

3)初始化端口和串口参数:GPIO_Init();  USART_Init();

4)使能串口和串口中断:USART_Cmd();  USART_ITConfig();

备注:初始化过程中一般还会对串口中断标志清除一下,避免以前使用过程产生串口中断将标志位置位带来的影响

使用USART_ClearFlag()或者USART_ClearITPendingBit(),前者用在开启中断之前进行标志位清除,后者则是在开启了中断使能以后进行清除

5)设置串口中断优先级:NVIC_Init();

6)编写串口中断服务程序:

5、串口通信编程步骤:

1)添加库函数底层串口驱动源文件stm32f4xx_usart.c,点击编译,使头文件自动添至工程中(这一步工作能有效避免编写过程中想要右键go to definition了但跳转不过去的问题):

 

2)新建用户串口驱动源文件usart.c和头文件usart.h,保存至公用文件夹Public(因为封装好的GPIO位带操作system.c、封装好的延时函数SysTick.c、还有目前的串口,是不同项目、不同工程都需要使用到的东西,所以不放到用户驱动文件夹App中),这里为了操作方便就没有再建子文件夹:

 

3)点击左上角品字图标,将usart.c添加到工程中:

 

4)点击左上角魔术棒,将usart.h包含到工程头文件路径中:

 

5)在usart.h中编写防止重复包含格式(格式来源参考任意一个库函数底层驱动文件,譬如stm32f4xx_gpio.h),因为stm32f4xx.h基本都会用到,所以也要包含进来:

 

 

6)在usart.c中包含usart.h:

 

7)在main.c中将usart.h包含进来,到这里完成工程框架搭建,然后点击编译:

 

8)按“4、串口通信配置步骤:”中的内容执行,以下提示关键要点:

8-1)将配置步骤记住、背下来,这一步很重要。

8-2)使用函数需要知道参数,但不知道有什么可选项,右键该函数点击go to definition,然后查看断言内容,譬如:assert_param(IS_RCC_AHB1_CLOCK_PERIPH(RCC_AHB1Periph)); 

  其中assert_param()就是断言机制,主要用来检查传入参数的合法性。但我们编程主要是使用IS_RCC_AHB1_CLOCK_PERIPH()这一项,一般规律是:在IS_XXX_XXX()上右键继续go to definition,然后就能看到对应参数的可选项了,这个技巧是经常使用到的。

   学到以上基本操作之后,你会发现有时候函数的确有这个参数,但是当你跳到函数里头去会发现没有参数的断言,如此一来不就没有参数可选项入口了吗?所以你需要做的就是,在往后的编程过程中积累这种不常见例子,然后把你最终是如何找到参数可选项的步骤背下来,下面我也举一些示例:

示例一:GPIO_Init()函数的结构体GPIO_InitStruct中,你会发现其它成员GPIO_Pin、GPIO_Mode、GPIO_PuPd的断言内容都排列在函数一开始的地方,而GPIO_Speed、GPIO_OType两个成员均分布在程序内部(一个在228行,另一个在235行),所以你要做的就是:总结这种异常规律然后记下来背住。

 示例二:再来一个更极端一些的规律,像下面的NVIC_Init()函数,你追进去看它的NVIC_InitTypeDef,发现其实有四个成员,但是在函数断言内容中,只交待了三个成员的参数入口,剩下的一个NVIC_IRQChannel成员看遍整个函数也找不到断言内容,那这时候怎么办?我找到的规律是:在这种情况下啊,你就要去看注释,譬如下面第二张图,它在这个NVIC_IRQChannel成员旁边的注释着这个参数的可选项需要你去stm32f4xx.h头文件中去找。

8-3)定义结构体变量问题:一般的做法都是先在第一行将GPIO_InitTypeDef GPIO_InitStructure写出来,但问题是,像GPIO端口这种我们比较熟悉的就知道应该写GPIO_InitTypeDef类型的,但在遇到使用其它陌生的新函数时,我们根本不知道这个结构体类型怎么写,那怎么办?按我的实践来说,首先要做的往往不是在开头部分写结构体变量定义,而是先将需要用到的函数搬出来,譬如GPIO_Init(),暂时不填没关系,我们拿它出来放这,然后右键go to definition,查看到传进函数的结构体类型是什么了,我们再返回需要编程的第一行把结构体变量定义出来,如果需要查看这个结构体变量内部都有什么成员,我们再使用上面“8-2)”的办法通过go to definition继续追进去。将这个基本过程描述出来,一是为了减少编程的突兀感,二是增强编程时的应变能力(特别是视频教程,别人就知道应该这么写、第一句话应该写这个,但是原因他们很少会交待出来,因为他们都用惯了已经习以为常了,所以这一次你记住了他教你第一行应该首先写这个,但是别的地方需要换一个函数了,你就不知道应该怎么办了)。

 8-4)关于引脚复用,判断的标准就是:当你不再使用该引脚作为普通IO口了,而是需要使用它的第二/第三/第四/.../第N功能定义就应该配置成引脚复用(能够被复用成什么功能需要按上述形式查看原理图引脚内容)。和普通的IO口初始化过程的区别在于,需要调用GPIO_PinAFConfig()将引脚设置成你想要的第N功能,并且在初始化端口结构体时,需要选择为复用引脚而不是普通引脚。

 8-5)总线挂接以及时钟使能问题:一开始上手几乎都是记不清楚你即将要使用的外设挂接在哪个总线上的,那这个怎么办?记不住时最好的办法是,把stm32f4xx_rcc.h打开,直接在宏定义RCC_AHB1Periph_xxx、RCC_AHB2Periph_xxx、RCC_APB1Periph_xxx、RCC_APB2Periph_xxx中去找你外设xxx对应的总线,对应的总线知道了,后面该调用哪个时钟使能函数也就跟着出来了。

 

猜你喜欢

转载自www.cnblogs.com/weizhunie/p/12354473.html