打印
[PIC32/SAM]

输出比较-双比较模式

[复制链接]
10040|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
aoyi|  楼主 | 2021-9-1 17:12 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
1、PIC32参考资源

PIC32系列参考手册 中文版  


使用特权

评论回复
沙发
aoyi|  楼主 | 2021-9-1 17:13 | 只看该作者
2、双比较匹配模式简介
当控制位 OCM<2:0>(OCxCON<2:0>)= 100 或 101 时,输出比较配置为

• 单输出脉冲模式

• 连续输出脉冲模式

在双比较模式下,模块在处理比较匹配事件时使用 OCxR 和 OCxRS 这两个寄存器。将 OCxR 寄存器的值与递增定时器 TMRy 计数的值作比较,并且在发生比较匹配事件时,在 OCx 引脚上产生脉冲的前 (上升)沿。然后 OCxRS 寄存器的值与同一个递增定时器 TMRy 计数的值作比较,并且在发生比较匹配事件时,在 OCx 引脚上产生脉冲的后 (下降)沿。


使用特权

评论回复
板凳
aoyi|  楼主 | 2021-9-1 17:15 | 只看该作者
3、单输出脉冲模式简介
要将输出比较模块配置为单输出脉冲模式,需设置控制位 OCM<2:0> = 100。此外,必须选择并使能比较时基。一旦使能了该模式,输出引脚 OCx 将被驱动为低电平,并保持低电平直到时基和OCxR 寄存器之间发生匹配为止。

• 在比较时基和 OCxR 寄存器之间发生比较匹配后的一个外设时钟, OCx 引脚被驱动为高电平。 OCx 引脚将保持高电平直到时基和 OCxRS 寄存器之间发生下一次匹配事件为止。此时,引脚将被驱动为低电平。 OCx 引脚将保持低电平直到模式发生改变或模块被禁止。

• 比较时基将计数到与关联周期寄存器中包含的值相等为止,然后在下一个指令时钟复位为0x0000。

• 如果时基周期寄存器的内容小于 OCxRS 寄存器的内容,则不会产生脉冲的下降沿。OCx 引脚将保持高电平直到 OCxRS <= PR2、模式改变或复位条件产生为止。

• 当OCx引脚被驱动为低电平(单脉冲的下降沿)时,相应通道的中断标志OCxIF会置为有效。

双比较模式OCxR < OCxRS < PRy

双比较模式OCxR < PRy < OCxRS 不产生脉冲的下降沿


使用特权

评论回复
地板
aoyi|  楼主 | 2021-9-1 17:17 | 只看该作者
4、设置产生单脉冲的步骤
当控制位 OCM<2:0> (OCxCON<2:0>)被设置为 100 时,选定的输出比较通道将 OCx 引脚初始化为低电平状态并产生单输出脉冲。

1. 确定外设时钟周期时间。

2. 计算从 TMRy 起始值 (0x0000)到输出脉冲的上升沿所需的时间。

3. 根据所需的脉冲宽度和到脉冲上升沿的时间,计算出现脉冲下降沿的时间。

4. 将以上步骤2和步骤3中计算出的值分别写入比较寄存器OCxR和辅助比较寄存器OCxRS。

5. 将定时器周期寄存器 PRy 的值设置为等于或大于辅助比较寄存器 OCxRS 中的值。

6. 设置 OCM<2:0> = 100,并将 OCTSEL (OCxCON<3>)位设置为所需定时器源的对应值。此时 OCx 引脚状态被驱动为低电平。

7. 将 ON (TyCON<15>)位设为 1 以使能定时器。

8. 在 TMRy 和 OCxR 第一次匹配时, OCx 引脚将被驱动为高电平。

9. 当递增定时器 TMRy 和辅助比较寄存器 OCxRS 发生匹配时,在 OCx 引脚上驱动脉冲的第二个边沿(即后沿,从高电平到低电平)。OCx 引脚上不会驱动输出额外的脉冲,它将保持为低电平。第二次比较匹配事件会导致 OCxIF 中断标志位置 1,这将会产生中断(如果已通过将 OCxIE 位置 1 允许中断)。

10. 要启动另一个单脉冲输出,根据需要更改定时器和比较寄存器的设置,然后进行写操作将OCM<2:0>(OCxCON<2:0>)位设置为 100。不需要禁止和重新使能定时器并清零 TMRy寄存器,而且这样做有利于从已知事件时间边界定义脉冲。

在输出脉冲下降沿后不一定要禁止输出比较模块。通过重写 OCxCON 寄存器的值可以启动另一个脉冲。

双比较模式产生单输出脉冲的特殊情况


使用特权

评论回复
5
aoyi|  楼主 | 2021-9-1 17:19 | 只看该作者
5、双比较模式单输出脉冲Harmony配置

1、在Project Graph界面中添加定时器TMR2以及输出比较OCMP1,并配置定时器(可参考前面**配置,不赘述);

2、配置输出比较参数,其中Select Output Compare Mode选择为Initialize OCx pin low; generate single output pulse on OCx pin 即双输出比较模式单输出脉冲;并配置Compare value(OCxR)值以及Secondary Compare Value(OCxRS)值;



3、配置完成后点击左侧的Generate Code按钮生成代码;


4、代码生成后进行代码确认;


5、代码生成后需要的操作;


1、初始化完成后添加TMR2以及OCMP1的启动;


2、OCMP1添加中断处理;


6、编译运行将代码烧录到开发板中;



使用特权

评论回复
6
aoyi|  楼主 | 2021-9-1 17:20 | 只看该作者
6、具体代码分析

文件plib_ocmp1.c


//OCMP1初始化函数

void OCMP1_Initialize (void)

{

    /*Setup OC1CON */

    /*OCM = 4 */ //OCM<2:0>=100,双比较模式单输出脉冲

    /*OCTSEL = 0 */ // 输出比较定时器选择位,0:TMR2,1:TMR3

    /*OC32 = 0 */ //32 位比较模式位

    /*SIDL = false */ //空闲模式停止位

    OC1CON = 0x4; //输出比较控制寄存器

    OC1R = 2000; //输出比较比较寄存器

    OC1RS = 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_CompareSecondaryValueSet (uint16_t value)

{

    OC1RS = value; //16位辅助比较寄存器值

}

//获取输出比较辅助比较寄存器值

uint16_t OCMP1_CompareSecondaryValueGet (void)

{

    return (uint16_t)OC1RS; //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
aoyi|  楼主 | 2021-9-1 17:22 | 只看该作者
7、实验验证,双比较模式单脉冲输出

点击编译按钮,编译提示BUILD SUCCESSFUL,点击烧录,提示Programming/Verify complete,开发板上的灯初始时熄灭,在一定时间后亮起,然后一定时间后再熄灭。


使用特权

评论回复
8
aoyi|  楼主 | 2021-9-1 17:23 | 只看该作者
8、双比较模式连续输出脉冲简介

要将输出比较模块配置为该模式,需设置控制位 OCM<2:0> = 101。此外,必须选择并使能比较时基。一旦使能了该模式,输出引脚OCx将被驱动为低电平,并保持低电平直到比较时基和OCxR寄存器之间发生匹配为止。

• 在比较时基和 OCxR 寄存器之间发生比较匹配后的一个 PBCLK 周期,OCx 引脚被驱动为高电平。OCx 引脚将保持高电平直到时基和 OCxRS 寄存器之间发生下一次匹配事件为止,此时引脚将被驱动为低电平。OCx 引脚将重复这种脉冲发生序列(即,从低电平变为高电平边沿,然后是从高电平变为低电平边沿),而无需用户进一步干预。


• OCx 引脚将产生连续脉冲,直到模式发生改变或模块被禁止为止。


• 比较时基将计数到与关联周期寄存器中包含的值相等为止,然后在下一个指令时钟复位为0x0000。


• 如果比较时基周期寄存器的值小于 OCxRS 寄存器的值,则不会产生下降沿。OCx 引脚将保持高电平,直到 OCxRS <= PRy、模式发生改变或器件复位。


• 当OCx引脚被驱动为低电平(单脉冲的下降沿)时,相应通道的中断标志OCxIF会置为有效。



使用特权

评论回复
9
aoyi|  楼主 | 2021-9-1 17:25 | 只看该作者
9、设置产生连续输出脉冲

当控制位 OCM<2:0> (OCxCON<2:0>)被设置为 101 时,选定的输出比较通道将 OCx 引脚初始化为低电平状态,并在每次发生比较匹配事件时产生输出脉冲。

1. 确定外设时钟周期时间。考虑定时器源(如果使用了一个定时器源)的外部时钟频率和定时器预分频比的设置。


2. 计算从 TMRy 起始值 (0x0000)到输出脉冲的上升沿所需的时间。


3. 根据所需的脉冲宽度和到脉冲上升沿的时间,计算出现脉冲下降沿的时间。


4. 将以上步骤2和步骤3中计算出的值分别写入比较寄存器OCxR和辅助比较寄存器OCxRS。


5. 将定时器周期寄存器 PRy 的值设置为等于或大于辅助比较寄存器 OCxRS 中的值。


6. 设置 OCM<2:0> = 101,并将 OCTSEL (OCxCON<3>)位设置为所需定时器源的对应值(仅适用于 16 位模式)。此时 OCx 引脚状态被驱动为低电平。


7. 通过将 TON (TyCON<15>)位设为 1 使能比较时基。


8. 在 TMRy 和 OCxR 第一次匹配时, OCx 引脚将被驱动为高电平。


9. 当比较时基 TMRy 和辅助比较寄存器 OCxRS 发生匹配时,在 OCx 引脚上驱动脉冲的第二个边沿 (即后沿,从高电平到低电平)。


10. 第二次比较匹配事件会导致 OCxIF 中断标志位置 1。


11. 当比较时基和相应周期寄存器中的值匹配时,TMRy寄存器复位为0x0000并重新开始计数。


12. 重复步骤 8 到步骤 11,可无限制地产生连续脉冲流。在每次发生 OCxRS-TMRy 比较匹配事件时, OCxIF 标志会置 1。


双比较模式产生连续输出脉冲的特殊情况


使用特权

评论回复
10
aoyi|  楼主 | 2021-9-1 17:26 | 只看该作者
10、双比较模式连续输出脉冲Harmony配置

1、在Project Graph界面中添加定时器TMR2以及输出比较OCMP1,并配置定时器(可参考前面**配置,不赘述);

2、配置输出比较参数,其中Select Output Compare Mode选择为Initialize OCx pin low; generate continious output pulse on OCx pin 即双输出比较模式连续输出脉冲;并配置Compare value(OCxR)值以及Secondary Compare Value(OCxRS)值;



3、配置完成后点击左侧的Generate Code按钮生成代码;


4、代码生成后进行代码确认;


5、代码生成后需要的操作;


1、初始化完成后添加TMR2以及OCMP1的启动;


2、OCMP1添加中断处理;


6、编译运行将代码烧录到开发板中;



使用特权

评论回复
11
aoyi|  楼主 | 2021-9-1 17:32 | 只看该作者
11、具体代码分析

双比较模式连续输出与双比较模式单脉冲输出仅初始化函数存在差异,其余代码可参看双比较模式单脉冲输出函数分析


void OCMP1_Initialize (void)

{

    /*Setup OC1CON */

    /*OCM = 5 */ //OCM<2:0>=101,双比较模式连续输出脉冲

    /*OCTSEL = 0  */ // 输出比较定时器选择位,0:TMR2,1:TMR3

    /*OC32 = 0 */ //32 位比较模式位

    /*SIDL = false */ //空闲模式停止位

    OC1CON = 0x5; //输出比较控制寄存器

    OC1R = 5000; //输出比较比较寄存器

    OC1RS = 30000; //辅助比较寄存器

    IEC0SET = _IEC0_OC1IE_MASK; //中断允许控制

}



使用特权

评论回复
12
aoyi|  楼主 | 2021-9-1 17:34 | 只看该作者
12、实验验证,双比较模式连续输出

点击编译按钮,编译提示BUILD SUCCESSFUL,点击烧录,提示Programming/Verify complete,开发板上的灯初始时熄灭,然后LED亮灭交替。


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

99

主题

3305

帖子

3

粉丝