|
众所周知,一般PLC可发出10-10000Hz的脉冲信号.我打算用AVR来实现这个功能.用MEGA168的TIMER1,工作于CTC模式,比较匹配时OC1A切换电平状态,同时中断进行已经脉冲数量计数并判断.以1000Hz发1000个脉冲为例得到以下程序并测试成功.感觉用这种方法存在以下问题,请高手指导.
问题1,无法精确产生1Hz为间隔的脉冲频率,如产生10001Hz的频率.
问题2,当为了通讯要采用14.7456M的晶体时,更没法得到整数频率输出.
问题3,当输出10000HZ时每隔50us即产生一次中断,以下的中断程序耗时约5us(AVRSTUDIO).真正工作时,有没有实用性.
问题4,还有其他方法么?
// Declare your global variables here
bit plus_busy,plus_complete; //发送中,发送完成
unsigned long int plus_sv;plus_pv;//设定发送数量,已经发送数量
// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
// Place your code here
if(!PINB.1)//脉冲输出低电平
{
if((++plus_pv)>=plus_sv)
{
plus_complete = 1;
plus_busy = 0;
TCCR1B = 0x0;//停止TIMER1
}
}
}
void main(void)
{
// Declare your local variables here
bit temp;
// Timer/Counter 1 initialization
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x40;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x7C;
OCR1BH=0x00;
OCR1BL=0x00;
// Global enable interrupts
#asm("sei")
while (1)
{
// Place your code here
if(!plus_busy)
{
if(PINC.0 && (!temp))//单次有效,PINC.0起动脉冲
{
// Clock source: System Clock
// Clock value: 125.000 kHz
// Mode: CTC top=OCR1A
// OC1A output: Toggle
// OC1B output: Discon.
plus_sv = 1000;
plus_pv = 0x0;
TCNT1H=0x00;
TCNT1L=0x00;
TCCR1B=0x0B;
plus_complete = 0;
plus_busy = 1;
}
}
temp = PINC.0;
};
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|