关于timer的pwm的使用

我们首先需要知道的是PWM的产生方式

通过STM32控制板,有两种方式能产生PWM,第一是利用普通IO口输出PWM,第二种是利用定时器的PWM的IO口或复用IO口

第一种为普通IO口产生PWM

普通IO口如何产生一个pwm?其实就是通过一个高低电平周期性的变化。这种思想很重要,确定频率就可以确定周期(T=1/f)也就是在一个周期内产生pwm的时间可以确定下来了。

如何改变占空比?确定了时间,高电平的时间不就是想要的占空比么,比如要产生一个频率1khz,占空比为70%的pwm,根据频率我们知道了pwm的周期为1ms,产生一个占空比为70%的不就是0.7ms的时间给高电平么,(我们用定时器中断的方式,使0.1ms产生一次更新中断,计数中断次数,中断处理函数前七次中断都给高电平就ok了。

我们用的是第二种

设置输出时是按输出通道分的库函数。即需要初始化哪个通道,就调用哪个函数。不同的通道对应的GPIO口也是不一样的。

也就是说,使用这个PWM波形,是用来等效地实现一个模拟信号的输出。
比如我们以一个很快的频率给电机进行通电、断电,那么电机的速度就能维持在一个速度中。
LED在熄灭时,由于余晖和人眼视觉暂留现象,LED不会应马熄灭。而是有定的惯性,过一小段时间才会熄灭。电机也是。当电机断电时。电机的转动不会立马停止。这就是惯性的系统

分析捕获/比较通道的输出部分

在这里插入图片描述
在这个图的左边输入的数据就是CNT和CRR1,他们进行比较,当满足CNT>CRR1CNT=CRR1时,进入输出模式控制器。
输出模式控制器改变它输出OC1ref(reference参考信号)的高低电平。
接着这个ref信号往后转递。
首先他可以转递到上部分的主模式控制器中。可以把这个ref映射到主模式的TRGO输出上去。
主要是

创建一个完整的工程文件,包含 TIMERPWM 功能模块的设计与实现,通常需要以下几个部分:项目结构设计、核心代码实现(包括 TIMERPWM 的初始化与配置)、头文件定义以及可能的中断服务程序。以下是基于 Zynq7020 平台和 VxWorks 实时系统的完整工程文件说明。 --- ### 工程目录结构 以下是一个典型的嵌入式工程项目目录结构: ``` Project/ │ ├── inc/ # 存放所有的头文件 │ ├── axi_timer.h # AXI Timer 寄存器定义及相关接口声明 │ ├── pwm.h # PWM 配置及功能接口声明 │ └── system_config.h # 系统全局配置文件 │ ├── src/ # 存放所有的源代码文件 │ ├── main.c # 主函数入口点 │ ├── axi_timer.c # AXI Timer 初始化及控制逻辑实现 │ ├── pwm.c # PWM 输出逻辑实现 │ └── interrupt_handler.c # 中断处理程序实现 │ ├── Makefile # 编译脚本 └── README.md # 项目文档说明 ``` --- ### 核心代码实现 #### `axi_timer.h` 文件 该文件用于定义 AXI Timer 的寄存器偏移量及其他相关宏。 ```c #ifndef AXI_TIMER_H #define AXI_TIMER_H #include <stdint.h> #include <vxworks.h> // 定义 AXI Timer 基础参数 #define AXI_TIMER_CLK 100000000UL // AXI Timer 时钟频率为 100 MHz [^1] #define AXI_TIMER_REG_BASE 0x42800000 // AXI Timer 寄存器基地址 [^1] // 定义 AXI Timer 寄存器偏移量 #define OFF_TCSR0 0x00 // TIMER0 控制和状态寄存器 [^1] #define OFF_TLR0 0x04 // TIMER0 重载寄存器 [^1] #define OFF_TCR0 0x08 // TIMER0 计数寄存器 [^1] #define OFF_TCSR1 0x10 // TIMER1 控制和状态寄存器 [^1] #define OFF_TLR1 0x14 // TIMER1 重载寄存器 [^1] #define OFF_TCR1 0x18 // TIMER1 计数寄存器 [^1] typedef struct { volatile uint32_t TCSR0; // TIMER0 控制和状态寄存器 volatile uint32_t TLR0; // TIMER0 重载寄存器 volatile uint32_t TCR0; // TIMER0 计数寄存器 volatile uint32_t RESERVED_0[5]; // 保留字段 volatile uint32_t TCSR1; // TIMER1 控制和状态寄存器 volatile uint32_t TLR1; // TIMER1 重载寄存器 volatile uint32_t TCR1; // TIMER1 计数寄存器 } AxiTimer_Regs; extern void Ax iTimerInit(uint32_t baseAddr); // 初始化 AXI Timer extern void Ax iTimerStart(uint32_t baseAddr, int timerNum); // 启动指定的 Timer extern void Ax iTimerSetReloadValue(uint32_t baseAddr, int timerNum, uint32_t reloadVal); // 设置重载值 #endif // AXI_TIMER_H ``` --- #### `pwm.h` 文件 该文件用于定义 PWM 相关的功能接口。 ```c #ifndef PWM_H #define PWM_H #include <stdint.h> // PWM 参数定义 #define PWM_MAX_DUTY_CYCLE 100 // 最大占空比 [%] #define PWM_MIN_DUTY_CYCLE 0 // 最小占空比 [%] // 函数原型声明 extern void PwmInit(uint32_t periodUs); // 初始化 PWM 模块 extern void SetPwmDutyCycle(int dutyCyclePercent); // 设置 PWM 占空比 extern void StartPwm(); // 开始 PWM 输出 #endif // PWM_H ``` --- #### `main.c` 文件 主函数负责初始化系统并启动 TIMERPWM 功能。 ```c #include "axi_timer.h" #include "pwm.h" int main() { // 初始化 AXI Timer Ax iTimerInit(AXI_TIMER_REG_BASE); Ax iTimerSetReloadValue(AXI_TIMER_REG_BASE, 0, (AXI_TIMER_CLK / 1000)); // 设置 TIMER0 为每毫秒触发一次中断 Ax iTimerStart(AXI_TIMER_REG_BASE, 0); // 初始化 PWM PwmInit(1000); // 设置 PWM 周期为 1ms SetPwmDutyCycle(50); // 初始占空比设为 50% StartPwm(); while (1) { // 主循环等待事件发生 } return 0; } ``` --- #### `axi_timer.c` 文件 实现 AXI Timer 的初始化和控制逻辑。 ```c #include "axi_timer.h" void Ax iTimerInit(uint32_t baseAddr) { *(volatile uint32_t *)(baseAddr + OFF_TCSR0) = 0x00020000; // 清除所有标志位并禁用计数器 *(volatile uint32_t *)(baseAddr + OFF_TCSR1) = 0x00020000; // 对于 TIMER1 执行相同操作 } void Ax iTimerStart(uint32_t baseAddr, int timerNum) { if (timerNum == 0) { *(volatile uint32_t *)(baseAddr + OFF_TCSR0) |= 0x00010000; // 启动 TIMER0 } else if (timerNum == 1) { *(volatile uint32_t *)(baseAddr + OFF_TCSR1) |= 0x00010000; // 启动 TIMER1 } } void Ax iTimerSetReloadValue(uint32_t baseAddr, int timerNum, uint32_t reloadVal) { if (timerNum == 0) { *(volatile uint32_t *)(baseAddr + OFF_TLR0) = reloadVal; // 设置 TIMER0 的重载值 } else if (timerNum == 1) { *(volatile uint32_t *)(baseAddr + OFF_TLR1) = reloadVal; // 设置 TIMER1 的重载值 } } ``` --- #### `pwm.c` 文件 实现 PWM 的初始化和动态调整功能。 ```c #include "pwm.h" static uint32_t g_pwmPeriodUs = 0; // 全局变量存储当前周期长度 static uint32_t g_pwmDutyCyclePercent = 0; // 全局变量存储当前占空比百分比 void PwmInit(uint32_t periodUs) { g_pwmPeriodUs = periodUs; // 这里可以根据具体的硬件平台完成进一步的初始化工作 } void SetPwmDutyCycle(int dutyCyclePercent) { if (dutyCyclePercent >= PWM_MIN_DUTY_CYCLE && dutyCyclePercent <= PWM_MAX_DUTY_CYCLE) { g_pwmDutyCyclePercent = dutyCyclePercent; // 更新硬件中的占空比设置 } } void StartPwm() { // 启动 PWM 输出的具体实现取决于目标硬件平台 } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值