STM32F103RCT6开发板M3单片机教程07-TIMER1CH1输出 PWM做LED呼吸灯

本文主要是介绍STM32F103RCT6开发板M3单片机教程07-TIMER1CH1输出 PWM做LED呼吸灯,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概述

本教程使用是(光明谷SUN_STM32mini开发板
 



免费开发板
 

在谷动谷力社区注册用户,打卡,发帖求助都可以获取积分,当然最主要是发原创应用文档奖励更多积分.
(可用积分换取,真的不用钱,开发板免费玩):STM32F103RCT6开发板M3单片机核芯小系统板学习板 ...
已经购买用的,可以注册用户,打卡,发帖求助都可以获取积分,当然最主要是发原创应用文档奖励更多积分.用积分换钱,返还您的买开发板钱
详细参阅
[推荐]STM32F103RCT6开发板M3单片机最小系统板学习板 带USB JTAG...

 
资料下载
STM32F103RCT6_SDK开发资料应用手册下载


书接上回:
上回我们用Timer2做了一个定时中断,让LED灯闪烁(STM32F103RCT6开发板M3单片机教程06--定时器中断 .. )

这回我们用Timer1的CH1 输出PWM做呼吸灯参看原理图(详细到 STM32F103RCT6_SDK开发资料应用手册下载
 


程序设计

何为呼吸灯?

慢慢变亮又慢慢变暗到灭,如此往复循环灯为呼吸灯也。

硬件解读

上回书得知PA8连接LED阴极,低电平点亮。
参考STM32F103RCT6数据手册, 发现PA8是Timer1的CH1,可以输出PWM
 



上回有云:
大容量的STM32F103xx增强型系列产品包含最多2个高级控制定时器、 4个普通定时器和2个基本定时器,以及2个看门狗定时器和1个系统嘀嗒定时器。
下表比较了高级控制定时器、普通定时器和基本定时器的功能:
 

高级控制定时器(TIM1和TIM8)

两个高级控制定时器(TIM1TIM8)可以被看成是分配到6个通道的三相PWM发生器,它具有带死区插入的互补PWM输出,还可以被当成完整的通用定时器。四个独立的通道可以用于:
● 输入捕获
● 输出比较
● 产生PWM(边缘或中心对齐模式)
● 单脉冲输出
配置为16位标准定时器时,它与TIMx定时器具有相同的功能。配置为16PWM发生器时,它具有全调制能力(0~100%)
在调试模式下,计数器可以被冻结,同时PWM输出被禁止,从而切断由这些输出所控制的开关。
很多功能都与标准的TIM定时器相同,内部结构也相同,因此高级控制定时器可以通过定时器链接功能与TIM定时器协同操作,提供同步或事件链接功能。


程序流程

1、系统初始化(RCC, GPIO)
2、设定初始LED亮度为0,亮度递增
3、高度到100%(全亮时),亮度递减
返回第2步



开发码码

复制上节的工程源,更改文件夹名
 

GPIO配置--PWM输出模式

修改BSP下Led.c, LED_GPIO_Config函数
更改主GPIO输出模式
原://        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        //设置引脚工作模式为通用推挽输出
改:GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     //PWMout

/*******************************************************************************
* 函数名  : LED_GPIO_Config
* 描述    : LED IO配置
* 输入    : 无
* 输出    : 无
* 返回    : 无
* 说明    : LED(1~4)的IO口分别是:PB5,PB6,PB7,PB8
*******************************************************************************/
void LED_GPIO_Config(void)
{GPIO_InitTypeDef  GPIO_InitStructure;                                //定义一个GPIO_InitTypeDef类型的GPIO初始化结构体RCC_APB2PeriphClockCmd(LED_RCC, ENABLE);                        //使能GPIOB的外设时钟        GPIO_InitStructure.GPIO_Pin = LED_ALL;                                //选择要初始化的GPIOB引脚(PA5,PA6,PA7,PA8)GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     //PWMout
//        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        //设置引脚工作模式为通用推挽输出                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //设置引脚输出最大速率为50MHzGPIO_Init(LED_PORT, &GPIO_InitStructure);                        //调用库函数中的GPIO初始化函数,初始化GPIOB中的PA5,PA6,PA7,PA8引脚LED_ALL_OFF();                                                                                //关闭ALL_LED                                          
}


定时器配置--PWM模式

修改main.c,  原Timer2定时函数, 修改通用Timer_Init_Config定时中断配置函数(这个也可以不修改不影响功能,为了让源码更接近实际项目代码,提高代码可用性,可移植性,所以这样修改)一般来说TimerPeriod越大越好越定时越精确,但不能超过16bits 最大数65535。

/*******************************************************************************
* 函数名  : Timer_Init_Config
* 描述    : Timer初始化配置
* 输入    : TIM_TypeDef* TIMx 定时器名 TIM1~8uint16_t fre_hz 定时器 中断 频率
* 输出    : 无
* 返回    : 无
* 说明    : 无
*******************************************************************************/
void Timer_Init_Config(TIM_TypeDef* TIMx, uint16_t fre_hz)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;uint16_t TimerPeriod = 0;uint16_t TimerPrescaler = 71; //1Mhz Timer Conter frequency/* Compute the value to be set in ARR regiter to generate signal frequency at Fre_hz */TimerPeriod = (SystemCoreClock / fre_hz /( TimerPrescaler +1)) - 1;TIM_TimeBaseStructure.TIM_Period = TimerPeriod; //4999;                                        //设置在下一个更新事件装入活动的自动重装载寄存器周期的值(计数到5000为500ms)TIM_TimeBaseStructure.TIM_Prescaler = TimerPrescaler; //7199;                                        //设置用来作为TIMx时钟频率除数的预分频值(10KHz的计数频率) 71TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;                //设置时钟分割:TDTS = TIM_CKD_DIV1TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;        //TIM向上计数模式TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);                                //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位/*中断优先级NVIC设置*/NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;                                //TIM2中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;        //先占优先级1级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;                        //从优先级1级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                //使能IRQ通道NVIC_Init(&NVIC_InitStructure);                                                         //初始化NVIC寄存器TIM_ITConfig(TIMx, TIM_IT_Update, ENABLE );                                 //使能TIMx指定的中断TIM_Cmd(TIMx, ENABLE);                                                                          //使能TIMx外设
}         



修改main函数

/*******************************************************************************
* 函数名  : main
* 描述    : 主函数,用户程序从main函数开始运行
* 输入    : 无
* 输出    : 无
* 返回值  : int:返回值为一个16位整形数
* 说明    : 无
*******************************************************************************/
int main(void)
{u8 keyVal;RCC_Configuration();SysTick_Init_Config();USART1_Init_Config(115200);//USART1初始化配置LED_GPIO_Config();Key_GPIO_Config();printf ("*===================================================*\n");printf ("*  *  Name: Sun STM32 mini Demo Code.    *************\n");printf ("*  * (C) Sunshine Silicon Corporation    *************\n");printf ("*  *  Website: http://www.sunsili.com    *************\n");printf ("*  *   E-Mail : fan@sunsili.com          *************\n");printf ("*===================================================*\n");printf ("* Sun STM32 mini PWM  Demo code .*\n");lum = 0;    //Start luminance 0flag = 1;   //Up count inTimer_Ch1_pwm_init(TIM1, 10000, lum);Timer_Init_Config(TIM2, 100);        //Timer2初始化配置 100Hz 中断频率 10ms中断一次while (1){if(tim2_tick){tim2_tick = 0;if(flag){if(++lum >= 100){flag = 0;    //Down count in}
//               LED4_ON();}else{               if(!lum){flag = 1;}else{lum--;}
//                LED4_OFF();}TIM_OC1_set_Pulse(TIM1, 10000, 100-lum);}
}


增加:

/*******************************************************************************
* 函数名  : Timer_Ch1_pwminit
* 描述    : 定时器 Ch1 pwm 初始化
* 输入    : TIM_TypeDef* TIMx  定时器名 TIM1~8uint16_t fre_hz PWM 频率uint16_t dty 占空比 0-100
* 输出    : 无
* 返回    : 无
* 说明    : 无
*******************************************************************************/
void Timer_Ch1_pwm_init(TIM_TypeDef* TIMx, uint16_t fre_hz, uint16_t dty)
{TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;TIM_OCInitTypeDef  TIM_OCInitStructure;uint16_t TimerPeriod = 0;uint16_t Channel1Pulse = 0;/* TIM1 Configuration ---------------------------------------------------Generate 7 PWM signals with 4 different duty cycles:TIM1CLK = SystemCoreClock, Prescaler = 0, TIM1 counter clock = SystemCoreClockSystemCoreClock is set to 72 MHz for Low-density, Medium-density, High-densityand Connectivity line devices and to 24 MHz for Low-Density Value line andMedium-Density Value line devicesThe objective is to generate 7 PWM signal at 17.57 KHz:- TIM1_Period = (SystemCoreClock / 17570) - 1The channel 1 and channel 1N duty cycle is set to 50%The channel 2 and channel 2N duty cycle is set to 37.5%The channel 3 and channel 3N duty cycle is set to 25%The channel 4 duty cycle is set to 12.5%The Timer pulse is calculated as follows:- ChannelxPulse = DutyCycle * (TIM1_Period - 1) / 100----------------------------------------------------------------------- *//* Compute the value to be set in ARR regiter to generate signal frequency at Fre_hz */TimerPeriod = (SystemCoreClock / fre_hz ) - 1;/* Compute CCR1 value to generate a duty cycle at duty for channel 1 and 1N */Channel1Pulse = (uint16_t) (((uint32_t) dty * (TimerPeriod - 1)) / 100);/* Compute CCR2 value to generate a duty cycle at 37.5%  for channel 2 and 2N */
//  Channel2Pulse = (uint16_t) (((uint32_t) 375 * (TimerPeriod - 1)) / 1000);/* Compute CCR3 value to generate a duty cycle at 25%  for channel 3 and 3N */
//  Channel3Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100);/* Compute CCR4 value to generate a duty cycle at 12.5%  for channel 4 */
//  Channel4Pulse = (uint16_t) (((uint32_t) 125 * (TimerPeriod- 1)) / 1000);/* Time Base configuration */TIM_TimeBaseStructure.TIM_Prescaler = 0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseStructure.TIM_Period = TimerPeriod;TIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);/* Channel 1, 2,3 and 4 Configuration in PWM mode */TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;TIM_OCInitStructure.TIM_Pulse = Channel1Pulse;TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;TIM_OC1Init(TIMx, &TIM_OCInitStructure);/* TIM1 counter enable */TIM_Cmd(TIMx, ENABLE);/* TIM1 Main Output Enable */TIM_CtrlPWMOutputs(TIMx, ENABLE);}/*******************************************************************************
* 函数名  : TIM_OC1_set_Pulse
* 描述    : 定时器 Ch1 pwm 脉冲相关设置
* 输入    : TIM_TypeDef* TIMx  定时器名 TIM1~8uint16_t prd  PWD周期uint16_t dty 占空比 0-100
* 输出    : 无
* 返回    : 无
* 说明    : 无
*******************************************************************************/
void TIM_OC1_set_Pulse(TIM_TypeDef* TIMx, uint16_t fre_hz, uint16_t dty)
{uint16_t Channel1Pulse = 0;uint16_t TimerPeriod = 0;/* Compute the value to be set in ARR regiter to generate signal frequency at Fre_hz */TimerPeriod = (SystemCoreClock / fre_hz ) - 1;/* Compute CCR1 value to generate a duty cycle at duty for channel 1 and 1N */Channel1Pulse = (uint16_t) (((uint32_t) dty * (TimerPeriod - 1)) / 100);/* Set the Capture Compare Register value */TIMx->CCR1 = Channel1Pulse;
}


修改:RCC_Configuration函数

/*******************************************************************************
* 函数名  : RCC_Configuration
* 描述    : 设置系统时钟为72MHZ(这个可以根据需要改)
* 输入    : 无
* 输出    : 无
* 返回值  : 无
* 说明    : STM32F107x和STM32F105x系列MCU与STM32F103x系列MCU时钟配置有所不同
*******************************************************************************/
void RCC_Configuration(void)
{ErrorStatus HSEStartUpStatus;               //外部高速时钟(HSE)的工作状态变量RCC_DeInit();                               //将所有与时钟相关的寄存器设置为默认值RCC_HSEConfig(RCC_HSE_ON);                  //启动外部高速时钟HSEHSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部高速时钟(HSE)稳定if(SUCCESS == HSEStartUpStatus)             //如果外部高速时钟已经稳定{/* Enable Prefetch Buffer */FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Flash设置/* Flash 2 wait state */FLASH_SetLatency(FLASH_Latency_2);RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置AHB时钟等于系统时钟(1分频)/72MHZRCC_PCLK2Config(RCC_HCLK_Div1);  //设置APB2时钟和HCLK时钟相等/72MHz(最大为72MHz)RCC_PCLK1Config(RCC_HCLK_Div2);  //设置APB1时钟是HCLK时钟的2分频/36MHz(最大为36MHz)RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //PLLCLK = 8MHz * 9 = 72 MHzRCC_PLLCmd(ENABLE); //使能PLLwhile(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //等待PLL稳定RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);          //设置系统时钟的时钟源为PLLwhile(RCC_GetSYSCLKSource() != 0x08);               //检查系统的时钟源是否是PLLRCC_ClockSecuritySystemCmd(ENABLE);                 //使能系统安全时钟/* TIM1 GPIOx clock enable */RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE);/* TIM2 clock enable */RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);}
}

编译调试

编译


保存全部,编译, 下载。

调试

点运行后,观察运行结果 
运行结果:

串口打印日志信息

 慢慢变亮又慢慢变暗到灭,如此往复循环灯为呼吸灯也。

这篇关于STM32F103RCT6开发板M3单片机教程07-TIMER1CH1输出 PWM做LED呼吸灯的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/599678

相关文章

电脑提示d3dx11_43.dll缺失怎么办? DLL文件丢失的多种修复教程

《电脑提示d3dx11_43.dll缺失怎么办?DLL文件丢失的多种修复教程》在使用电脑玩游戏或运行某些图形处理软件时,有时会遇到系统提示“d3dx11_43.dll缺失”的错误,下面我们就来分享超... 在计算机使用过程中,我们可能会遇到一些错误提示,其中之一就是缺失某个dll文件。其中,d3dx11_4

Linux下在线安装启动VNC教程

《Linux下在线安装启动VNC教程》本文指导在CentOS7上在线安装VNC,包含安装、配置密码、启动/停止、清理重启步骤及注意事项,强调需安装VNC桌面以避免黑屏,并解决端口冲突和目录权限问题... 目录描述安装VNC安装 VNC 桌面可能遇到的问题总结描js述linux中的VNC就类似于Window

Go语言编译环境设置教程

《Go语言编译环境设置教程》Go语言支持高并发(goroutine)、自动垃圾回收,编译为跨平台二进制文件,云原生兼容且社区活跃,开发便捷,内置测试与vet工具辅助检测错误,依赖模块化管理,提升开发效... 目录Go语言优势下载 Go  配置编译环境配置 GOPROXYIDE 设置(VS Code)一些基本

Windows环境下解决Matplotlib中文字体显示问题的详细教程

《Windows环境下解决Matplotlib中文字体显示问题的详细教程》本文详细介绍了在Windows下解决Matplotlib中文显示问题的方法,包括安装字体、更新缓存、配置文件设置及编码調整,并... 目录引言问题分析解决方案详解1. 检查系统已安装字体2. 手动添加中文字体(以SimHei为例)步骤

Java JDK1.8 安装和环境配置教程详解

《JavaJDK1.8安装和环境配置教程详解》文章简要介绍了JDK1.8的安装流程,包括官网下载对应系统版本、安装时选择非系统盘路径、配置JAVA_HOME、CLASSPATH和Path环境变量,... 目录1.下载JDK2.安装JDK3.配置环境变量4.检验JDK官网下载地址:Java Downloads

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

在Linux中改变echo输出颜色的实现方法

《在Linux中改变echo输出颜色的实现方法》在Linux系统的命令行环境下,为了使输出信息更加清晰、突出,便于用户快速识别和区分不同类型的信息,常常需要改变echo命令的输出颜色,所以本文给大家介... 目python录在linux中改变echo输出颜色的方法技术背景实现步骤使用ANSI转义码使用tpu

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实

Java Web实现类似Excel表格锁定功能实战教程

《JavaWeb实现类似Excel表格锁定功能实战教程》本文将详细介绍通过创建特定div元素并利用CSS布局和JavaScript事件监听来实现类似Excel的锁定行和列效果的方法,感兴趣的朋友跟随... 目录1. 模拟Excel表格锁定功能2. 创建3个div元素实现表格锁定2.1 div元素布局设计2.

SpringBoot连接Redis集群教程

《SpringBoot连接Redis集群教程》:本文主要介绍SpringBoot连接Redis集群教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 依赖2. 修改配置文件3. 创建RedisClusterConfig4. 测试总结1. 依赖 <de