STM32学习笔记之呼吸灯实验

STM32呼吸灯实验(寄存器版本)

在继定时器中断之后,开始PWM的学习,
脉冲宽度调制(PWM),是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。
以下就是原子的PWM的原理图

PWM原理图
图中,我们假定定时器工作在向上计数PWM模式,且当CNT<CCRx时,输出0,当CNT>=CCRx时输出1。那么就可以得到如上的PWM示意图:当CNT值小于CCRx的时候,IO输出低电平(0),当CNT值大于等于CCRx的时候,IO输出高电平(1),当CNT达到ARR值的时候,重新归零,然后重新向上计数,依次循环。改变CCRx的值,就可以改变PWM输出的占空比,改变ARR的值,就可以改变PWM输出的频率,这就是PWM输出的原理。 STM32的定时器除了TIM6和7。其他的定时器都可以用来产生PWM输出。其中高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出。而通用定时器也能同时产生多达4路的PWM输出。(选自《不完全手册》)

废话不多说直接说代码:

我是外接了一个LED灯进行呼吸灯的实验。

首先是捕获/比较模式寄存器(TIMx_CCMR1/2),该寄存器总共有2个,TIMx _CCMR1和TIMx _CCMR2。TIMx_CCMR1控制CH1和2,而TIMx_CCMR2控制CH3和4。
在这里插入图片描述
图1
在这里插入图片描述
图2

在这里,我们用的是[PB1]的io口,同时采用TIM3定时器。
.在这里插入图片描述.图3
注意这里是TIM3_CH4,所以我们在配置CCMR时采用的是上图2中黄色笔标记的位。捕获比较的都是4通道,具体配置查看中文参考手册14.4

在这里插入图片描述
我们在这里设置PWM1模式

代码如下:.

	TIM3->CCMR2|=6<<12;  	//CH4 PWM2模式		 
	TIM3->CCMR2|=1<<11; 	//CH4预装载使能	 
	

关键配置就是以上操作:具体步骤查看具体代码:(一定要注意注释!!!!!)

time.h

#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"

#define LED0_PWM_VAL TIM3->CCR4  //注意:我们要捕获的是4通道
 
void TIM3_Int_Init(u16 arr,u16 psc);
void TIM3_PWM_Init(u16 arr,u16 psc);
#endif

time.c

#include "timer.h"
#include "led.h"

//TIM3_CH1 PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM3_PWM_Init(u16 arr,u16 psc)
{		 					 
	//此部分需手动修改IO口设置
	RCC->APB1ENR|=1<<1; 	//TIM3时钟使能    
	GPIOB->CRL&=0XFFFFFF0F;	//PB1清除之前的设置
	GPIOB->CRL|=0X000000B0;	//复用功能输出 
	
	TIM3->ARR=arr;			//设定计数器自动重装值 
	TIM3->PSC=psc;			//预分频器设置
  
	TIM3->CCMR2|=6<<12;  	//CH4 PWM2模式		 
	TIM3->CCMR2|=1<<11; 	//CH4预装载使能	 
 	TIM3->CCER|=1<<12;   	//OC4 输出使能	   
	//TIM1->BDTR|=1<<15;   	//MOE 主输出使能	   

	TIM3->CR1=0x0080;   	//ARPE使能 
	TIM3->CR1|=0x01;    	//使能定时器3 										  
}  


led.c

#include "sys.h"   
#include "led.h"

void LED_Init(void)
{
	RCC->APB2ENR|=1<<3;
	GPIOB->CRL&=0XFFFFFF0F;
	GPIOB->CRL|=0x00000030;
	
	GPIOB->ODR|=1<<1;//PB1
}


main.c

#include "sys.h"
#include "usart.h"		
#include "delay.h"	
#include "led.h"   
#include "timer.h" 


int main(void)
{			
 	u16 led0pwmval=0;    
	u8 dir=1;	
	Stm32_Clock_Init(9); //系统时钟设置
	delay_init(72);	     //延时初始化
	uart_init(72,9600);  //串口初始化 
	LED_Init();		  	 //初始化与LED连接的硬件接口
	TIM3_PWM_Init(899,0);//不分频。PWM频率=72000/(899+1)=80Khz 
   	while(1)
	{
 		//delay_ms(10);	 
		if(dir)led0pwmval++;
		else led0pwmval--;	 
 		if(led0pwmval>300)dir=0;
		if(led0pwmval==0)dir=1;	   					 
		LED0_PWM_VAL=led0pwmval;
		//printf("%d\r\n",LED0_PWM_VAL);
	} 
}


这样代码就完成了!
在这里插入图片描述

在这里插入图片描述
较暗

在这里插入图片描述

OK!今天笔记记于此结束!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值