搜索
bottom↓
回复: 3

定时器产生脉冲同步问题

[复制链接]

出0入0汤圆

发表于 2011-7-29 10:39:22 | 显示全部楼层 |阅读模式
要实现以上波形,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>
#define  uchar unsigned char
#define  uint  unsigned 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;
}


波形图示 (原文件名:波形图.GIF)

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2011-8-1 10:24:02 | 显示全部楼层
没有人回答,自己顶一个。

出0入0汤圆

发表于 2011-8-1 13:39:56 | 显示全部楼层
问题出在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,并停止自己计数。

出0入0汤圆

 楼主| 发表于 2011-8-1 17:22:59 | 显示全部楼层
谢谢马老师。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 08:23

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表