定时器产生脉冲同步问题
要实现以上波形,PB0(T0)接收外部开关的信号(频率在改变),波形为第1个。AVR M16程序参考马老师的例子8.3 N分频系统实现8分频,占空比为1:8,输出波形如图2 ,分频后的信号从PD7输出(以上2步都实现并验证过)。图中1的周期《=1MS ,想让图3中脉冲宽度=0.5MS .考虑使用定时器2实现,思路如下:在图2波形的上升沿,启动TC2,TC2工作在CTC模式,采用比较匹配中断,比较匹配中断时间设置为0.5MS,在比较匹配中断中复位PD7,并且停止TC2工作。再在TC0的比较匹配中断中启动TC2,保证图2和图3的脉冲同步。程序如下,但是PD7没有输出波形,不知道哪里出了问题,请各位高手帮忙分析一下。程序如下:#include <iom16v.h>
#include <macros.h>
#defineuchar unsigned char
#defineuintunsigned int
unsigned int value_ovf,value_comp;
void port_init(void)
{
PORTA = 0x00;
DDRA= 0x00;//设置PA0为输入方式
PORTB = 0x00;
DDRB= 0x00; //设置PB0(TO)为输入方式
PORTC = 0x00; //m103 output only
DDRC= 0x00;
PORTD = 0x00; //PD口输出低电平
DDRD= 0xFF; //设置PD口为输出方式
}
//定时器T0初始化
void timer0_init(void)
{
//T/C0初始化
TCCR0=0X07; //设置T/C0工作普通模式,T0上升沿触发
TCNT0=value_ovf; //PB0口信号8分频,PD口输出
OCR0=value_comp; // 设置OCR0的比较值,>TCNT0的初始值,<0xFF
TIMSK=0X03; //允许T/C0的溢出和比较匹配中断
SEI(); //开放全局中断
}
//Timer 0溢出中断服务
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
TCNT0=value_ovf; // 重新设置TCNT0的初值
PORTD&=0X7F; //使PD7复位,其它位保持不变0111 1111
}
// Timer 0 比较匹配中断服务
#pragma interrupt_handler timer0_comp_isr:20
void timer0_comp_isr(void)
{
PORTD|=0X80; //使PD7置1,其它位保持不变 1000 0000
TCCR2=0X0E; //启动TC2
}
//定时器T2初始化
void timer2_init(void)
{ // T/C2初始化
TCCR2=0x0C; // 内部时钟,64分频(4M/64=62.5KHz),CTC模式
//0000 1100(110为64分频)
TCNT2=0x00;
OCR2=0x0C;// OCR2 = 0x0C(30),(300+1)/62.5=0.496ms
TIMSK=0x80; // 允许T/C2比较匹配中断
SEI();
}
//********************T/C2中断服务函数********************//
#pragma interrupt_handler Timer2_comp:4
void Timer2_comp(void)
{
PORTD&=0X7F; //使PD7清零,其它位保持不变
TCCR2=0X08; //停止TC2
}
void main(void)
{
port_init(); //端口初始化程序
value_ovf=255-8+1; //8为8分频
value_comp=255-1; //占空比调节
timer0_init(); //定时器T0初始化
timer2_init(); //定时器T2初始化
while(1)
{
NOP;
}
http://cache.amobbs.com/bbs_upload782111/files_43/ourdev_661809G3QK5E.GIF
波形图示 (原文件名:波形图.GIF) 没有人回答,自己顶一个。 问题出在2个定时器初始化过程中:
timer0_init(); //定时器T0初始化 =====》 TIMSK=0X03; //允许T/C0的溢出和比较匹配中断
timer2_init(); //定时器T2初始化 =====》 TIMSK=0x80; // 允许T/C2比较匹配中断(但前面T0中断允许被清掉了!)
你PD7的控制使用了“ PORTD|=0X80; //使PD7置1,其它位保持不变 1000 0000”
奇怪的是TIMSK的设置为什么没有使用这样的方式?
因此我觉的你的学习方法还是需要改进,每个概念、每个方法、每条语句都要真正的去掌握,全面的考虑。而不是简单的拼代码,做组合。
另外,开全局中断的语句不要放在各个接口的初始化模块中,应该在全部系统初始化后,最后统一开启。
===============================
下面给你另外一个比较简单的办法是:
1。TO只要工作在比较匹配(ctc)输出方式,输出触发方式为置1(参考例8.5),比较值为7。每计数8个,T0会自己将PD7置1,将TCNT0清零,并进入中断。
2。在T0的比较匹配中断中开启T2:
void timer0_comp_isr(void)
{
//PORTD|=0X80; //使PD7置1,其它位保持不变 1000 0000 这句不要,T0比较匹配会自动置PD7为1的(初始化输出触发方式为置1)
TCNT2 = 0; //清零TC2计数器(保证0.5ms更准些)
TCCR2=0X0E; //启动TC2
}
3。T2按原来方式工作在CTC方式,中断中清零PD7,并停止自己计数。 谢谢马老师。
页:
[1]