一.输出比较初始化
步骤:
1.复用端口映射为OCx
例如:RPA0Rbits.RPA0R=0b0101; 即RPA0引脚作为外设OC1使用
2.OCM<2:0>:输出比较模式选择位
例如:OC1CON=0X06;
3.OC32<5>:32 位比较模式位
例如:OC1CONCLR=0X010;
4.OCTSEL<3>:输出比较定时器选择位
例如:OC1CONSET=0X08;
5.定时器使能初始化
例如:OpenTimer3(T1_ON|T1_SOURCE_INT|T1_PS_1_1,pwmn);
Pwmn周期数={ FB外设/pwmfp频率 } - 1;
6.ON<15>:输出比较外设使能位
例如:OC1CONSET=0X8000;
详细初始化控制寄存器见附二
二.中断触发条件
单比较模式
• 比较匹配事件强制OCx 引脚为高电平;该引脚的初始状态为低电平。在发生单比较匹配事件
时,产生中断。
• 比较匹配事件强制OCx 引脚为低电平;该引脚的初始状态为高电平。在发生单比较匹配事件时,产生中断。
• 比较匹配事件使OCx 引脚电平翻转。翻转事件是连续的,且每次翻转事件都会产生一次中断。
双比较模式
当OCx引脚被驱动为低电平(单脉冲的下降沿)时,相应通道的中断标志OCxIF会置为有效。
PWM模式
TyIF 中断标志在每个PWM 周期边界处置为有效。
当使能了具有故障保护输入模式的PWM 时,必须通过将相应的TRIS SFR 位置1 以将OCFx 故
障引脚配置为输入。选择PWM 故障模式时, OCFx 故障输入引脚不会自动配置为输入。
三.计算各项值
所需的PWM通过写入OCxRS 寄存器来指定PWM 占空比。可以在任何时候写OCxRS 寄存器,但是在PRy和TMRy 发生匹配(即周期结束)前占空比值不会被锁存到OCxR 中。
PWM 周期 = [(PR 1) • TPB • (TMR 预分频值)]
PWM 频率 = 1/[PWM 周期]
最大PWM 分辨率:在一个PWM周期内有n个时基(PR),为2的x次方,分辨率为x。
以频率为52.08 kHz为例
FPB = 10 MHz
Timer2 预分频比设置: 1:1
1/52.08 kHz = (PR2 1) • TPB • (Timer2 预分频值)=(PR2 1)/(FPB/Timer2预分频)
19.20 us = (PR2 1) • 0.1 us • (1)
PR2 = 191
确定可用于52.08 kHz PWM 频率和10 MHz 外设总线时钟速率的占空比的最大分辨率。
1/52.08 kHz = 2^PWM 分辨率• 1/10 MHz • 1
19.20 us = 2^PWM 分辨率• 100 ns • 1
192 = 2^PWM 分辨率
log10(192) = (PWM 分辨率) • log10(2)
PWM 分辨率 = 7.6 位
四.拓展
#用PWM绘制新波形
峰峰值最大为PR定时器数。
每个PWM周期为一个样本
所需波形频率:
所需频率=1/(n个样本*PWM周期)
每个样本波形的幅度值(占空比*PR):
波形/n,将n个值列入数组表格,OCxRS引用。
每个PWM周期输出通过RC滤波电路转换为模拟信号,约为一条幅值为 高电平*占空比 的直线,
通过改变占空比控制赋值y轴,再通过控制周期数控制产生的x轴
正弦波波形产生,占空比计算值 OC1RS=偏移量 振幅*SIN(2*pi/周期样本值),但如此短的时间无法
来的及计算sin,最好制成表格数组引用。
#发出声音
绘制相应的频率可发出相应的音高(do,re,me…),再调整波形幅度决定音色(不同的乐器)。
举例说明
一.
#include
#pragma config FPLLIDIV = DIV_2
#pragma config FPLLMUL = MUL_24
#pragma config FPLLODIV = DIV_2
#pragma config FPBDIV = DIV_1
#pragma config FNOSC = FRCPLL
#pragma config FUSBIDIO = OFF
#pragma config FWDTEN = OFF
#pragma config JTAGEN = OFF
int pwm1,pwmn,pwmfp,count,pwm_g;
void PWMinint()
{
}
void __ISR(_TIMER_2_VECTOR,ipl3) Timer2hander(void)
{
}
int main()
{
}
二.按键实时控制PWM
#include
// Configuration Bit settings
// SYSCLK = 48 MHz (8MHz Crystal / FPLLIDIV * FPLLMUL / FPLLODIV)
// PBCLK = 48 MHz (SYSCLK / FPBDIV)
// Primary Osc w/PLL (XT ,HS ,EC PLL)
// WDT OFF
#pragma config FPLLMUL = MUL_24, FPLLIDIV = DIV_2, FPLLODIV = DIV_2, FWDTEN = OFF
#pragma config POSCMOD = OFF, FNOSC = FRCPLL, FPBDIV = DIV_1,FSOSCEN = OFF
#pragma config FUSBIDIO = OFF
#pragma config FVBUSONIO = OFF
#pragma config JTAGEN
#pragma config CP
#pragma config DEBUG
// Period needed for timer 1 to trigger an interrupt every 0.1 second
// (48MHz PBCLK / 1 = 48000000KHz Timer 1 clock)
#define PERIOD
#define BTN_DELAY
#define SYS_FREQ (48000000L)
//????????
typedef enum //PRO_Status
{
}PRO_STATUS;
PRO_STATUS g_status=SHOW_PERIOD;
UINT16 g_period=40,g_duty=20; //初始周期40,占空比20
UINT16 g_set_period=40,g_set_duty=20;
int
//显示于按键标志,用于周期性定时处理LED显示和按键
unsigned char Led_lib[] = {
//LED字库SPI初始化
void SpiInitDevice() {
}
void SpiDoBurst(unsigned char *pBuff, unsigned char Len) {
}
//LED初始化
void Led()
{
}
void pwminit()
{
//
//
}
//void __ISR(_TIMER_2_VECTOR,ipl1) Timer2(void)
//{
//
//
//
//若由输出比较的基定时器2刷新值,则会随着PWM周期的太小刷新过快,会与定时器1的中断多次冲突造成定时器1无法正常工作。
//
//}
void Timer1Init()
{
}
//??1????
void __ISR(_TIMER_1_VECTOR, ipl5) Timer1Handler(void)
{
}
//设为数字端口,当有足够电压改变1与0的转换才有信号
void BtnInit()
{
//
}
//????
void Button(void)
{
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
}
int main(int argc, char** argv) {
}
表11-2: 输出引脚选择
例如:RPA0Rbits.RPA0R=0b0101;或 PPSOutput(1,RPA0,OC1);
例如:RPB15Rbits.RPB15R=0b0011; 或 PPSOutput(1,RPB15,SS1);
输入引脚映射选择
INT4Rbits.INT4R=0B0001; 或 PPSInput(3,SDI2,RPB6)
SDI1Rbits.SDI1R=0B0110; 或 PPSInput(2,SDI1,RPC8)
初始化相关位定义
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)
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 = 输出比较外设被禁止,但会继续消耗电流
转载请说明出处谢谢