目录
一.背景
imx6ull将PWM封装为外设

PWM原理

此图有三个中断,周期寄存器的回滚中断,采样寄存器的比较中断,以及FIFO缓冲区的空槽中断。此处只用FIFO中断,每次从FIFO中取数到采样寄存器,决定了占空比(该FIFO深度为4,即存放4个16位数),当FIFO缓冲区的数据被取到空的阈值时产生中断,在中断处理函数中再往FIFO里重新装入数据,以下实现的代码基于此。
计数寄存器自增到和采样寄存器比较,相等则将PWM电平翻转,后续再和周期寄存器的值比较,相等则翻转电平,同时从0开始重新计数自增,重复此过程,和采样寄存器比较,再和周期寄存器的值比较,相等就翻转电平,并回滚为0.

二.寄存器
PWMCR
FWM(bit27:26):
队列有四个数,设置FWM位为01,当队列有两个空槽时置1

POUTC(bit19:18):

00表示回滚点高电平,比较点低电平,01相反,即设置起始的默认电平。
如下图

CLKSRC(bit17:16):
PRESCALER(bit15:4):
REPEAT(bit2:1):

EN(bit0):

PWMSR
FE(bit3):

PWMIR
FIE(bit0):

PWMSAR
设置PWM的占空比,即采样寄存器

PWMPR
设置PWM周期,即周期寄存器

三.代码实现
float global_ratio = 1.0;
// 设置占空比
void set_ratio(void)
{
int i = 0 ;
for (i = 0; i < 4; i++)
{
PWM1->PWMSAR = PWM1->PWMPR * global_ratio;
}
}
void pwm1_interrupt_handler(void)
{
if ((PWM1->PWMSR & (1 << 3)) != 0)
{
set_ratio();
PWM1->PWMSR |= (1 << 3);
}
}
// pwm1初始化
void pwm1_init(void)
{
// 1. pwm引脚复用
IOMUXC_SetPinMux(IOMUXC_GPIO1_IO08_PWM1_OUT, 0);
// 2. pwm引脚电气属性
IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO08_PWM1_OUT, 0xB9);
PWM1->PWMCR = 0;
PWM1->PWMCR |= (1 << 26) | (1 << 16) | (65 << 4) | (3 << 1);
PWM1->PWMIR |= (1 << 0);
PWM1->PWMPR = 998;
set_ratio();
// 注册pwm中断
system_interrupt_register(PWM1_IRQn, pwm1_interrupt_handler);
// 设置pwm中断优先级
GIC_SetPriority(PWM1_IRQn, 0);
// 使能pwm中断
GIC_EnableIRQ(PWM1_IRQn);
// 使能PWM
PWM1->PWMCR |= (1 << 0);
}
250



被折叠的 条评论
为什么被折叠?



