Во всех микроконтроллерах AVR есть конфигурационные fuse биты. Это такие биты, которые задают ряд глобальных настроек микроконтроллера, например, источник тактового сигнала, пороговое напряжение схемы сброса, размер загрузочной области, разрешение сторожевого таймера и т.д. 
   Fuse биты хранятся во флэш памяти, поэтому сохраняют свое значение при отсутствии питания. Обычно они устанавливается однократно на этапе первичного программирования прошивки.
   Неправильно установленные fuse биты могут нарушить работу системы. В лучшем случае микроконтроллер будет работать, например, на неправильной частоте, а в худшем мы потеряем возможность программирования микроконтроллера по SPI интерфейсу. Это может произойти или по не знанию, или в результате случайной ошибки.
   Существует способ, который может предотвратить часть таких ситуаций. Он состоит в том, чтобы заложить в программу микроконтроллера сравнение fuse битов с требуемыми значениями. Что-то вроде самоконтроля. Но для того чтобы их можно было проверять, их нужно сначала прочитать. И сейчас мы разберемся, как это сделать.

 Майкл Барр

 Когда я разговариваю с Си программистами об аппаратных интерфейсах или стандарте программирования, я часто вижу, что они не обладают необходимыми навыками и информацией об этом языке программирования. Как правило, это потому, что все мы в основном инженеры-электронщики, которые изучали Си (или какой-нибудь другой язык) самостоятельно. 

   Один из таких навыков относится к созданию заголовочных файлов. Что нужно (или не нужно) размещать в заголовочном Си файле .h? Когда нужно создавать заголовочный файл? И почему?
   На перечисленные вопросы у меня есть свой список ответов.

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

   Существует интересный макрос, который используется для определения количества элементов в объявленном массиве. Его обычное определение выглядит так:

#define N_ELEMENTS(X) (sizeof(X)/sizeof(*(X)))

   Данный макрос удобно применять для перебора всех элементов массива в циклах.

void foo(void)
{
   uint8_t bar[] = {0, 1, 2, 3, 4};
   uint8_t i;

   /* передать каждый элемент массива bar[] */
   for (i = 0; i < N_ELEMENTS(bar); ++i){
      txc(bar[i]);
   }
}

   Внутренняя программа микроконтроллера AVR может читать и записывать любой байт EEPROM памяти. Однако при программировании EEPROM`a внешним программатором чтение и запись осуществляется постранично. В зависимости от типа микроконтроллера страницы EEPROM памяти имеют разный размер. Например, у микроконтроллера atmega16 размер страницы EEPROM памяти равен 4-ем байтам. 
   Существует мнение, что заявленный производителем ресурс EEPROM памяти AVR микроконтроллеров, равный 100000 циклов запись/чтение, относится не к единичной ячейке памяти, а к целой странице. То есть если мы в один байт EEPROM`а atmega16 запишем 100000 раз, остальные три ячейки страницы памяти потеряют свой ресурс, будучи вроде ни разу не тронутыми. 
   Мне стало интересно узнать, соответствует ли это действительности, и я провел небольшой тест EEPROM памяти atmega16. Понятно, что этот тест не является каким-то глубоким научным исследованием, но это все же лучше, чем ничего.