本文对正点原子STM32F4探索者的基本功能及外设作最基本的介绍,随笔者本人的学习进程(基本按照正点原子)而不定时更新,起到总结的作用。


一、HAL库编写程序的运行逻辑

  HAL库函数(如stm32f4xx_hal_dma.c/.h):提供最基本的初始化函数和一些基本寄存器操作。

  库函数(如led.c.h、dma.c.h):在HAL库之上,需要由用户编写的库函数进行时钟使能和端口配置。大部分情况下,中断函数也要写到用户的库函数里。

  在main.c函数里:while(1)之外主要写一些Init()函数(如HAL_Init、LED_Init等)启用一些外设的功能,while(1)之内主要实现对外部相应的及时控制(如串口输入了一个字符串、外部有按键输入、触摸屏输入等)


二、LED灯

  位于PF9PF10两个端口。

1.led_init();

  使能

2.void HAL_GPIO_WritePin (GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,GPIO_PinState PinState);

  用于设置引脚输出高电平或者低电平

3.void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);

  用于设置引脚的电平翻转

如何使用:把led.c放入路径中,在main函数里,while前声明led_init()。

用途:可以来判断系统是否正常运行。


三、蜂鸣器

  位于PF8

1.beep_init();

  使能:BEEP(0)停止蜂鸣/BEEP(1)开始蜂鸣

2.BEEP_TOGGLE();

  状态反转

如何使用:把beep.c放入路径中,在main函数里,while前声明beep_init()。

用途:没啥用。


四、按键输入

  KEY0:PE4

  KEY1:PE3

  KEY2:PE2

  KEY_UP:PA0

1.key_init();

  按键初始化

2.key_scan();

  按键扫描函数

如何使用:把key.c放入路径中,在main函数里,while前声明key_init()。

在while(1)中使用key=key_scan(0)

用途:可以当作四个外部信号输入。比如检测到某按键按下之后,执行特定的功能。


五、外部中断

NVIC:暂略

EXTI:外部中断和事件控制器

  EXTI 的两大部分功能,产生中断产生事件

1.产生中断

  最终信号是流入 NVIC 控制器中。输入线是线路的信息输入端,它可以通过配置寄存器设置为任何一个 GPIO 口,或者是一些外设的事件。输入线一般都是存在电平变化的信号。(如按键按下,串口输入等等)。

2.产生事件

  产生中断线路目的使把输入信号输入到 NVIC,进一步运行中断服务函数,实现功能。

 而产生事件线路目的是传输一个脉冲信号给其他外设使用,属于硬件级功能。

  每个中断线对应了最多 7 个 IO 口,以线 0 为例:它对应了 GPIOA.0、GPIOB.0---GPIOF.0 和 GPIOG.0(如KEY0对应PE4,那么应设置线4的中断)。

  HAL 库的 EXTI 外部中断的设置功能整合到 HAL_GPIO_Init 函数里面,而不是单独独立一个文件。

3.中断的使用:(exti.c)

1)exitx_init()外部中断初始化

(1).端口使能:

  与正常使能有区别的地方在于

gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;

  GPIO_MODE_IT_RISING:上升沿触发

  GPIO_MODE_IT_FALLING:下降沿触发

  GPIO_MODE_IT_RISING_FALLING:上升沿和下降沿都能触发

(2).使能之后,还要配置NIVIC优先级和使能中断线

void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority,uint32_t SubPriority);

  设置中断的抢占优先级和响应优先级(子优先级)。

  形参 1 是中断号,可以选择范围:IRQn_Type 定义的枚举类型,定义在stm32f407xx.h。与exti有关的IRQN有:

  EXTI0_IRQn、EXTI1_IRQn、EXTI2_IRQn、EXTI3_IRQn、EXTI4_IRQn、EXTI9_5_IRQn和EXTI15_10_IRQn。

  其中,5-9共用一个,10-15共用一个。

  形参 2 是抢占优先级,可以选择范围:0 到 15。抢占>响应

  形参 3 是响应优先级,可以选择范围:0 到 15。

void HAL_NVIC_EnableIRQ(IRQn_Type IRQn);

  使能中断线,形参同上

void HAL_NVIC_DisableIRQ(IRQn_Type IRQn);

  用于中断除能。例程中没有用到,还是写在这里

2)写在初始化函数之外

(1).

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)



  包含中断标志位清除和调用回调函数

__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin)

  中断标志位清除

(2).void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

  中断服务程序中需要做的事情,在HAL库中所有的外部中断服务函数都会调用此函数。内部可以使用switch来控制对不同的中断作出反应。

3)使用方法

  把exti.c放入路径中,在main函数里,while前声明extix_init()。


六、串口通信(USART1)

串口USART1:

发送引脚TX:PA9

接收引脚RX:PA10

  正点原子将PA9和PA10通过USB转串口芯片CH340C实现与电脑通讯。

使用方法

  把usart.c放入路径中,在main函数里,while前声明usart_init(115200)。使用正点原子提供的串口通信助手就可以进行通信。

  其他的通信方式放到之后再介绍,目前重点是如何对接收到的数据进行处理。

usart.c:

1.printf()

向上位机发送字符串

2.g_usart_rx_buf

从上位机接收到的消息,是一个数组


七、独立看门狗(IWDG)

  本质上是一个定时器,并且有一个输出端,可以产生复位信号。在计数器没减到0之前重置计数器的值,就不会产生复位信号,即“喂狗”。

  为了防止程序受到不可控因素干扰,维护系统的稳定性。

复位信号:相当于重启系统(复位信号触发会造成什么?)

驱动代码:stm32f4xx_hal_iwdg.c

驱动源码:wdg.c/.h

看门狗溢出时间:

Tout=((4×2^prer) ×rlr) /32

prer 为看门狗时钟预分频值,范围为 0~7。

rlr 为看门狗的重装载值。

  比如我们设定 prer 值为 4(4 代表的是 64 分频,HAL 库中可以使用宏定义标识符IWDG_PRESCALER_64),rlr 值为 500,那么就可以得到 Tout=64×500/32=1000ms,这样,看门狗的溢出时间就是 1s,只要你在一秒钟之内,有一次写入 0xAAAA 到 IWDG_KR,就不会导致看门狗复位(当然写入多次也是可以的)。

iwdg_init(prer,rlr)

看门狗初始化

iwdg_feed()

喂狗函数

使用方法:把wdg.c放入路径中。在主函数里,while前声明iwdg.init(),并设置喂狗函数触发条件。

窗口门狗(WWDG)

  通常被用来检测由外部干扰或者不可预见的逻辑条件造成的应用程序背离正常运行序列而产生的软件故障。

驱动代码:stm32f4xx_hal_wwdg.c

驱动源码:wdg.c/.h

窗口门狗溢出时间:TWWDG = TPCLK1×4096×2^WDGTB×(T[5:0] + 1)

上限时间和下限时间:

  调用 wwdg_init(0X7F,0X5F,WWDG_PRESCALER_8)这个语句,就设置计数器值为 0x7F,窗口寄存器为 0x5F,分频数为 8,然后可由前面的公式得到窗口上限时间 Twwdg=4096×8×(0x7F-0x5F)/42MHz=24.98ms,窗口下限时间 Twwdg=4096×8×(0x7F-0x3F)/42MHz=49.97ms,即喂狗的窗口区间为 24.98~49.97ms。

void wwdg_init(uint8_t tr, uint8_t wr, uint32_t fprer)

tr:计数器值 wr:窗口值 fprer:分频系数

使用方法:把wdg.c放入路径中。在主函数里,while前声明wwdg.init(),设置窗口上限(下限无法设置!),并设置喂狗函数触发后要执行的任务。


八、基本定时器

  STM32F407有两个基本定时器TIM6和TIM7,功能完全相同,可以同时使用。

  触发DAC的同步电路,以及生成中断/DMA请求

  定时器属于STM32F407的内部资源,只要软件设置好即可正常工作。

驱动代码:stm32f4xx_hal_tim.c和stm32f4xx_hal_ex.c

驱动源码:btim.c/.h

void btim_timx_int_init(uint16_t arr, uint16_t psc)

定时器时间周期:Tout= ((arr+1)(psc+1))/Tclk

btim_timx_int_init(5000 - 1, 8400 - 1):

Tout = ((4999+1)
(8399+1))/84000000 = 0.5s = 500ms

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)

设置中断优先级,使能中断

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

回调函数,在里面设置要执行的任务

如何使用:把btim.c添加到路径,然后再主函数里,while前使用btim_timx_int_init(),适当选择arr和psc设置定时器时间周期,在回调函数中设置要执行的任务。

是先执行完中断再计时,还是执行中断的同时进行计时?


九、通用定时器

10个:TIM2-TIM5,TIM9-TIM14,彼此独立

  利用定时器进行输入捕获:测量输入信号的脉冲宽度、测量PWM输入信号的频率和占空比等。(很有用!)

  基本定时器只能是递增计数模式,通用定时器可以递增计数模式、递减计数模式和中心对齐模式

驱动源码:gtim.c/.h

(一)、通用定时器中断

  定时器的计数器值是可以读取的

void gtim_timx_int_init(uint16_t arr, uint16_t psc)

通用定时器定时中断初始化

void GTIM_TIMX_INT_IRQHandler(void)

定时器中断服务函数

(二)、通用定时器PWM输出

  脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。

  在这个循环中,改变 CCRx 的值,就可以改变 PWM 的占空比,改变 ARR 的值,就可以改变 PWM 的频率

STM32F407的定时器除了TIM6和TIM7,其他的定时器都可以用来产生PWM输出,我们使用TIM3的CH2产生一路PWM输出为例

TIM14通道1:PF9复用(LED0)

HAL 库为定时器的针对 PWM 输出定义了单独的 MSP 回调函数HAL_TIM_PWM_MspInit

void gtim_timx_pwm_chy_init(uint16_t arr,uint16_t psc)

初始化函数,频率从这里调整

  对于gtim_timx_pwm_chy_init(500 - 1, 84 - 1);:

  84M/84=1M 的计数频率,自动重装载为 500,那么 PWM 频率为 1M/500=2kHz

__HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, GTIM_TIMX_PWM_CHY,ledrpwmval);

  修改比较值ledrpwmval控制占空比,实际上修改的是寄存器的CCR1

(三)、通用定时器输入捕获

  输入捕获模式可以用来测量脉冲宽度或者频率

  使用TIM5_CH1做输入捕获,捕获PA0上的高电平脉宽

  计数器计数的个数计算方法为:N(ARR+1)+ CCRx2

  N为溢出次数,CCRx2 表示 t2 时间点,捕获/比较寄存器的值

TIM5_CH1:PA0复用

void gtim_timx_cap_chy_init(uint16_t arr, uint16_t psc)

初始化

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)

定时器输入捕获中断处理回调函数

uint8_t g_timxchy_cap_sta = 0; /
输入捕获状态 / 可以看做一个寄存器

uint16_t g_timxchy_cap_val = 0; /
输入捕获值 /

最大捕获时间为63
定时器溢出时间

对于gtim_timx_cap_chy_init(0XFFFF, 84 - 1);:

  这两个形参分别设置自动重载寄存器的值为 65535,以及预分频器寄存器的值为 83。定时器 5 是 32 位的计数器,为了通用性,我们只使用 16 位,所以计数器设置为 65535。预分频系数,我们设置为 84 分频,定时器 5 的时钟频率是 2 倍的 APB1 总线时钟频率,即 84MHz,可以得到计数器的计数频率是 1MHz,即 1us计数一次,所以我们的捕获时间精度是 1us。这里可以知道定时器的溢出时间是 65536us。

  这两个参数既出现在gtim.c中,又需要在main函数中随时使用。出现这种情况有两种应对方法,一是想方法把main.c中有关该参数的的命令在gtim.c中整合成函数。另一种更简便的方法是在gtim.c中声明,并使用extern外部变量调用(写在main函数之前)

(四)、通用定时器脉冲计数实验

  外部时钟模式1的外部输入引脚只能是通道一或者通道二对应的IO,通道三或者通道四是不可以的。

定时器 2,使用 TIM2 通道 1,PA0 复用为 TIM2_CH1。

void gtim_timx_cnt_chy_init(uint16_t psc)

通用定时器TIMX通道Y脉冲计数初始化函数


STM32F407 学习 (0) 各种外设功能 (上)的更多相关文章

  1. PHP语言学习之php做图片上传功能

    本文主要向大家介绍了PHP语言学习之php做图片上传功能,通过具体的内容向大家展示,希望对大家学习php语言有所帮助. 今天来做一个图片上传功能的插件,首先做一个html文件:text.php < ...

  2. Docker技术入门与实战 第二版-学习笔记-8-网络功能network-1-单个host上的容器网络

    Docker 中的网络功能介绍 Docker 允许通过外部访问容器或容器互联的方式来提供网络服务 1) 外部访问容器 容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -p或 -P参数 ...

  3. Eviews 8.0&9.0界面新功能介绍

    Eviews 8.0&9.0界面新功能介绍 本文其中一些是自己的整理,也有一些是经管之家论坛中一位热心.好学坛友的整理,其中只是简单介绍一下这两个新版本的部分特性,分享出来,有兴趣的看客可以一 ...

  4. Docker技术入门与实战 第二版-学习笔记-8-网络功能network-3-容器访问控制和自定义网桥

    1)容器访问控制 容器的访问控制,主要通过 Linux 上的 iptables防火墙来进行管理和实现. iptables是 Linux 上默认的防火墙软件,在大部分发行版中都自带. 容器访问外部网络 ...

  5. Linux学习2-在阿里云服务器上部署禅道环境

    前言 以前出去面试总会被问到:测试环境怎么搭建?刚工作1-2年不会搭建测试环境还可以原谅自己,工作3-5年后如果还是对测试环境搭建一无所知,面试官会一脸的鄙视. 本篇以最简单的禅道环境搭建为例,学习下 ...

  6. stm32学习笔记之GPIO功能框图分析

    GPIO 是通用输入输出端口的简称,简单来说就是STM32 可控制的引脚,STM32 芯片的GPIO 引脚与外部设备连接起来,从而实现与外部通讯.控制以及数据采集的功能.STM32 芯片的GPIO被分 ...

  7. Ionic 的 ng-class 在聊天功能上面的巧妙运用

    很多人在问我是ionic好呢?还是react好呢? 其实我只想告诉你去看文档啊,不用用怎么知道哪个合适呢? 嘿嘿但是真的这么问的时候我也不会这么回答的,那岂不是太张狂了哈哈哈 react我确实没有用过 ...

  8. C# 3.0相比C# 2.0增加的功能

    1.自动属性 (1)自动属性(Auto-Implemented Properties),C#自动属性可以避免原来我们手工的来声明一个私有成员变量以及和属性get,set的书写. public clas ...

  9. Web开发者应当开始学习HTML5的新功能

    据国外媒体报道,谷歌开发者业务部门高管马克·皮尔格雷姆(Mark Pilgrim)在WWW2010会议上表示,尽管还需要进一步完善,HTML5已经获得大多数平台支持,适合完成大多数任务. 但并非所有人 ...

  10. c++学习笔记之封装篇(上)

    title: c++学习笔记之封装篇(上) date: 2017-03-12 18:59:01 tags: [c++,c,封装,类] categories: [学习,程序员,c/c++] --- 一. ...

随机推荐

  1. Idea提交文件时,添加不需要提交的文件至.gitignore文件中

    1.在Idea中,依次打开File ---->Setting ---> Editor --->File Types 2.在当前编辑栏下方找到Ignore files and fold ...

  2. 前端本地 Nginx 反向代理

    一.问题引入 本地开发遇到线上bug,debug得stash代码切换分支,同时需切换开发环境与生产环境服务,npm run serve 或 npm start 费时 二.webpack-dev-ser ...

  3. h5移动端识别二维码信息

    jsqr插件 图片跨域时不允许绘制到canvas,所以先转blob在画到canvas上面就可以,如果不跨域直接画就行 function getImageBlob (url) {             ...

  4. ORA-00972: identifier is too long异常处理

    环境:由于数据库更换,做数据同步,提示 too long 问题,导致一直无法同步完数据. 经排查 oracle 历史数据库版本: Oracle Database 12c Standard Editio ...

  5. Educational Codeforces Round 3 个人总结A-D

    Educational Codeforces Round 3 A. USB Flash Drives 降序排序后,贪心,甚至不会爆longlong void solve() { int n,m; ci ...

  6. springboot 项目启动后访问不论什么请求的是spring的注册页面Please sign in Username || springboot禁用security

    解决方法: 1.在启动类上添加注解@EnableAutoConfiguration(exclude = {SecurityAutoConfiguration.class}) 2.或者:@SpringB ...

  7. android 下载安装包更新app

    1下载 public void download(String url) { Utils.Loge("download",url); Uri uri = Uri.parse(url ...

  8. 中兴radius属性列表new.xls

    标准属性 自定义属性

  9. C# 将实体转xml/xml转实体

    xml转实体 /// <summary> /// 把xml转换成实体 /// </summary> /// <typeparam name="T"&g ...

  10. springboot使用MD5加密

    (11条消息) SpringBoot项目-密码MD5加密_springboot md5加密_wdfxfff的博客-CSDN博客 (11条消息) 创建MD5工具类_md5依赖_天天喝旺仔的博客-CSDN ...