fyjzmx2000 发表于 2009-7-15 22:29:10

请教马老师,为什么我用定时器1普通模式进行比较匹配输出方波不能实现高频?

我用M64,外部8M晶振,想实现连续不规则变化的变频方波。
我用CTC模式已经做出高频,但频率高的时候跨度比较大,我想要能连续变化的频率。

所以现在想试用普通模式,比较匹配中断来做频率输出。
但我能做出最高频率才只有17.5KHZ。即是57US周期。最小频率是69HZ,周期16.40MS
请问怎么才能做出高频呢?
下面是我的程序代码:

#include <iom64v.h>
#include <macros.h>
#define   SYSCLK 8000000L      //晶振
#define   ucharunsigned char
#define   uint   unsigned int
#define   OC0_OUT_EN        DDRE |= 0b00001000//PE3输出方波
long T;

//定时器1初始化
void Timer1Init(void)
{
        TCCR1A = 0x00;        //普通模式比较匹配, OCnA/OCnB/OCnC 未连接
       TCCR1B = 0X01;       //1分频
        TIMSK = 0x10;      // bit4,比较中断
        TCNT1 = 0x00;        //设置TC0计数寄存器初值
        OCR1A= 0x77;        //输出比较寄存器初值
}
/*-----------------------------------------------------------------
函数名称: timer1_comp_isr(void)比较中断
-----------------------------------------------------------------*/
#pragma interrupt_handler timer1_comp_isr:iv_TIMER1_COMPA
void timer1_comp_isr(void)
{
CLI();
 TCNT1 = 0x00; //reload counter value?????????不知道这里重置计数器会不会影响频率正确输出????????????
PORTE^=0x08;//PE3输出反相电平
OCR1A=T*4;//(T/2)*8;//其中,T为一个周期单位是US,计数器每加一个数是0.125US,加8个是1US。
SEI();
}

//主程序
void main(void)
{CLI();
        OC0_OUT_EN;        //设置PE3为输出
        PORTE=0X00;
        Timer1Init();
        SEI();
        while(1)
        {
        T=87;//这里是想实现87US一周期的方波,误差是18US,也就是测得的周期是105US。
        }
}

fyjzmx2000 发表于 2009-7-16 09:58:17

谁能帮帮我?我做了好多天实验了,就是不能实现高频。。。。。。。。

pipige 发表于 2009-7-16 10:10:07

我想你需要的是T0~T2的“比较匹配输出模式”,仔细看一下datasheet,我做过30KHz,没问题的

fyjzmx2000 发表于 2009-7-16 10:54:17

我要1M左右的频率。为什么T1不行?手册我看了好几十遍了,就能理解到这个程度。。。
你能说详细一些吗?谢谢

machao 发表于 2009-7-17 00:18:16

For generating a waveform output in CTC mode, the OC1A output can be set to toggle
its logical level on each compare match by setting the compare output mode bits to toggle
mode (COM1A1:0 = 1). The OC1A value will not be visible on the port pin unless the
data direction for the pin is set to output (DDR_OC1A = 1). The waveform generated will
have a maximum frequency of fOC1A = fclk_I/O/2 when OCR1A is set to zero (0x0000). The
waveform frequency is defined by the following equation:

fOCnA = (fclk_I/O) / 2N(1 + OCRnA)
= --------------------------------------------------
The N variable represents the prescaler factor (1, 8, 64, 256, or 1024)

======================================================================================
看了好几十遍了,比我都多了。上面的看到以及看懂么?

如果类似看武侠小说那样,就是看过几百遍也是白看的。

fyjzmx2000 发表于 2009-7-17 10:26:04

看的懂,但马老师说的这段话是CTC模式的设置。
我说的是不用CTC模式,
只是普通模式下比较中断不能产生高频。。。

fyjzmx2000 发表于 2009-7-18 08:08:35

OCR1A=T*4;//(T/2)*8;//其中,T为一个周期单位是US,计数器每加一个数是0.125US,加8个是1US。
我把这句话改成 OCR1A=T+T+T+T;//(T/2)*8;//就能出50K的频率了,但还是不高。
请老师帮指导一下。谢谢了

machao 发表于 2009-7-19 13:02:05

你应该仔细学习定时器的工作原理,并考虑中断过程中对定时器工作的影响。

CPU响应和退出中断是需要时间的,你在中断中还要做乘法,这些时间已经大于你要输出方波的半周期了,这样处理是不可能得到高频率方波输出的。

如果使用CTC方式,比较匹配取反输出!这样方波的产生是纯定时器硬件产生,最高可以有4M的输出。在比较匹配中断中只要改变比较寄存器的值就可以了(甚至中断都不需要)。

这样做输出高频率为 f = 8M / 2(1 + OCRnA), 4M、1M、512K、256K、128K。问题是频率跨度大,不能做到比较连续。其分频系数为2、4、6、8、10......

实际上要做到频率变化连续是有条件的,只有这些可能值:8M/2、3、4、5、6....65534、65535。也就是在上面基础上增加一挡。

如果这种分辨率能满足你系统的需要,建议使用T1的工作模式14的快速PWM方式。此时ICR1设置成2,3,4,5,6,7,8,9....是分频系数,而OCR1A为ICR1的一半。

这样可以比纯CTC方式,频率跨度比较小的方波,但是并不都是50%对称的。注意在高频输出时,改变频率会出现输出波形的紊乱,但会马上正常的。

如果在改变频率时,允许输出波形的暂时紊乱(约8个cpu周期),那么可以不使用任何中断,只要在程序需要的时候,同时改变OCR1A和ICR1寄存器的值就可以。

你应该给出一个实际上需要的最高频率,然后分析是否可以实现,以及如何实现。还有就是应该使用16M的系统时钟,这样在同样的方法下,输出频率可以提高一倍。

liyachenvv 发表于 2009-8-19 19:07:31

强啊。相当于一篇论文。
页: [1]
查看完整版本: 请教马老师,为什么我用定时器1普通模式进行比较匹配输出方波不能实现高频?