Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
DIY综合交流区
[RealTouch例程]用定时器控制Led灯闪烁
发布于 2012-08-24 07:56:43 浏览:10431
订阅该版
实验目的 闪灯程序在嵌入式学习中犹如“Hello World!”在C/C++语言学习中一样经典。它以简单的方式引导了无数的嵌入式爱好者。通过本节的学习你可以基本了解STM32的GPIO以及基本定时器的使用。 硬件说明 本例程需要一个定时器和一个LED,其中LED就是扩展板上的红色LED接在PD3上且正极接在高电平上,定时器选用基本定时器7。 1. STM32 GPIO简介 ? GPIO主要特性 ? 输出状态可选推挽、开漏、上拉或下拉 ? 可为每个I/O选择速度 ? 输入状态可选则悬空、上拉/下拉、模拟 ? 每个I/O引脚都有复用功能 ? 可对每个输出引脚进行位操作 STM32的每个GPIO都有4个32位配置寄存器:模式选择寄存器、输出类型配置寄存器、输出速度配置寄存器、上拉/下拉电阻配置寄存器;2个32位数据寄存器:数据输入寄存器、数据输出寄存器;1个32位锁定寄存器和2个32位复用功能选择寄存器。无论你选择某个I/O作为输入还是输出,都可以给根据需求选择是否使用上拉或下拉电阻。总的来讲,每个I/O有8中模式可供选择:输入悬空、带上拉输入、来下拉输入、带上拉或下拉开漏输出、带上拉或下拉推挽输出、模拟输入、推挽且带上拉或下拉的复用功能、开漏且带上拉或下拉的复用功能。 1.1 I/O模式选择 每个I/O引脚都有4种用途模式可供选择。GPIOx_MODER(x = A..I)是一个32位寄存器,每两位配置一个引脚,位[1:0]配置引脚0以此类推。其取值及含义如表1.1所示。 表1.1 I/O用途模式设置 MODER[1:0] 描述 B00 输入模式(初始值) B01 通用输出模式 B10 复用功能模式 B11 模拟信号模式 1.2 输出类型选择 根据输出需求你可在GPIOx_OTYPER中设置推挽或开漏输出。这个寄存器只有低16位有效,取值及定义如表1.2所示。 表1.2 输出类型设置 OT[0] 描述 B0 推挽输出(初始值) B1 开漏输出 1.3 输出速度设置 表1.3 端口输出速度设置 OSPEEDER[1:0] 描述 B00 2MHZ低速 B01 25MHZ中速 B10 50MHZ快速 B11 100MHZ高速 1.4 上拉下拉电阻设置 表1.4 上拉下拉电阻设置 PUPDR[1:0] 描述 B00 无上拉或下拉电阻 B01 上拉电阻连接 B10 下拉电阻连接 B11 保留 1.5 数据输入和输出 当GPIO设置为通用输入时,读取寄存器GPI Ox_IDR)(x = A..I)可得到端口的输入状态且这个寄存器是只读的;GPIOx_ODR(x = A..I)是一个可读写寄存器,写数据到这个寄存器可控制端口输出电平,从这个寄存器读数据可判断端口的输出状态。 1.6 复用功能选择 STM32中有16种复用功能,一个引脚会对应其中几种。共有两个寄 存器GPIOx_AFRL与GPIOx_AFRH 用来设置引脚的复用功能,其中每 4位对应一个引脚。 表1.6 复用功能配置 AFR[3:0] 描述 0X1 AF1(TIM1/TIM2) 0X2 AF2(TIM3...5) 0X4 AF4(I2C1...3) 0XD AF14(DCMI) 2. STM32基本定时器简介 STM32的定时器非常强大,根据功能可分为高级控制定时器、通用定时器、基本定时,其中定时器6、7为基本定时器。在这里我们主要对基本定时器给予简单介绍。它具有一个16位自动重载加法计数器和一个16位可编程预分频器。预分频器对输入时钟进行分频,然后提供给计数器作为计数时钟使用。STM32的自动重载寄存器(TIMx_ARR)在物理上对应两个寄存器,一个是咱们可以随便读写的,另一个则只能被定时器读取。这个咱们无法操作的寄存器被称作影子寄存器。当TIMx_CR1中的ARPE位等于0时改变TIMx_ARR的值就可马上改变影子寄存器里的值。当ARPE等于1时TIMx_ARR的值被缓存起来了,只有当更新事件发生后才会将新的值传送到影子寄存器中。 操作定会器前需要先打开输入时钟,然后可设置重预分频系数寄存器(TIMx_PSC)和自动载值寄存器。因为我们要让定时器产生更新中断,因此必需使能TIMx_DIER中的UIE位以及设置NVIC相关寄存器。初始化完成后设置TIMx_CR1的CEN位即可开启定时器。 实验原理及程序结构 实验设计 利用STM32的基本定时器产生更新中断,在中断处理函数中控制LED引脚的电平,带给大家一个闪灯的效果。本例程会涉及到GPIO_D03以及基本定时器7的初始化和一个定时器7 中断服务例程等。 源程序说明 下面让我们来看看blink.c是如何实现的。 LED初始化 ```/* blink.c */ void led_init(void) { GPIO_InitTypeDef GPIO_InitStructure; /* 使能GPIOD时钟 */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); /* 配置GPIO_LED引脚 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOD, &GPIO_InitStructure); }``` LED的初始化比较简单,选择好引脚并将引脚用途模式设置为输出即可。需要注意的是STM32的每个外设的时钟都可单独控制,在操作前需要打开时钟而且要从STM32用户手册中确认清楚,你要用到的外设具体挂载在哪个总线上的(AHB1、APB1等)。 LED控制 ```/* blink.c */ void led_on(void) { /* 设置PD3为低电平 */ GPIO_ResetBits(GPIOD, GPIO_Pin_3); } void led_off(void) { /* 设置PD3为高电平 */ GPIO_SetBits(GPIOD, GPIO_Pin_3); } void led_toggle(void) { /* 切换PD3电平状态 */ GPIO_ToggleBits(GPIOD, GPIO_Pin_3); }``` 这三个LED控制函数都使用了位操作,由于LED的正极是接在高电平上的,led_on是让PD3输出低电平从而点亮LED。led_toggle将会在定时器的中断服务例程中调用,它会把引脚在高低电平之间切换达到闪灯的果。 定时器初始化 ```/* blink.c */ void TIM7_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; /* 操作定时器前先使能输入时钟 */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE); /**** Time base configuration ****/ /* 设置自动重装载周期,计数到5000为1000ms */ TIM_TimeBaseInitStruct.TIM_Period = 5000; /* 设置预分频值,即定时器计数频率为10Khz */ TIM_TimeBaseInitStruct.TIM_Prescaler =(8400-1); TIM_TimeBaseInitStruct.TIM_ClockDivision = 0; /* 向上计数模式 */ TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; /* 根据TIM_TimeBaseInitStruct中指定的参数初始化TIM7的时基单位 */ TIM_TimeBaseInit(TIM7, &TIM_TimeBaseInitStruct); /* 使能TIM7更新中断 */ TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE); /* Configure the NVIC Preemption Priority Bits */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* Enable the TIM7 global Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* 启动定时器 */ TIM_Cmd(TIM7, ENABLE); } ``` 这里使用的是最简单的基本定时器,打开输入时钟、设置预分频器和计数重载值后配置好相关中断寄存器后就可启动定时器了。在ST库代码的stm32f4xx_it.C中定义了所有中断入口,我们需要在里面添加如下代码: 定时器7中断服务例程 ```/* stm32f4xx_it.C */ void TIM7_IRQHandler(void) { if (TIM_GetITStatus(TIM7, TIM_IT_Update) != RESET) { /* 清除中断标志 */ TIM_ClearITPendingBit(TIM7, TIM_IT_Update ); /* 切换I/O状态 */ led_toggle(); } } ``` 关于闪灯的驱动部分就是这些了,详细代码请参见示例工程。 ![用定时器控制LED闪烁.pdf](/uploads/88_19985cb3e8e1df08647e87f5f565865f.pdf) ![RealTouch_blink.zip](/uploads/88_14606a0479d7d7bd1545c425021c65db.zip)
查看更多
6
个回答
默认排序
按发布时间排序
lixupeng
2013-07-02
这家伙很懒,什么也没写!
学习!
fengchao989
2013-10-07
这家伙很懒,什么也没写!
源码中有错误;(程序运行后不会按1秒钟计时) 改两个地方, 第一个是 system-STM32FXX.C 中 #define PLL_M 25 改为#define PLL_M 8 第二个 TIM_TimeBaseInitStruct.TIM_Period = 10000;
aozima
2013-10-08
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
>源码中有错误;(程序运行后不会按1秒钟计时) >改两个地方, 第一个是 system-STM32FXX.C 中 #define PLL_M 25 改为#define PLL_M 8 >第二个 TIM_TimeBaseInitStruct.TIM_Period = 10000; --- 第一个 ``` --- a/bsp/stm32f40x/Libraries/CMSIS/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c +++ b/bsp/stm32f40x/Libraries/CMSIS/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c @@ -146,7 +146,7 @@ /************************* PLL Parameters *************************************/ /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ -#define PLL_M 25 +#define PLL_M (HSE_VALUE / 1000000UL) #define PLL_N 336 /* SYSCLK = PLL_VCO / PLL_P */ ```
lujun723
2013-11-08
这家伙很懒,什么也没写!
The stm32f4xx_tim.h file states that the TIM_TimeBaseInitTypeDef structure is used with all TIMx except for TIM6 and TIM7.
qiuwei
2023-11-03
这家伙很懒,什么也没写!
控制led闪烁的时候,它不是很亮会是什么问题
撰写答案
登录
注册新账号
关注者
0
被浏览
10.4k
关于作者
shaolin
这家伙很懒,什么也没写!
提问
115
回答
444
被采纳
0
关注TA
发私信
相关问题
1
[项目]搞个开源的硬件项目
2
硬件计划贴,及时更新,欢迎提意见
3
软件计划贴,及时更新,欢迎提意见::WMA,MOUNT,LWIP等问题急需解决.
4
MMS协议
5
定点的wma解压库-libwma
6
QQ群记录 [20090821]
7
STM32网络收音机PCB报名征集
8
第一版调试记录
9
第二版硬件讨论
10
RADIO项目相关模块规格--欢迎大家自己做板时规格与此兼容,减少重复劳动
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
8
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
3
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部