Когда я занимаюсь встроенным программированием, я нахожу чрезвычайно полезным добавлять комментарии, поясняющие, что именно я собираюсь делать, когда я устанавливаю регистры конфигурации. Таким образом, мне не нужно возвращаться к таблицам данных, чтобы выяснить, что делает 0x01001010
, когда я пытаюсь получить код в следующий раз, когда мне придется его изменить. (Обязательно синхронизируйте комментарии с изменениями).
Из того, что я могу декодировать, похоже, что у вас настроены ШИМ-регистры, но нет способа изменить частоту с нужными интервалами. Есть несколько способов сделать это, вот две идеи:
- Вы можете прочитать таймер при запуске, добавить желаемый интервал, чтобы получить целевое время, и опрашивать таймер в цикле while. Когда таймер достигнет цели, установите новый рабочий цикл ШИМ и добавьте следующий интервал к целевому времени. Это будет работать нормально, пока вам не нужно будет заняться другими вещами в фоновом цикле.
- Вы можете установить счетчик таймера 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()
обновит ШИМ. Логика будет выглядеть следующим образом: «Если он включен, выключите его; в противном случае включите его. Обновите тональный сигнал (рабочий цикл), если необходимо» *
Не должно быть необходимости в дополнительных задержках или паузах в основном цикле while. Цель в том, чтобы он просто бегал снова и снова, ожидая, что что-то сделать. Если программе нужно сделать что-то еще с другой скоростью, вы можете добавить еще один флаг, который срабатывает совершенно независимо, и синхронизация этих двух задач не будет мешать друг другу.