【问题标题】:AVR GCC, Generating tone with Timer0 does not workAVR GCC,使用 Timer0 生成音调不起作用
【发布时间】:2014-08-09 09:24:30
【问题描述】:

我正在尝试将旧的 ASM 程序转换为 C。

我很确定我提取了所有需要的逻辑,但它根本不起作用。

我的目标是使用定时器比较匹配来切换输出引脚,为扬声器产生嗡嗡声。

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>

// speaker pin
#define SPK _BV(PA0)

#define SYSPORT         PORTA
#define SYSPIN          PINA
#define SYSDDR          DDRA

ISR(TIMER1_COMPA_vect)
{
    SYSPIN |= SPK; // toggle speaker
}

void main()
{
    cli(); // disable all interrupts

    SYSDDR  = 0b00000001;  // SPK to output
    SYSPORT = 0b00000001;  // turn off SPK

    TCCR0A  = _BV(WGM01);  // CTC mode
    TCCR0B  = _BV(CS01) | _BV(CS00);  // Prescaler 64
    OCR0A   = 62;  // compare match = 62 (output freq 1kHz)
    TIMSK = _BV(OCIE0A);  // enable timer interrupt

    sei();  // enable all interrupts

    while(1) {}  // infinite loop.
}

这段代码没有发出一声哔哔声,甚至没有点击,什么都没有。

但是,当我只使用循环和延迟时,它可以很好地工作 - 证明扬声器连接正确。

但我不能这样做,我必须在它发出声音的时候做点别的事情。

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#include <stdint.h>

// speaker pin
#define SPK _BV(PA0)

// PORTA
#define SYSPORT         PORTA
#define SYSPIN          PINA
#define SYSDDR          DDRA

void main()
{
    SYSDDR  = 0b00000001; // SPK to output
    SYSPORT = 0b00000001; // turn off SPK

    while(1) {
        _delay_us(100);
        SYSPIN |= SPK;
    }
}

保险丝设置为

LFUSE       = 0xE2
HFUSE       = 0xDF

频率 4MHz。

【问题讨论】:

    标签: c avr avr-gcc


    【解决方案1】:

    哦,哈哈,我太不专心了

    这应该是

    ISR(TIMER0_COMPA_vect)
    

    而不是

    ISR(TIMER1_COMPA_vect)
    

    它正在处理不同的计时器:D

    【讨论】:

    • 如果您的 ISR 实际上只是切换引脚,您应该考虑使用OCRnx 位在硬件中处理此问题。
    • @sapi 我知道这个功能,不幸的是,插座已经焊接,OCnx 引脚用于其他用途。我会在以后的项目中记住这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多