Пропуск такта при формировании сигнала (меандр)
- Войдите на сайт для отправки комментариев
Вс, 08/06/2014 - 18:19
Здравствуйте.
При формировании на выходе простого сигнала, например как демонстрационная программа "Blink", примерно каждую секунду или даже чаще контролер пропускает такт, что естественно ведёт с фазовому сдвигу сигнала. Я использую задержку в микросекундах, программа вроде как примитивная... То ли это загрузчик периодически обнуляет контролер, то ли ещё чего, но осциллограмма примерно такая:
П_П_П_П_ПП_П_П_П_П, где двойное П - просто единица два такта, потом опять продолжает работать.
Программа:
/***** Делаю генерацию на 12 выводе *****/
int Ped = 12;
void setup()
{
pinMode(Ped, OUTPUT);
}
void loop()
{
digitalWrite(Ped, HIGH);
delayMicroseconds(2);
digitalWrite(Ped, LOW);
delayMicroseconds(2);
}
С чем связан перезапуск?
Возможно связано с прерываниями...
Любые задержки с помощью функций типа delay... как бы то ни было дают примерную задержку. Если нужны точные задержки/формирование импульсов, нужно использовать таймеры. Тогда никакие прерывания или еще что то не будет мешать формированию импульсов - всё аппаратно.
delayMicroseconds особая функция, которая не использует таймер для формирования задержки, потому ТОЛЬКО для этого скетча можно попробовать запретить прерывания и проверить, импульсы должны быть ровными. Но это "костыль", "затычка".
Здесь получается не примерная задержка, хотя длительность импульсов дребезжит примерно до 5 процентов по времени, в среднем, а просто интересно, почему пропускает целую команду. На социллографе выглядит, что команда на установку вывода в ноль периодически пропускается.
Или в команде void setup() есть ещё какие-то установки, которые идут автоматом, ну вроде запущеного сторожевого таймера?
Дополнение: пропускаются как переключение в единицу, так и в ноль. При этом на других выводах процессора изменений нет. Какое-то прерывание, записанное "подпольно" ))).
Кстати, период следования этих пропусков переключения примерно 1,1 миллисекунды.
Arduino UNO
Спасибо.
Чуть по-другому напишу.
Каждую миллисекунду Ардуин игнорирует какую-нибудь команду. В данном случае каждую миллисекунду процессор делает что-то, что не написано в скетче, то есть не смотря на всю правильность кода, процессор сделает операцию, кода которой не существует. Если программа будет больше в несколько раз, можно бесконечно перебирать код и ничего не найти?
Или достаточно описать состояние всех прерываний, не оставлять их на откуп судьбе?
Там программа много чего делает, что в скетче не написано. Я так поступаю:
...
void loop(){
noInterrupts();
while(1){
//do something
}
В таком виде всё стало работать красиво и правильно, частота получилась 102,6 килогерца, дребезга фронтов нет, пропуска команд нет.
Спасибо за науку!
Можно значительно ускориться если не использовать digitalWrite, а записывать биты непосредственно в порт PORTx = B11111111; и если время у счетчика TCNTx брать
Был интересен именно этот простейший вариант, светодиодом поморгал раз в секунду - хорошо!
Теперь всё то же самое, только моргаем чаще, а оно воно как вышло. Но я только учусь. )))