Я сделал простую программу, которая работает на микроконтроллере P12F629, используя MikroC.
Мне нужно выполнить некоторые критичные ко времени задачи (например, увеличить внутренние часы, вывести данные на светодиодную матрицу и т. д.).
Вместо простого цикла + Delay_ms()
(который имеет свой набор проблем) я использую прерывание:
void main()
{
InitTimer0();
while(1);
}
void InitTimer0()
{
//setup timer0 interrupt
//...
}
void Interrupt() //will be fired every x ms
{
//perform some time-critical tasks
//e.g. increase internal clock
//...
}
Проблема в том, что while
петля потребляет циклы ЦП впустую (и, таким образом, сокращает время работы от батареи).
Есть ли способ избежать этого?
Если я уберу while(1);
вызов в конце main()
, программа будет работать точно так же. Есть ли разница? Поможет ли добавление Delay_ms(1000)
вызова внутри цикла while снизить нагрузку на ЦП?
Насколько я помню, в x86 есть halt
инструкция, которая останавливает ЦП до тех пор, пока не будет запущено внешнее прерывание. Здесь было бы идеально. Есть ли такое в MikroC?
Если вы управляете светодиодной матрицей, я бы не подумал, что микропотребление энергии будет таким значительным.
Если вы переведете микроконтроллер в спящий режим, часы остановятся, и вы не получите прерывания от таймера 0, чтобы вернуть его обратно. Вы можете использовать сторожевой таймер, чтобы вернуть его обратно, но он очень переменный, и задержка может достигать 25 мс.
Если вы действительно хотите снизить энергопотребление и сохранить время, вы можете запустить микро с кристаллом 32 кГц, который будет поддерживать разумное время и потреблять только микроампер (в зависимости от того, что еще включено).
Вам нужно RTFM ( datasheet ) о различных типах и режимах часов. Также есть справочное руководство от Microchip с дополнительной информацией. И тогда вы сможете понять, как заставить ваш компилятор давать требуемые инструкции чипу.
Игнасио Васкес-Абрамс