AVR单片机TO定时器快速PWM模式范例:
/*///////////////////////////////////////////////
///////定时器TO的使用例程——快速PWM模式/////////
//作者:宝山
//时间:2008.06.02
//编译环境:ICCV7 for AVR
//晶体: 11.0592Mhz
///////////////////////////////////////////////*/
#include
#include
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0x08; //PB3为PWM输出
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
}
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x01;
OCR0 = 0xF0; //改变此值可改变占空比
TCCR0 = 0x7D; //设置为快速PWM模式,匹配时OC0置1,分频系数1024
}
// 频率计算公式:fOCn= fclk/(N*256)
// N=1024
// fOC0=11059200/(1024*256)=42.1875Hz
// 在PB3管脚输出占空比可调,频率为42.1875Hz的PWM信号
// 通过改变分频系数N改变频率
#pragma interrupt_handler timer0_comp_isr:iv_TIM0_COMP
void timer0_comp_isr(void)
{
//compare occured TCNT0=OCR0
}
#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
TCNT0 = 0x01; //reload counter value
}
void init_devices(void)
{
CLI(); //disable all interrupts
port_init();
timer0_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x03; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void main(void)
{
init_devices();
while(1);
}
以下转自datasheet
快速PWM 模式(WGM01:0 = 3) 可用来产生高频的PWM 波形。快速PWM 模式与其他PWM模式的不同之处是其单斜坡工作方式。计数器从BOTTOM计到MAX,然后立即回到BOTTOM重新开始。对于普通的比较输出模式,输出比较引脚OC0在TCNT0与OCR0匹配时清零,在BOTTOM 时置位;对于反向比较输出模式, OC0 的动作正好相反。由于使用了单斜坡模式,快速PWM 模式的工作频率比使用双斜坡的相位修正PWM 模式高一倍。此高频操作特性使得快速PWM 模式十分适合于功率调节,整流和DAC 应用。高频可以减小外部元器件( 电感,电容) 的物理尺寸,从而降低系统成本。
工作于快速PWM 模式时,计数器的数值一直增加到MAX,然后在后面的一个时钟周期清零。图中柱状的TCNT0 表示这是单边斜坡操作。方框图同时包含了普通的PWM 输出以及反向PWM 输出。TCNT0 斜坡上的短水平线表示OCR0和TCNT0 的比较匹配。
工作于快速PWM 模式时,比较单元可以在OC0 引脚上输出PWM 波形。设置COM01:0为2 可以产生普通的PWM 信号;为3 则可以产生反向PWM 波形。要想在引脚上得到输出信号还必须将OC0 的数据方向设置为输出。产生PWM 波形的机
理是OC0 寄存器在OCR0 与TCNT0 匹配时置位( 或清零),以及在计数器清零( 从MAX变为BOTTOM) 的那一个定时器时钟周期清零( 或置位)。
OCR0寄存器为极限值时表示快速PWM模式的一些特殊情况。若OCR0等于BOTTOM,输出为出现在第MAX+1 个定时器时钟周期的窄脉冲; OCR0 为MAX 时,根据COM01:0的设定,输出恒为高电平或低电平。
通过设定OC0 在比较匹配时进行逻辑电平取反(COM01:0 = 1),可以得到占空比为50%的周期信号。OCR0 为0 时信号有最高频率foc2 = fclk_I/O/2。这个特性类似于CTC 模式下的OC0 取反操作,不同之处在于快速PWM 模式具有双缓冲。
:( 你的程序我拿来用。没有显示波形,
除非在中断里加一句PORTB^=0X08;才可以。
为什么呢?