8、PIC32系列 输出比较-单比较匹配模式
2022-07-28 来源:csdn
1、PIC32参考资源
PIC32系列参考手册 中文版 链接地址:PIC32系列参考手册 第16章 输出比较
2、输出比较模块
输出比较模块主要用于在响应选定时基事件时产生单脉冲信号或一连串脉冲信号。
每个输出比较模块都包含以下特殊功能寄存器 (Special Function Register, SFR)
OCxCON:OCMP 模块 “x” 的控制寄存器
OCxR:模块 “x” 的数据寄存器
OCxRS:模块 “x” 的辅助数据寄存器
T2CON:时基寄存器
TMR2:定时器寄存器
PR2:周期 2 寄存器
每个输出比较模块都具有以下工作模式:
单比较匹配模式:输出驱动为高电平,输出驱动为低电平、输出驱动为电平翻转;
双比较匹配模式:单输出脉冲、连续输出脉冲;
简单脉宽调制模式:不带故障保护输入、带故障保护输入;
3、寄存器介绍
OCxCON :输出比较 x 控制寄存器
bit 15 ON:输出比较外设使能位
1 = 使能输出比较外设。
0 = 禁止输出比较外设,不会消耗电流。允许进行 SFR 修改。该寄存器中其他位的状态不会受该位置 1或清零影响。
注: 使用 1:1 PBCLK 分频比时,在清零模块 ON 位的指令之后,用户的软件不应立即在 SYSCLK周期中读 / 写外设的 SFR。
bit 14 FRZ: 调试异常模式冻结位
1 = 在 CPU 进入调试异常模式时停止工作;
0 = 在 CPU 进入调试异常模式时继续工作
注: FRZ 仅在调试异常模式下可写,在正常模式下强制为 0。
bit 13 SIDL :IDLE (空闲)模式停止位
1 = 在 CPU 进入 IDLE (空闲)模式时停止工作;
0 = 在 IDLE (空闲)模式下继续工作
bit 12-6 保留:写入 0 ;忽略读操作
bit 5 OC32 :32 位比较模式位
1 = OCxR<31:0> 和 / 或 OCxRS<31:0> 用于与 32 位定时器源进行比较;
0 = OCxR<15:0> 和 OCxRS<15:0> 用于与 16 位定时器源进行比较
bit 4 OCFLT:PWM 故障条件状态位
1 = 发生了 PWM 故障条件 (仅可用硬件清零);
0 = 未发生 PWM 故障条件
注: 仅当 OCM<2:0> = 111 时,才使用该位。
bit 3 OCTSEL:输出比较定时器选择位
1 = Timer3 作为该 OCMP 模块的时钟源;
0 = Timer2 作为该 OCMP 模块的时钟源
bit 2-0 OCM<2:0>: :输出比较模式选择位
111 = OCx 处于 PWM 模式;故障引脚使能
110 = OCx 处于 PWM 模式;故障引脚禁止
101 = 初始化 OCx 引脚为低电平;在 OCx 引脚上产生连续输出脉冲
100 = 初始化 OCx 引脚为低电平;在 OCx 引脚上产生单输出脉冲
011 = 比较事件使 OCx 引脚电平翻转
010 = 初始化 OCx 引脚为高电平;比较事件强制 OCx 引脚为低电平
001 = 初始化 OCx 引脚为低电平;比较事件强制 OCx 引脚为高电平
000 = 输出比较外设被禁止,但会继续消耗电流
OCxCONCLR :输出比较 x 控制清零寄存器
OCxCONSET :输出比较 x 控制置1 寄存器
OCxCONINV :输出比较 x 控制取反寄存器
OCxR :输出比较 x 比较寄存器
bit 31-16 OCxR<31:16> :当 OC32 (OCxCON<5>) = 1 时,为 32 位比较值的高 16 位
bit 15-0 OCxR<15:0> :为 32 位比较值的低 16 位,或者在 OC32 = 0 时,为 16 位比较值的全部 16 位
OCxRCLR :输出比较 x 比较清零寄存器 比较清零寄存器
OCxRSET :输出比较 x 比较置 1 寄存器 寄存器
OCxRINV :输出比较 x 比较取反寄存器
OCxRS :输出比较 x 辅助比较寄存器
bit 31-16 OCxRS<31:16> :当 OC32 (OCxCON<5>) = 1 时,为 32 位比较值的高 16 位
bit 15-0 OCxRS<15:0> :为 32 位比较值的低 16 位,或者在 OC32 = 0 时,为 16 位比较值的全部 16 位
OCxRSCLR :输出比较 x 辅助比较清零寄存器 辅助比较清零寄存器
OCxRSSET :输出比较 x 辅助比较置 1 寄存器 寄存器
OCxRSINV :输出比较 x 辅助比较取反寄存器
IFS0 :中断标志状态寄存器 0
bit 22 OC5IF :输出比较 5 中断请求标志位
bit 18 OC4IF :输出比较 4 中断请求标志位
bit 14 OC3IF :输出比较 3 中断请求标志位
bit 10 OC2IF :输出比较 2 中断请求标志位
bit 6 OC1IF :输出比较 1 中断请求标志位
1 = 产生了中断请求;0 = 未产生中断请求
该中断寄存器中的阴影位名称用于控制其他 PIC32MX 外设,与输出比较模块无关。
IEC0 :中断允许控制寄存器 0
bit 22 OC5IE :输出比较 5 中断允许位
bit 18 OC4IE :输出比较 4 中断允许位
bit 14 OC3IE :输出比较 3 中断允许位
bit 10 OC2IE :输出比较 2 中断允许位
bit 6 OC1IE :输出比较 1 中断允许位
1 = 允许中断;0 = 禁止中断
该中断寄存器中的阴影位名称用于控制其他 PIC32MX 外设,与输出比较模块无关。
IPC1 :中断优先级控制寄存器 1
bit 20-18 OC1IP<2:0> :输出比较 1 中断优先级位
111 = 中断优先级为 7
110 = 中断优先级为 6
101 = 中断优先级为 5
100 = 中断优先级为 4
011 = 中断优先级为 3
010 = 中断优先级为 2
001 = 中断优先级为 1
000 = 禁止中断
bit 17-16 OC1IS<1:0> :输出比较 1 中断子优先级位
11 = 中断子优先级为 3
10 = 中断子优先级为 2
01 = 中断子优先级为 1
00 = 中断子优先级为 0
IPC2、IPC3、IPC4、IPC5状态相同
OCx引脚分别为RDO、RD1、RD2、RD3、RD4,需要注意。
4、单比较匹配模式
当控制位 OCM<2:0>(OCxCON<2:0>)设置为 001、010 或 011 时,选定的输出比较通道将配置为三种单输出比较匹配模式中的一种。同时,必须使能比较时基。
在单比较模式下,将 OCxR 寄存器中装载的值与选定的递增定时器寄存器 TMRy 中的值作比较。
在发生比较匹配事件时,将发生以下事件之一:
• 控制位 OCM<2:0> = 001,比较匹配事件强制OCx引脚为高电平;该引脚的初始状态为低电平。在发生单比较匹配事件时,产生中断。
• 控制位 OCM<2:0> = 010,比较匹配事件强制OCx引脚为低电平;该引脚的初始状态为高电平。在发生单比较匹配事件时,产生中断。
• 控制位 OCM<2:0> = 011,比较匹配事件使 OCx 引脚电平翻转。翻转事件是连续的,且每次翻转事件都会产生一次中断。
5、单比较匹配模式Harmony配置
1、在Project Graph界面中添加定时器以及输出比较单元;
2、TMR2以及OCMP1初始化状态如下;
OCMP1初始化状态;
3、设置TMR2定时器信息如下,分频系数为256,定时时间为200ms;
4、设置输出比较信息如下,输出比较模式为初始化为低,比较匹配时为高电平,16位宽度,比较值为60000,使能中断输出;
Select Output Compare Mode 输出比较模式选择
Output compare peripheral is disabled but continues to draw current
Initialize OCx pin low; compare event forces OCx pin high 单比较匹配模式输出驱动为高电平
Initialize OCx pin high; compare event forcesOCx pin low 单比较匹配模式输出驱动为低电平
Compare event toggles OCx pin 单比较匹配模式输出驱动为翻转电平
Initialize OCx pin low; generate single output pulse on OCx pin 双比较匹配模式单输出脉冲
Initialize OCx pin low; generate continious output pulses on OCx pin 双比较匹配模式连续输出脉冲
PWM mode on OCx; Fault pin disabled 简单脉宽调制模式不带故障保护输入
PWM mode on OCx; Fault pin enabled简单脉宽调制模式带故障保护输入
5、组件配置完成后点击左侧的Generate Code按钮生成代码;
6、生成的代码与原始代码存在差异,需进行确认;
7、代码生成后需要的操作;
1、初始化完成后添加TMR2以及OCMP1的启动;
2、OCMP1添加中断处理;
6、具体代码分析
TMR2部分代码参看前面几篇文章。
文件plib_ocmp1.c
//OCMP1初始化函数
void OCMP1_Initialize (void)
{
/*Setup OC1CON */
/*OCM = 1 */ //001为高电平,010为低电平,011为翻转电平
/*OCTSEL = 0 */ // 输出比较定时器选择位,0:TMR2,1:TMR3
/*OC32 = 0 */ //32 位比较模式位
/*SIDL = false */ //空闲模式停止位
OC1CON = 0x1; //输出比较控制寄存器
OC1R = 60000; //输出比较比较寄存器
IEC0SET = _IEC0_OC1IE_MASK; //中断允许控制
}
//使能输出比较外设
void OCMP1_Enable (void)
{
OC1CONSET = _OC1CON_ON_MASK; //输出比较外设使能位
}
//禁止输出比较外设
void OCMP1_Disable (void)
{
OC1CONCLR = _OC1CON_ON_MASK; //输出比较外设使能位
}
//输出比较比较寄存器
void OCMP1_CompareValueSet (uint16_t value)
{
OC1R = value; //16位比较值
}
//获取输出比较比较寄存器值
uint16_t OCMP1_CompareValueGet (void)
{
return (uint16_t)OC1R; //16位比较值
}
//
void OCMP1_CallbackRegister(OCMP_CALLBACK callback, uintptr_t context)
{
ocmp1Obj.callback = callback;
ocmp1Obj.context = context;
}
//输出比较中断
void OUTPUT_COMPARE_1_InterruptHandler (void)
{
IFS0CLR = _IFS0_OC1IF_MASK; //Clear IRQ flag
/* 可添加中断处理内容 */
GPIO_RB0_Toggle();
if( (ocmp1Obj.callback != NULL))
{
ocmp1Obj.callback(ocmp1Obj.context);
}
}
interrupts.c文件
void __ISR(_OUTPUT_COMPARE_1_VECTOR, ipl1SOFT) OUTPUT_COMPARE_1_Handler (void)
{
OUTPUT_COMPARE_1_InterruptHandler();
}
7、实验验证
点击编译按钮,编译提示BUILD SUCCESSFUL,点击烧录,提示Programming/Verify complete,开发板上的灯初始时熄灭,在一定时间后亮起。