使用C编程以一定的时间间隔产生音调
我使用 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);
}
Im using C language for a PIC18F to produce tones such that each of them plays at certain time-interval. I used PWM to produce a tone. But I don't know how to create the intervals. Here is my attempt.
#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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当我进行嵌入式编程时,我发现添加注释来准确解释我在设置配置寄存器时的意图非常有用。 这样,当我下次必须更改代码时,我不必返回数据表来弄清楚
0x01001010
的作用。 (请确保评论与更改保持同步)。从我可以解码的情况来看,您似乎已经设置了 PWM 寄存器,但无法按照所需的间隔更改频率。 有几种方法可以做到这一点,这里有两个想法:
0xFFFF-interval
,并将其设置为在翻转时中断。 在 ISR 中,设置新的 PWM 占空比,并将 Timer0 计数重置为下一个间隔。在嵌入式进程中控制时序的一种常见方法如下所示:
flag
在哪里设置? 在中断处理程序中:您已获得示例中的所有部分,只需将它们放在正确的位置即可。 在您的情况下,
update_something()
将更新 PWM。 逻辑如下:“如果它打开,则将其关闭;否则将其打开。如果需要,请更新音调(占空比)”主 while 循环中不需要额外的延迟或暂停。 目标是它一遍又一遍地运行,等待执行某些操作。 如果程序需要以不同的速率做其他事情,可以添加另一个标志,该标志完全独立触发,两个任务的时间不会互相干扰。
When I'm doing embedded programming, I find it extremely useful to add comments explaining exactly what I'm intending when I'm set configuration registers. That way I don't have to go back to the data sheets to figure out what
0x01001010
does when I'm trying to grok the code the next time I have to change it. (Just be sure to keep the comments in sync with the changes).From what I can decode, it looks like you've got the PWM registers set up, but no way to change the frequency at your desired intervals. There are a few ways to do it, here are 2 ideas:
0xFFFF-interval
, and set it to interrupt on rollover. In the ISR, set the new PWM duty cycle, and reset timer0 count to the next interval.One common way of controlling timing in embedded processes looks like this:
Where does
flag
get set? In the interrupt handler:You've got all the pieces in your example, you just need to put them together in the right places. In your case,
update_something()
would update the PWM. The logic would look like: "If it's on, turn it off; else turn it on. Update the tone (duty cycle) if desired"There should be no need for additional delays or pauses in the main while loop. The goal is that it just runs over and over again, waiting for something to do. If the program needs to do something else at a different rate, you can add another flag, which is triggered completely independently, and the timing of the two tasks won't interfere with each other.
编辑:
我现在对你想要实现的目标感到困惑。 您想要一系列相同音调的脉冲(开-关-开-关)吗? 或者您想要一系列没有停顿的不同音符(do-re-me-fa-...)? 我一直假设是后者,但现在我不确定。
看到您更新的代码后,我不确定您的系统是如何配置的,所以我只想问一些问题,希望对您有所帮助。
PWM部分工作正常吗? 你听懂初始音了吗? 我假设是的。您的硬件是否有某种时钟脉冲连接到 RA4/T0CKI 引脚? 如果不是,则需要T0为时钟模式,而不是计数器模式。中断正在被调用吗? 您正在设置 INT0IE,它启用外部中断,而不是定时器中断您希望音调更新之间的间隔是多少? 现在,您得到0xFFFF / (clock_freq/8)
如果您想要不同的东西,您需要设置 TMR0H/L 寄存器。这只是说您有一些语法错误,没有向我们显示错误报告,我们无法真正提供帮助。
EDIT:
I'm now confused about what you are trying to accomplish. Do you want a series of pulses of the same tone (on-off-on-off)? Or do you want a series of different notes without pauses (do-re-me-fa-...)? I had been assuming the latter, but now I'm not sure.
After seeing your updated code, I'm not sure exactly how your system is configured, so I'm just going to ask some questions I hope are helpful.
Is the PWM part working? Do you get the initial tone? I'm assuming yes.Does your hardware have some sort of clock pulse hooked up to the RA4/T0CKI pin? If not, you need T0 to be clock mode, not counter mode.Is the interrupt being called? You are setting INT0IE, which enables the external interrupt, not the timer interruptWhat interval do you want between tone updates? Right now, you are getting0xFFFF / (clock_freq/8)
You need to set the TMR0H/L registers if you want something different.This just says you have some syntax error, without showing us the error report, we can't really help.
在 Windows 中,您可以使用 kernel32 中的 Beep 功能:
In Windows you can use the Beep function in kernel32: