AVR引脚输出脉冲频率最高能到多少?
我用的是m16,晶振7.3728M。使用定时器时定时按一定时间使PA0脚翻转,从而输出脉冲。最小定时时间应该是1/7.3728微妙,但是实际用示波器测量引脚输出频率时,最高只有57.5KHz,周期17微妙多些。实际1M的频率也达不到,但是定时到毫秒级就比较精确了,难道是芯片硬件原因达不到?为了使用相应的频率我也是先写个大概值然后再用示波器测量,上下调整TCNT里的初值。难道M16的输出上限就是几十KHz?欢迎各位凡人、牛人、或马老师级别的仙人们拍砖指正,不胜感激!!!!!!!! 实际1M的频率也达不到 -----是不是用了默认的1M 内部时钟------- 回复【1楼】erxun 老孟
-----------------------------------------------------------------------
没有啊 用的是外部晶振7.3228M的,这个我检查了,如果熔丝位错了下次会烧不进程序的(自己出现过几次这种情况了,汗!)
用的是T0,在ICC程序向导里就是把它设置成7MHz定时频率输出也不过100多K ctc模式 至少可以1M,11.0592MHZ, 这个是ICC的程序,就是一个简单的T0定时程序应该没错。但是示波器测量PA0脚输出只有115KHz左右,为什么呢?我可是定时的7MHz!
// Target : M16
// Crystal: 7.3728Mhz
//TIMER0 initialize - prescale:64
// WGM: Normal
// desired value: 7MHz
// actual value:7.373MHz (5.1%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0xFF; //set count
OCR0= 0x01;//set compare
TCCR0 = 0x01; //start timer
}
#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
TCNT0 = 0xFF; //reload counter value
PORTA^=0x01;//翻转PA0,只有这一句是自己写的其他都是程序向导生成的
} 直接些,AVR怎么产生一个0.8us宽度的脉冲,重复频率2KHz,就是在1个周期内只用0.8us为高电平周期内其他时间为低电平。AVR能到达这个要求吗? 回复【3楼】vipcff
-----------------------------------------------------------------------
杯具的是芯片是M16L的,最高只能8M。 用PIN寄存器也许可以的. 不要用中断去翻转IO口,这样肯定会慢了,中断的现场保护和恢复还有你的IO执行语句都是需要时间的呀。
你查看一下资料,它可以设置成由硬件比较自动翻转IO口,不需要中断的。 给一个我做的一个项目里的你参考,使用ATmega88单片机,8M晶振。自己改一下。
输出125K时钟。
/*********************************************************
*定时器2初始化
*分频比:1:1
*输出方式:快速PWM模式7
*溢出时间:4us(125K感应信号输出用)
*********************************************************/
void timer2_init(void)
{
//TCCR2B = 0x00; //stop
ASSR= 0x00; //set async mode
//TCNT2 = 0x80; //setup
OCR2A = 0x3F; //用于控制输出频率
OCR2B = 0x1F; //用于调节占空比
TCCR2A = 0x33;
TCCR2B = 0x09; //start
TCCR2A |= 0x30; //信号输出使能
} 回复【8楼】117433525 Owen
-----------------------------------------------------------------------
哈哈 “可以设置成由硬件比较自动翻转IO口,不需要中断的。”按这个方法确实产生了2us的脉冲,看来中断保护花费的时间实在太多了!
不过用M16实现重复频率2KHz,就是在1个周期内只用0.8us为高电平周期内其他时间为低电平,好像有些困难 “重复频率2KHz,就是在1个周期内只用0.8us为高电平周期内其他时间为低电平”不太理解?? 回复【12楼】117433525 Owen
-----------------------------------------------------------------------
就是说一个2KHz的脉冲高电平只用0.8us其他时间为低电平;也就是说脉冲波的占空比8/5000;相当于一个窄脉冲 回复【12楼】117433525 Owen
-----------------------------------------------------------------------
想了一个办法,使用T2产生2K的脉冲中断,在T2中断中使PB3为一,然后给T0的寄存器赋值TCCR0=0x29使OC0即PB0脚清零,但是貌似不好使。还在调试中 在各位前辈的帮助下,终于成功实现了窄脉冲的产生,其实题目可以换成:如何使用AVR产生窄脉冲。我是用窄脉冲来控制MOS管开关的。示波器实测的脉冲宽度是400ns、5V。思路是T2与T0定时器配合,使用T2产生2K的脉冲中断,在T2中断中使PB3置位,然后给T0的寄存器赋值TCCR0=0x29使OC0即PB0脚清零。M16程序如下:
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0xF9; //set count
OCR0= 0x07;//set compare调整OCR0值改变窄脉冲的宽度,各种原因计算和实际有出入的
//TCCR0 = 0x29; //start timer
}
//TIMER2 initialize - prescale:32
// WGM: Normal
// desired value: 1KHz
// actual value:1.002KHz (0.2%)
void timer2_init(void)
{
TCCR2 = 0x00; //stop
ASSR= 0x00; //set async mode
TCNT2 = 0x1A; //setup
OCR2= 0xE6;
TCCR2 = 0x03; //start
}
#pragma interrupt_handler timer2_ovf_isr:iv_TIM2_OVF
void timer2_ovf_isr(void)
{
TCNT2 = 0x1A; //reload counter value
PORTB|=BIT(3);
TCCR0 = 0x00; //stop
TCCR0 = 0x29; //start timer
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
没有数码相机就不上图了,但可以向伟大领袖保证真实性!特别感谢117433525 Owen的帮助。 搞一个定时器做2K的周期中断(中断优先级设为最高),在中断里面用几个空指令做延时输出0.8us高电平。
注意你用ICC程序向导生成的初始化可能会有误差,它不会帮你考虑现场保护什么的所用时间,你需要调整一下定时器的初值。 回复【16楼】117433525 Owen
-----------------------------------------------------------------------
最开始就是采用延时的方法但是测出来的波形幅值很小还不到100mv,所以论坛上就有这个问题了,呵呵!使用我在15楼那个方法输出波形就能到5V 不可能幅值小的,你是不是IO的方向寄存器没有设置成输出呀。DDRx寄存器。或延时时间不够。 回复【18楼】117433525 Owen
-----------------------------------------------------------------------
先鄙视下自己,又试了试延时的方法确实幅值确实是5V的,看来是自己的错误绕了这么大一圈,哈哈 不过还是非常感谢各位的帮忙!
void timer0_ovf_isr(void)
{
TCNT0 = 0x8D; //reload counter value
PORTA|=BIT(0);
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
PORTA&=~BIT(0);
}
简单几句就行了,搞这么复杂,哈哈! 我也走过一段你这样的经历! 回复【20楼】117433525 Owen
-----------------------------------------------------------------------
谢谢啊,学校就开了51的课,自己学的AVR问老师,说没用过,还是论坛高手多啊 发固定脉冲不需要有定时器.CTC模式就可以了. 到底大家是在用AVR吗?老是框在51中。落后了。使用STM32也这样?
这个问题根本不是“AVR引脚输出脉冲频率最高能到多少”!AVR引脚输出脉冲频率最高是系统时钟的1/2!!
271707在5楼明确了要求:
AVR怎么产生一个0.8us宽度的脉冲,重复频率2KHz,就是在1个周期内只用0.8us为高电平周期内其他时间为低电平。AVR能到达这个要求吗?
这个不能用CTC,而应该使用PWM。只是占空比不需要改变,初始化后便自动产生的,不需要任何中断和代码控制了。
给一个非常精确的参考设计思路:
因为需要一个“0.8us为高电平周期”,它只能是系统周期的倍数,才能非常精确。所以系统时钟采用5M的晶体,它的周期是0.2us。0.8/0.2 = 4
重复频率2KHz,周期为500us,500/0.2= 2500
使用M16的T/C1,初始化T/C1,采用系统时钟计数,1分频,工作在PWM模式,上限为2499,比较寄存器的值为3,开始工作,OK了。 回复【楼主位】271707
-----------------------------------------------------------------------
#include<avr/io.h>
int main(void)
{
DDRB|= _BV(0);
while(1)
{
PORTB|=_BV(0);
PORTB&= ~(_BV(0));
}
}
和楼主一样,一个脉冲时间2.7us
7.3728M晶振
望高手指点! 23楼已经指点了,自己要学会理解。基础!基础!还是基础!!! 什么啊……我用7.3728MHz做频率计,用CTC输出3.6864MHz都没问题啊,你们弄出这么多问题来? AVR引脚输出脉冲频率最高能到多少?
单片机系统时钟的一半。不过看看马老师的分析还是很精辟。 路过路过了顺便看看
页:
[1]