2009-03-02 1 views
3

Im использует язык 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); 
} 
+0

Как насчет добавления «PIC18F» в качестве метки? – Johan

ответ

-2

В Windows вы можете использовать функцию звукового сигнала в kernel32:

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

и в вашем автомобиле вы можете использовать звуковой сигнал ... (к сожалению, он встроен в процессор). – AShelly

+0

Не нужно зарываться. Я просто неправильно понял контекст вопроса ... –

+0

+1 за хороший смех. – Nate

6

Когда я делаю встроенных программ, я нахожу это чрезвычайно полезно добавлять комментарии объясняя именно то, что я намерен, когда я 'm устанавливает регистры конфигурации. Таким образом, мне не нужно возвращаться к листам данных, чтобы выяснить, что делает 0x01001010, когда я пытаюсь получить код в следующий раз, когда мне нужно его изменить. (Просто не забудьте сохранить комментарии в синхронизации с изменениями).

Из того, что я могу расшифровать, похоже, что у вас настроены регистры PWM, но нет возможности изменить частоту в нужные промежутки времени. Есть несколько способов сделать это, вот 2 идеи:

  • Вы можете прочитать таймер при запуске, добавить желаемый интервал, чтобы получить целевое время, и опросить таймер в цикле while. Когда таймер попадает в цель, установите новый рабочий цикл PWM и добавьте следующий интервал в целевое время. Это будет работать нормально, пока вам не придется начинать делать другие вещи в фоновом цикле.
  • Вы можете установить счетчик таймера 0 на 0xFFFF-interval и настроить его на прерывание при опрокидывании. В ISR установите новый рабочий цикл ШИМ и сбросьте таймер 0 на следующий интервал.

Один общий способ контроля времени во встроенных процессов выглядит следующим образом:

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; 
} 

У вас есть все части в вашем примере, нужно просто поставить их в нужных местах. В вашем случае update_something() обновит PWM. Логика выглядела бы так: «Если она включена, выключите ее, а затем включите ее. Обновите тон (рабочий цикл), если хотите»

В основной петле во время работы не должно быть необходимости в дополнительных задержках или паузах. Цель состоит в том, что он просто работает снова и снова, ожидая чего-то сделать. Если программе нужно сделать что-то другое с другой скоростью, вы можете добавить еще один флаг, который запускается полностью независимо, а время выполнения этих двух задач не будет мешать друг другу.

0

EDIT:
теперь я запутался о том, что вы пытаетесь достичь. Вам нужна серия импульсов одного и того же тона (включено-выключено)? Или вы хотите серию разных заметок без пауз (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. Где вы пытаетесь изменить частоту ШИМ? Вам не нужно писать на PR2? Вам нужно будет дать ему другое значение для каждого тона.

"Приостановление построить на первый провал, как просили."

Это просто говорит, что у вас есть синтаксическая ошибка, не показывая нам отчет об ошибке, мы не можем реально помочь.

Смежные вопросы