目录
一.背景
PWM原理
二.寄存器
PWMCR
FWM(bit27:26):
POUTC(bit19:18):
CLKSRC(bit17:16):
PRESCALER(bit15:4):
REPEAT(bit2:1):
EN(bit0):
PWMSR
FE(bit3):
PWMIR
FIE(bit0):
PWMSAR
PWMPR
三.代码实现
一.背景
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); }