使用C编程以特定时间间隔产生音调

时间:2009-03-02 17:53:10

标签: c embedded pic18

我使用C语言为PIC18F产生音调,使得每个音调以特定的时间间隔播放。我用PWM来产生音调。但我不知道如何创建间隔。这是我的尝试。

#pragma code                                    // 
void main (void)
{

 int i=0;
    // set internal oscillator to 1MHz  
    //OSCCON = 0b10110110;                    // IRCFx = 101
    //OSCTUNEbits.PLLEN = 0;                //PLL disabled

    TRISDbits.TRISD7 = 0;

    T2CON  = 0b00000101;                    //timer2 on
    PR2    = 240;
    CCPR1L = 0x78;
    CCP1CON= 0b01001100;



LATDbits.LATD7=0;
Delay1KTCYx(1000);

while(1);
}

3 个答案:

答案 0 :(得分:6)

当我进行嵌入式编程时,我发现添加注释非常有用,可以解释我在设置配置寄存器时的确切意图。这样我就不必返回数据表来确定{I}在我下次需要更改代码时尝试查看代码时的作用。 (请务必保持评论与更改保持同步)。

根据我的解码,看起来你已经设置了PWM寄存器,但没办法按照你想要的间隔改变频率。有几种方法可以做到,这里有两个想法:

  • 您可以在启动时读取计时器,添加所需的间隔以获取目标时间,并在while循环中轮询计时器。当定时器到达目标时,设置新的PWM占空比,并将下一个间隔添加到目标时间。这样可以正常工作,直到你需要在后台循环中开始做其他事情。
  • 您可以将timer0的计数设置为0x01001010,并将其设置为在翻转时中断。在ISR中,设置新的PWM占空比,并将timer0 count重置为下一个间隔。

控制嵌入式进程中的时序的一种常见方法如下:

0xFFFF-interval

int flag=0; void main() { setup_interrupt(); //schedule interrupt for desired time. while (1) { if (flag) { update_something(); flag = 0; } } 在哪里设置?在中断处理程序中:

flag

你已经得到了你的例子中的所有部分,你只需要将它们放在正确的位置。在您的情况下,void InterruptHandler() { flag = 1; acknowledge_interupt_reg = 0; } 将更新PWM。逻辑看起来像是:“如果它打开,请将其关闭;否则打开它。如果需要,更新音调(占空比)”

主while循环中不需要额外的延迟或暂停。目标是它只是一次又一次地运行,等待一些事情要做。如果程序需要以不同的速率执行其他操作,则可以添加另一个标记,该标记完全独立触发,并且两个任务的时间不会相互干扰。

答案 1 :(得分:0)

编辑:
我现在对你想要完成的事感到困惑。你想要一系列相同音调的脉冲(开 - 关 - 开)吗?或者你想要一系列不同的音符而没有停顿(do-re-me-fa -...)?我一直在假设后者,但现在我不确定。


看到更新的代码后,我不确定您的系统是如何配置的,所以我只想问一些我希望有用的问题。

  1. PWM部分有效吗?你有最初的基调吗?我假设是的。
  2. 您的硬件是否有某种时钟脉冲连接到RA4 / T0CKI引脚?如果没有,则需要T0为时钟模式,而不是计数器模式。
  3. 是否正在调用中断?您正在设置INT0IE,它启用外部中断,而不是定时器中断
  4. 您需要在音调更新之间的间隔时间间隔?现在,你得到0xFFFF / (clock_freq/8)如果你想要不同的东西,你需要设置TMR0H / L寄存器。
  5. LATD7上有什么?你为什么要清理它? 你是说它能启用PWM输出吗?
  6. 为什么要拨打Delay()?计时器本身应该提供所需的延迟。 关于如何进行计时似乎存在脱节。我会扩展我的其他答案
  7. 你想在哪里改变PWM频率?你不需要写PR2吗? 您需要为每种不同的音调赋予不同的值。

  8.   

    “按要求暂停第一次失败的构建。”

    这只是说你有一些语法错误,没有向我们显示错误报告,我们无法提供帮助。

答案 2 :(得分:-2)

在Windows中,您可以使用kernel32中的Beep功能:

    [DllImport("kernel32.dll")]
    private static extern bool Beep(int frequency, int duration);