Я не могу точно указать конкретную ошибку, но у вас есть некоторые проблемы в этом коде.
Основная проблема заключается в том, что 8051 был не ПК, а самым ужасным 8-битным MCU, когда-либо ставшим мейнстримом.Это означает, что вы должны отчаянно избегать таких вещей, как 32-битные целые числа и числа с плавающей запятой.Если вы разберете этот код, вы поймете, что я имею в виду.
Нет абсолютно никаких причин, по которым вам нужно использовать здесь с плавающей точкой.И 32-битных переменных, вероятно, тоже можно избежать.Вы должны использовать uint8_t
, когда это возможно, и избегать unsigned int
тоже.Ваш код C не должен знать время в секундах или частоту в Гц, а просто заботиться о количестве циклов таймера.
У вас есть несколько ошибок состояния гонки.Ваш goto
взлом в основном - грязное решение - вместо этого вы должны предотвратить возникновение состояния гонки.И у вас есть другое условие гонки между ISR с timer3_overflow_tmp
.
Каждая переменная, совместно используемая между ISR и main
, или между двумя различными ISR с разными приоритетами, должна быть защищена от условий гонки.Это означает, что вы должны либо обеспечить атомарный доступ, либо использовать какой-либо механизм защиты.В этом случае вы могли бы просто использовать "мьютекс бедняка" bool flag.Другой альтернативой является изменение 8-битной переменной и запись кода, обращающегося к ней, во встроенном ассемблере.Как правило, у вас не может быть атомарного доступа на unsigned int
на 8-битном ядре.