PWM定时器应用实例
- 格式:docx
- 大小:16.36 KB
- 文档页数:2
PWM基本原理及其应用实例PWM基本原理及其应用实例2009-06-26 14:12:02| 分类:嵌入式技术探索| 标签:|字号大中小订阅~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~理论篇(一)原理介绍~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~PWM(Pulse Width Modulation)控制——脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形(含形状和幅值)。
PWM控制技术在逆变电路中应用最广,应用的逆变电路绝大部分是PWM型,PWM控制技术正是有赖于在逆变电路中的应用,才确定了它在电力电子技术中的重要地位。
1 PWM控制的基本原理理论基础:冲量相等而形状不同的窄脉冲加在具有惯性的环节上时,其效果基本相同。
冲量指窄脉冲的面积。
效果基本相同,是指环节的输出响应波形基本相同。
低频段非常接近,仅在高频段略有差异。
面积等效原理:分别将如图1所示的电压窄脉冲加在一阶惯性环节(R-L 电路)上,如图2a所示。
其输出电流i(t)对不同窄脉冲时的响应波形如图2b所示。
从波形可以看出,在i(t)的上升段,i(t)的形状也略有不同,但其下降段则几乎完全相同。
脉冲越窄,各i(t)响应波形的差异也越小。
如果周期性地施加上述脉冲,则响应i(t)也是周期性的。
用傅里叶级数分解后将可看出,各i(t)在低频段的特性将非常接近,仅在高频段有所不同。
用一系列等幅不等宽的脉冲来代替一个正弦半波,正弦半波N等分,看成N个相连的脉冲序列,宽度相等,但幅值不等;用矩形脉冲代替,等幅,不等宽,中点重合,面积(冲量)相等,宽度按正弦规律变化。
SPWM波形——脉冲宽度按正弦规律变化而和正弦波等效的PWM波形。
图3 用PWM波代替正弦半波要改变等效输出正弦波幅值,按同一比例改变各脉冲宽度即可。
PWM电流波:电流型逆变电路进行PWM控制,得到的就是PWM电流波。
第十四章STM8S207 PWM 模块及其应用实例上一节我们学习了定时器中的基本定时器编程,这一节学习定时器里面一个PWM模块。
当终于到了PWM 模块编程时,有些许怀念,怀念过去的一年之中的日以继夜相对的PWM。
忘了介绍我们的团队---风驰,也就是第六届飞思卡尔比赛中的一个队伍。
1、PWM 介绍脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。
简单一点,就是对脉冲宽度的控制。
PWM 在实际应用很广,例如上面提到的飞思卡尔智能车就用到PWM 控制舵机以及电机。
关于舵机是如何用PWM 控制的,这里不详细说明,有兴趣的建议查询相关知识。
这些在模型制作中应用十分广泛。
关于PWM 如果控制电机的这里略为说明,因为和本节有些许关联普通直接电机在通电时以全电压工作,在没有PWM 控制电机之前是运用继电器通过不停开断实现对电机的速度控制。
引入PWM 就可以更为灵活控制电机。
PWM 是脉冲宽度可调的方波,在10K 左右的频率下,通过不同的占空比就可以得到近似稳定的电压。
例如输入5V,占空比为50%时,电压近似 2.5V。
我们这节实验也是应用PWM 这个特性。
利用PWM 中的占空比调节LED 的亮度。
关于PWM 的说明这里也简要说明,PWM 第一个参数是PWM 的周期,也就是一个PWM 的时间。
这个可以通过对应的寄存器进行设置,而我们的STM8S207 通过PSCR 设置定时器的时钟源CK_CNT,然后再通过ARR 寄存器设置周期。
例如我们这节的实验使用了16M 内部时钟源,LED4 是接着PD3 的,也就是TIM2_CH2,PSCR只能是2 的次幂,我们选择了4 分频。
CK_CNT = 4M,然后ARR 设置为200,分频200 后直接提供PWM 的时钟,所以f_pwm = 4M/200 = 20KHz。
⼀些主从定时器相关,PWM波精确控制步进电机的笔记1、步进电机 以滚珠丝杆为例,作假设如下: ①步进电机与滚珠丝杆的减速⽐是2:1; ②丝杆转⼀圈所移动的距离是2mm; 通过上⾯的1和2,我们可以得出我们需要的东西:步进电机转1圈所对应的移动距离是1mm。
步进电机通过PWM波输⼊来控制其输出速度,步进的意思是每⼀个PWM脉冲会使电机前进/后退1步。
步进细分数就是关联脉冲与电机速度的重要参数。
这⾥假设细分数是1000步,意思就是,每1000个脉冲会使步进电机转动⼀圈,倒过来讲就是每1个PWM脉冲,会使步进电机运动0.001步,也就是转动0.001圈。
这就是我们需要的第⼆个东西,把这两个放⼀起,可以看到如下: ③步进电机转1圈所对应的移动距离是1mm; ④每1个PWM脉冲,会使步进电机运动0.001步,也就是转动0.001圈; 通过上⾯3和4,我们可以得出:每1个PWM脉冲,会使运动机构运动0.001mm。
2、定时器中断与PWM输出 我们都知道,PWM的输出是CNT和CCRx寄存器⽐较的结果,所以只要配置好PSC、ARR和CCRx,就可以确定输出PWM的频率,公式是: PWM频率 = APBx的频率/(PSC+1)*(ARR+1) 占空⽐ = CCRx/ARR * 100% 为了输出占空⽐为50%的⽅波,我们令CCRx=ARR/2。
这样就可以确定输出频率了,频率其实就是每秒的脉冲数,⽐⽅说100HZ,其代表的就是100脉冲/秒。
⽽我们在前⾯2⾥头已经知道了,在这套假设的系统中,1个脉冲对应运动机构实际运⾏0.001mm,那么1000HZ就代表,在这个频率下,运动机构的运动速度是1mm/s。
到这⾥我们就可以知道如何控制速度了,我们按1个脉冲为最⼩单位,即0.001mm/s 的速度,在不考虑失步的情况下,我们的实际速度就能从0.001mm/s到任意⼤的区间⾥⾃由选择了,其控制精度为0.001mm/s。
stm32f103通用定时器pwm应用例程--蜂鸣器演奏乐曲STM32F103通用定时器PWM应用例程:蜂鸣器演奏乐曲一(说明:本例程是将流明LM3SLib_Timer.pdf文档中的例程9及例程10(PWM应用:蜂鸣器演奏乐曲),移植到STM32F103上。
二(流明LM3SLib_Timer.pdf例程9及例程10的拷贝:例程9( Timer PWM应用:蜂鸣器发声如图1.1所示,为EasyARM1138开发板上的蜂鸣器驱动电路。
蜂鸣器类型是交流蜂鸣器,也称无源蜂鸣器,需要输入一列方波才能鸣响,发声频率等于驱动方波的频率。
图1.1 蜂鸣器驱动电路程序清单1.9是Timer模块16位PWM模式的一个应用,可以驱动交流蜂鸣器发声,运行后蜂鸣器以不同的频率叫两声。
其中"buzzer.h"和"buzzer.c"是蜂鸣器的驱动程序,仅有3个驱动函数,用起来很简捷。
程序清单1.9 Timer PWM应用:蜂鸣器发声文件:main.c#include "systemInit.h"#include "buzzer.h"// 主函数(程序入口)int main(void) {jtagWait(); // 防止JTAG失效,重要~clockInit(); // 时钟初始化:晶振,6MHzbuzzerInit(); // 蜂鸣器初始化buzzerSound(1500); // 蜂鸣器发出1500Hz声音SysCtlDelay(400* (TheSysClock / 3000)); // 延时约400ms buzzerSound(2000); // 蜂鸣器发出2000Hz声音SysCtlDelay(800* (TheSysClock / 3000)); // 延时约800ms buzzerQuiet( ); // 蜂鸣器静音for (;;) {}}文件:buzzer.h#ifndef __BUZZER_H__#define __BUZZER_H__// 蜂鸣器初始化extern void buzzerInit(void);// 蜂鸣器发出指定频率的声音extern void buzzerSound(unsigned short usFreq); // 蜂鸣器停止发声extern void buzzerQuiet(void);1#endif // __BUZZER_H__文件:buzzer.c#include "buzzer.h"#include <hw_types.h>#include <hw_memmap.h> #include <sysctl.h>#include <gpio.h>#include <timer.h>#define PART_LM3S1138#include <pin_map.h> #define SysCtlPeriEnable SysCtlPeripheralEnable #define GPIOPinTypeOut GPIOPinTypeGPIOOutput// 声明全局的系统时钟变量extern unsigned long TheSysClock;// 蜂鸣器初始化void buzzerInit(void){SysCtlPeriEnable(SYSCTL_PERIPH_TIMER1); // 使能TIMER1模块SysCtlPeriEnable(CCP3_PERIPH); // 使能CCP3所在的GPIO端口GPIOPinTypeTimer(CCP3_PORT, CCP3_PIN); // 设置相关管脚为Timer功能TimerConfigure(TIMER1_BASE, TIMER_CFG_16_BIT_PAIR | // 配置TimerB为16位PWM TIMER_CFG_B_PWM); }// 蜂鸣器发出指定频率的声音// usFreq是发声频率,取值 (系统时钟/65536)+1 , 20000,单位:Hz void buzzerSound(unsigned short usFreq) {unsigned long ulVal;if ((usFreq <= TheSysClock / 65536UL) || (usFreq > 20000)) {buzzerQuiet( );}else {GPIOPinTypeTimer(CCP3_PORT, CCP3_PIN); // 设置相关管脚为Timer功能ulVal = TheSysClock / usFreq;TimerLoadSet(TIMER1_BASE, TIMER_B, ulVal); // 设置TimerB初值TimerMatchSet(TIMER1_BASE, TIMER_B, ulVal / 2); // 设置TimerB匹配值TimerEnable(TIMER1_BASE, TIMER_B); // 使能TimerB计数 }}// 蜂鸣器停止发声void buzzerQuiet(void){TimerDisable(TIMER1_BASE, TIMER_B); // 禁止TimerB计数GPIOPinTypeOut(CCP3_PORT, CCP3_PIN); // 配置CCP3管脚为GPIO输出GPIOPinWrite(CCP3_PORT, CCP3_PIN, 0x00); // 使CCP3管脚输出低电平 } 例程10(Timer PWM应用:蜂鸣器演奏乐曲程序清单1.10是Timer模块16位PWM模式的一个应用,能驱动交流蜂鸣器演奏一首动听的乐曲《化蝶》(乐谱参见图1.2)。
利用555定时器实现宽范围脉宽调制器(PWM)脉宽调制器(PWM)常常用在开关电源(稳压)中,要使开关电源稳压范围宽(即输入电压范围大),可利用555定时器构成宽范围PWM。
仅需把一个二极管和电位计添加到异步模式运转的555定时器上,就产生了一个带有可调效率系数为1%到99%的脉宽调制器(图1)。
它的应用包括高功率开关驱动的电动机速度控制。
(原文件名:555_Figure_01.gif)图1:在555定时器电路中增加一个二极管和电位计可构成一个宽范围PWM这个电路的输出可以驱动MOSFET去控制通过电动机的电流,达到平滑控制电动机速度90%左右。
这也应用于灯光的控制,灯光的强度可得以有效控制。
另一个应用是在开关式电源。
PWM调整允许一个可变的输出电压。
可通过555定时器(5个引脚)VC终端的反馈来调节电压。
一个超过调节阈值限制的输出电压将提前结束基于周期循环的PWM信号,以维持输出电压的稳定。
微处理器可以通过数字电位计直接调节PWM去控制电动机速度、灯光强度或者电源输出电压。
对于周期因子(DF):(原文件名:555_Figure_03.gif)其中,(原文件名:555_Figure_04.gif)而α是终端2和终端1之间电阻与终端3和终端1之间电阻的比值。
选R3=R1,R2=100×R1,这时DF为1%至99%。
如上所述,数字电位计可以代替R2。
通过的电流有限是在该应用中使用数字电位计的主要约束。
对于一个100kΩ的数字电位计,R1和R3可以达到1kΩ,则峰值电流为5mA。
标准二极管可在递减线性下当作D来使用。
对于理想的二极管,k=0.693,则有:(原文件名:555_Figure_05.gif)DF和α之间为线性关系。
图2显示了当α变化时VOUT的波形。
(原文件名:555_Figure_02.gif)图2:这三个波形显示了VOUT如何随α变化而变化。
作者:Henry Santana,Kavlico Corp=============呵呵,原来在这里8楼就有详细的解释<br><br> (原文件名:图2.gif)=============老外的图,是不是比3.2.3a少接一个VD2?阿莫的楼主位公式是不是应该改成3.2.3b那样?我个人觉得,有了光偶就可以省掉74HC14.有了HC14就可以省去光偶.74HC14换成CD40106如何?这样就不用额外的5V电源了.C2容量较大,是否在7812上并联反向二极管较为保险.印象中的555第3脚,好象拉电流能力强,输出电流好象很弱有一个小细节,有人能解释吗?IRFZ48N 的GS我加入了1K的电阻,是作为GS快速释放电荷使用的。
单片机中PWM技术原理与应用案例详解PWM(Pulse Width Modulation)是一种常用于控制电子设备的技术,广泛应用于单片机系统中。
PWM技术通过调整一个周期内高电平和低电平的时间比例,来实现对设备的控制。
本文章将详细介绍PWM技术的原理和应用案例。
首先,我们来了解PWM技术的基本原理。
PWM信号由高电平和低电平构成,高电平的时间称为占空比,用百分比来表示。
占空比越高,则高电平时间越长,输出的平均功率也越大。
相反,占空比越低,则高电平时间越短,输出的平均功率也越小。
PWM技术的原理是通过改变高电平和低电平的时间比例,来控制设备的输出。
以LED灯为例,当占空比为0%时,LED灯处于关闭状态;当占空比为100%时,LED灯处于全亮状态;当占空比为50%时,LED灯以一半的亮度工作。
在单片机系统中,PWM技术通常是通过定时器/计数器模块实现的。
所谓定时器,就是计算时间的设备,而计数器则是计数的设备。
定时器/计数器模块可以提供一个可编程的时钟源,并通过读取定时器的计数器值来确定时间的流逝。
使用PWM技术控制设备的步骤如下:1. 设定PWM的周期:通过设定定时器的计数器值和时钟源,来确定PWM的周期。
周期的选择取决于设备的要求和设计需求。
2. 设定PWM的占空比:通过修改定时器的计数器的初值和阈值,来设定PWM的占空比。
高电平的时间和低电平的时间由这两个值共同决定。
3. 启动定时器:启动定时器,开始产生PWM信号。
4. 反复循环:通过不断修改占空比,可以实现对设备的精确控制。
下面我们来看一个PWM技术的应用案例:温度控制。
在温度控制系统中,通过PWM技术可以精确地控制加热设备,以维持设定温度。
具体步骤如下:1. 设定温度范围和初始温度:根据实际需求,设定温度范围和初始温度。
2. 读取温度数据:使用温度传感器读取当前的温度数据。
3. 判断温度范围:将读取到的温度数据与设定的温度范围进行比较,判断当前的温度处于哪个范围。
hal库单定时器pwm输入捕获摘要:1.HAL 库简介2.定时器PWM 输入捕获的概念和原理3.HAL 库定时器PWM 输入捕获的实现方法4.HAL 库定时器PWM 输入捕获的应用实例5.总结正文:一、HAL 库简介HAL 库,即硬件抽象层库,是一种用于简化嵌入式系统开发的软件库。
它提供了一组通用的API,用于操作各种硬件设备,如定时器、PWM(脉冲宽度调制)输出等。
HAL 库在嵌入式系统开发中具有广泛的应用,能够帮助开发者降低开发难度,提高开发效率。
二、定时器PWM 输入捕获的概念和原理定时器PWM 输入捕获,是指在定时器PWM 输出模式下,对输入信号进行捕获处理的过程。
其原理是,在PWM 输出过程中,通过输入捕获功能,将PWM 信号的某个时刻的值捕捉并保存下来,以便后续处理。
这种输入捕获功能在很多实际应用场景中具有很大的价值,例如:测量脉冲宽度、控制电机转速等。
三、HAL 库定时器PWM 输入捕获的实现方法在使用HAL 库实现定时器PWM 输入捕获时,需要遵循以下步骤:1.初始化定时器:在使用定时器PWM 输入捕获功能之前,首先需要对定时器进行初始化。
这包括配置定时器的工作模式、时钟源、计数周期等参数。
2.配置PWM 输入捕获通道:根据实际需求,配置PWM 输入捕获通道,包括选择捕获引脚、设置触发条件等。
3.开启PWM 输入捕获:在完成定时器和PWM 输入捕获通道的配置后,需要开启PWM 输入捕获功能。
4.读取捕获值:当PWM 信号的某个时刻的值被捕获后,可以通过HAL 库提供的API 读取捕获值。
5.关闭PWM 输入捕获:在完成捕获操作后,需要关闭PWM 输入捕获功能,以释放相关资源。
四、HAL 库定时器PWM 输入捕获的应用实例假设我们需要测量一个电机驱动信号的脉冲宽度,可以通过以下步骤实现:1.初始化定时器和PWM 输入捕获通道。
2.开启PWM 输入捕获功能。
3.在定时器PWM 输出过程中,捕获输入信号的某个时刻的值。
PWM应用举例这里以单片机用PWM方式控制LED灯亮度为例,介绍PWM的应用硬件电路:如图10-36图10-36 PWM控制LED灯亮度软件:程序清单:;********************************************************************** ; PWM 控制 * ; 利用2个定时器控制产生占空比可变的 PWM 波 * ; T0方式1产生脉冲周期,其初始值为0F000H,定时4096机器周期 * ; T1方式1产生脉冲有效时间,其初始值从0F000H到0FFFFH, * ;其值越大,脉冲有效时间越小 * ;程序不断改变T1的初始值,使得输出脉冲有效时间不断变化, * ;对应的输出脉冲信号的平均值也不断变化,P2口所接的LED亮度也不断变化 * ;变化的效果只有在实际电路中可以观察到,仿真只可以看到波形变化 * ;资源:P2口,8路指示灯。
低电平有效 * ;效果:LED从亮到暗变化,然后从头开始。
;----------------------------PWM EQU 7FH ;PWM赋初始值PWM1 EQU 7EHOUT EQU P2 ;8个LED灯的接口;----------------------------ORG 0000HSJMP STARTORG 000BHSJMP INTT0ORG 001BHLJMP INTT1ORG 0030H;----------------------------;主程序;定时器0工作在模式1,确定脉冲周期;定时器1工作在模式1,确定高电平时间。
;----------------------------START: NOPMOV SP,#2FH ;堆栈开始在30HMOV TMOD,#11H ;T0、T1均方式1MOV TH1,#0F0H ;初始值F000H,脉冲周期固定MOV TL1,#00HMOV TH0,#0F0H ;初始值F000H,脉冲有效时间等于脉冲周期 MOV TL0,#00H ;频率调节SETB EA ;允许中断SETB ET0 ;允许T0中断SETB ET1 ;允许T1中断SETB TR0 ;启动T0MOV PWM,#0F0H ;脉宽调节,T1初始值MOV PWM1,#00H ;脉宽调节,T1初始值SJMP $ ;主程序到此结束;------------------------------;T0中断服务子程序(频率固定);控制定时器1中断;------------------------------INTT0: NOPCLR TR1 ;停止T1MOV A,PWM ;修改脉宽值ADD A,#5 ;初始值增加,脉宽减少MOV TL1,A ;脉宽初始值低字节MOV PWM,A ;保存JNC $+4 ;判断进位INC PWM1 ;进位为1,高字节加1MOV A,PWM1 ;判断高字节CJNE A,#0F0H,$+3 ;比较不相等转移JNC $+5 ;不小于0F0H转移MOV PWM1,#0F0H ;小于0F0H,从0F0H开始MOV TH1,PWM1 ;脉宽初始值高字节SETB TR1 ;启动T1MOV TH0,#0F0H ;T0初始值,周期MOV TL0,#00H ;频率固定MOV OUT,#00H ;启动输出,低电平有效RETI;------------------------------;T1中断服务子程序(脉宽);控制PWM脉冲宽度;------------------------------INTT1: NOPCLR TR1 ;脉宽调节结束MOV OUT,#0FFH ;结束输出RETI;---------------------------------------------------END以上内容请参看仿真文件PWM12A.DSN。
通用定时器-PWM实验二、预备知识通用定时器分为四个部分:1、选择时钟2、时基电路3、输入捕获4、输出比较定时器PWM输出主要涉及到定时器框图右下方部分,即输出比较部分时基时钟来源于内部默认时钟。
脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。
PWM工作过程:每个定时器有四个通道,每一个通道都有一个捕获比较寄存器,将寄存器值和计数器值比较,通过比较结果输出高低电平,实现PWM信号。
PWM输出库函数1、定时器通道初始化-TIM_OC1Init使用PWM需要配置,配置参数对应框图位置如下:1)TIMx_CCMR1寄存器的OC1M[2:0]位,设置输出模式控制器2)TIMx_CCER寄存器的CC1P位,设置输入/捕获通道1输出极性3)TIMx_CCER:CC1E位控制输出使能电路,信号由此输出到对应引脚初始化定时器输出比较通道:void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);TIM_OCInitTypeDef结构体:typedef struct{uint16_t TIM_OCMode; // PWM模式1或者模式2uint16_t TIM_OutputState; // 输出使能OR失能uint16_t TIM_OutputNState; // PWM输出不需要uint16_t TIM_Pulse; // 比较值,写CCRx,可以有次函数uint16_t TIM_OCPolarity; // 比较输出极性uint16_t TIM_OCNPolarity; // PWM输出不需要uint16_t TIM_OCIdleState; // PWM输出不需要uint16_t TIM_OCNIdleState; // PWM输出不需要} TIM_OCInitTypeDef;2、设置比较值函数-TIM_SetCompare1作用:外部改变TIM_Pulse值,即改变CCR的值void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);3、使能输出比较预装载-TIM_OC1PreloadConfig作用:TIM_CCMRx寄存器OCxPE位使能相应的预装在寄存器void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);4、使能自动重装载的预装载寄存器允许位-TIM_ARRPreloadConfig作用:操作TIMx_CR1寄存器ARPE位,使能自动重装载的预装载寄存器void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);5、修改通道极性作用:操作TIMx_CCER的CC1P位,修改通道极性void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);三、实验步骤:PWM输出步骤:1)使能定时器3和相关IO时钟(LED-PB5)使能定时器3时钟:RCC_APB1PeriphClockCmd();使能GPIOB时钟:RCC_APB2PeriphClockCmd();2)初始化IO口为复用功能输出GPIO_Init();GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;3)PB5输出PWM(定时器3通道2),需要部分冲突映射RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启AFIO时钟设置GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);//部分重映射4)初始化定时器(重装载值ARR,与分频系数PSC等)TIM_TimeBaseInit();//决定PWM周期5)初始化输出比较参数:TIM_OC2Init();//通道2输出比较初始化6)使能预装载寄存器TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);//定时器3 通道2 7)使能定时器TIM_Cmd();8)不断改变比较值CCRx,达到不同的占空比效果TIM_SetCompare2(); //通道2,改变比较值CCRxTIMER输出PWM实现步骤:1)设置RCC时钟;2)设置GPIO时钟;3)设置TIMx定时器的相关寄存器;4)设置TIMx定时器的PWM相关寄存器。
3 PWM定时器应用实例
本实例以定时器0的中断为例,讲解定时器0的配置过程。
/* 1. 相关寄存器的定义,关联各自的物理地址 */
#include "int.h"
#include "stdio.h"
#define PWMTIMER_BASE (0x139D0000)
#define TCFG0 ( *((volatile unsigned long *)(PWMTIMER_BASE+0x00)) ) #define TCFG1 ( *((volatile unsigned long *)(PWMTIMER_BASE+0x04)) ) #define TCON ( *((volatile unsigned long *)(PWMTIMER_BASE+0x08)) ) #define TCNTB0 ( *((volatile unsigned long *)(PWMTIMER_BASE+0x0C)) )
#define TCMPB0 ( *((volatile unsigned long *)(PWMTIMER_BASE+0x10)) )
#define TCNTO0 ( *((volatile unsigned long *)(PWMTIMER_BASE+0x14)) )
#define TINT_CSTAT ( *((volatile unsigned long *)(PWMTIMER_BASE+0x44)) )
#define ulong unsigned long
void pwm_stopall(void);
void timer_request(void);
void irq_handler(void);
void timer_init(ulongutimer,ulong uprescaler,ulong udivider,ulong utcntb,ulong utcmpb);
void irs_timer();
int counter; // 用于记录中断发生的次数
/* 2. 定义各个功能函数 */
void pwm_stopall(void) // 停止timer0
{
TCON = 0;
}
void irs_timer() // timer0中断的中断处理函数
{
TINT_CSTAT |= (0x1<<5); //清timer0的中断状态寄存器
printf("Timer0IntCounter = %d \r\n",counter++); // 打印中断发生次数
intc_clearvectaddr(); // vic相关的中断清
}
void timer_init(ulongutimer,ulong uprescaler,ulong udivider,ulong utcntb,ulong utcmpb)
{
ulong temp0;
// 定时器的输入时钟 = PCLK / ( {prescaler value + 1} ) / {divider value} = PCLK/(65+1)/16=62500Hz //设置预分频系数为66
temp0 = TCFG0;
temp0 = (temp0 & (~(0xff))) | ((uprescaler-1)<<0);
TCFG0 = temp0;
// 16分频
temp0 = TCFG1;
temp0 = (temp0 & (~(0xf<<4*utimer))) |(udivider<<4*utimer);
TCFG1 = temp0;
// 设置PWM占空比
TCNTB0 = utcntb;
TCMPB0 = utcmpb;
TCON |= 1<<1; // 手动更新
TCON &= ~(1<<1); // 清手动更新位
TCON |= (1<<0)|(1<<3); // 自动加载和启动timer0
// 使能timer0中断
temp0 = TINT_CSTAT;
temp0 = (temp0 & (~(1<<utimer)))|(1<<(utimer));
TINT_CSTAT = temp0;
}
void timer_request(void)
{
printf("\r\n#############Timer test############\r\n");
pwm_stopall(); // 禁止所有timer
counter = 0;
intc_setvectaddr(NUM_TIMER0,irs_timer); // 设置timer0中断的中断处理函数intc_enable(NUM_TIMER0); // 使能timer0中断
timer_init(0,65,4,62500,0); // 设置timer0的参数
}。