Обновлено 9.04.15. Здравствуйте дорогие друзья. В предыдущей статье мы с Вами рассмотрели подключение и алгоритм работы с семи сегментным индикатором. В этом посте я расскажу о цифровых датчиках температуры ds18b20 . Рассмотрим подключение, напишем программу на Си используя техническую документацию.
Познакомимся с интерфейсом 1-Wire. Выведем температуру на индикатор.
Итак из технического описания DS18B20 – это цифровой термометр ,датчик температуры, разрешающая способность измерения температуры, которого, может быть установлена от 9 до 12 бит. Диапазон измерений от –55°C до +125°C . Датчик фирмы DALLAS Semiconductor, работает как один так и вгруппе с другими НА ОДНОЙ ЛИНИИ через интерфейс 1-Wire. Что и является изюминкой данного «девайса».
Язык Си: компиляция в Visual Studio Code ПРОСТО
Что ж разберем далее что из себя представляет данный интерфейс.
1-Wire — двунаправленная шина связи для устройств с низкоскоростной передачей данных (обычно 15,4 Кбит/с, максимум 125 Кбит/с в режиме overdrive), в которой данные передаются по цепи питания (то есть всего используются два провода — один для заземления, а второй для питания и данных; в некоторых случаях используют и отдельный провод питания) — разработана корпорацией Dallas Semiconductor и является её зарегистрированной торговой маркой. Соответственно, топология такой сети — общая шина. Сеть устройств 1-Wire со связанным основным устройством названа «MicroLan», это также торговая марка Dallas Semiconductor.
. Данная шина относительно дешевая и требует небольшой пайки, подходит для пассивных датчиков (температура, влажность и др.). Не подходит для датчиков света и движения, является несимметричной, имеет высокий импеданс, чувствительна к шуму. На больших расстояниях, проходящая через потребителей наводящих наводку на линии будет много мусора. В данном случае используют CAN–шину (CAN STM32 SPL №98). Данный протокол широко используется в промышленности для обмена информации, слежением за состоянием узлов и проектирования приложения диагностики. (Слева контроллер CAN шины . Справа пример приложения диагностики ).
На рисунке ниже приведена схема подключения датчика с внешним питанием.
При подключении главное не перепутать полюс питания, т.к. погреется и выйдет из строя – горький опыт. Что ж давайте разберем даташит.
Давайте попробуем разобраться в алгоритме. Я буду писать как можно проще, самые основные функции. Для анализа я брал библиотеку аппноута 318 (протокол 1-Wire для семейства датчиков ds) а также библиотеки слегка измененные.
КАК ЧИТАТЬ И ПОНИМАТЬ С/C++ КОД?
Первое что нам надо знать, это как работать с данным интерфейсом. Так вот основные операции, это импульс сброса, запись бита и чтение. В даташите приведены тайм слоты для всех этих операций. Итак начнем писать. Для оживления датчика необходимо подать импульс сброса, а микроконтроллер должен получить сигнал присутствия.
На диаграмме ниже приведены временные задержки для инициализации.
Микроконтроллер на 480 мкс «проваливает» шину в ноль, а затем «отпускает» ее. Если к шине подключен термометр , то он обнаруживает положительный перепад и после паузы в 15-60 мкс уже датчик отвечает микроконтроллеру импульсом присутствия — «проваливает» шину в ноль на время от 60 до 240 мкс.
1. Функция инициализации на СИ.
init_devise () //функция инициализации датчика
<
cli (); //Запретим общие прерывания
DDRC |= _BV (PC2); //1 — выход
PORTC //0
_delay_us (480); //задержка 480 мкс
//«отпускает»
DDRC //0 — вход
PORTC //0
_delay_us (70); //задержка 70 мкс ,берем чуть больше после перепада
if (!(PINC2 /*Вывожу на индикатор единицы, если сигнал присутствует*/
else
Display (000); // иначе на индикатор выводится нули
_delay_us (410); //остальная задержка для окончания импульса присутствия
sei (); // разрешаем прерывания
>
Датчики откликнулись и готовы к приему команд. Т.к. у нас несколько датчиков на линии, то нам необходимо послать команду SEARCH ROM [F0h] — (ПОИСК ROM) – эта команда идентификация кодов ROM всех подчиненных устройств на шине. Эту процедуру необходимо выполнить столько раз, сколько датчиков, чтобы идентифицировать все из подчиненных устройств. Если есть только одно подчиненное устройство на шине.
Напишем функцию по отправке команд. Временные задержки расписаны на временной диаграмме, на рисунке ниже.
Обмен данными по шине происходит последовательно, младшим битом вперед. Передача или прием одного бита данных выполняются в течении фиксированного промежутка времени, так называемого тайм слота (time slot). Различают тайм слоты записи и тайм слоты чтения. Длительность всех тайм слотов должна быть > 60 мкс, а пауза между тайм слотами > 1 мкс.
Для передачи нуля микроконтроллер «проваливает» 1-Wire шину на время от 60 до 120 мкс. Затем «отпускает» ее и перед записью следующего бита выдерживает паузу >1 мкс.
Для передачи единицы микроконтроллер «проваливает» 1-Wire шину на время от 1 до 15 мкс, «отпускает» ее и выдерживает паузу. Пауза должна быть такой, чтобы длительность тайм слота была > 60+1 мкс.
2. Функция передачи комманды.
send_command (unsigned char command)
<
unsigned char i;
for (i=0; i < 8; i++)
<
if (command
cli (); //Запретим общие прерывания
DDRC |= _BV (PC2); //1 — выход
PORTC //0
_delay_us (15); //задержка 15 мкс
//«отпускает»
DDRC //0 — вход
PORTC //0
_delay_us (45); //задержка 46 мкс ,берем чуть больше
sei (); // разрешаем прерывания
>
else //передаем 0
<
cli (); //Запретим общие прерывания
DDRC |= _BV (PC2); //1 — выход
PORTC //0
_delay_us (120); //задержка 120 мкс
//«отпускает»
DDRC //0 — вход
PORTC //0
_delay_us (1); //задержка перед записью следующего бита
sei (); // разрешаем прерывания
>
command >>= 1; //сдвигаем для обработки следующего бита
>
>
Команду отправили. Все устройства на линии, начинают генерировать свои уникальные 64-битные коды, одновременно, причем посылают каждый бит дважды, первый фактический, втрой инверсный, т.е. микроконтроллер считывает состояние одного бита в течение двух Времен (тактов). Общий сигнал на линии формируется по законам умножения логического «И». Далее нам необходимо прочитать эти биты.
DS18B20 является подчиненным устройством и может передавать данные, только когда микроконтроллер формирует на шине тайм слоты чтения. Для формирования тайм слота чтения микроконтроллер «проваливает» шину на время от 1 до 15 мкс, а затем «отпускает» ее, передавая управление состоянием шины датчику. Если термометр передает ноль, он удерживает шину в «проваленном» состоянии (в состоянии логического нуля) до конца тайм слота. Если он передает 1, он оставляет шину в «подтянутом» состоянии. Микроконтроллер может считывать данные датчика DS18B20 через 15 мкс после начала тайм слота чтения.
3. Напишем функцию чтения битов.
unsigned char read_data (void)
<
unsigned char bit;
cli (); //Запретим общие прерывания
DDRC |= _BV (PC2); //1 — выход
PORTC //0
_delay_us (15); //задержка 15 мкс
//«отпускает», управление передается датчику
DDRC //0 — вход
PORTC //0
bit1 = (PINC
_delay_us (45); //задержка 1 мкс ,перед записью следующего бита
sei (); // разрешаем прерывания
return bit;
>
Написали, теперь давайте разберемся в алгоритме распознавания устройств. Техническая документация говорит следующее: если все устройства содержат в этой позиции двоичного разряда:
• «0», чтение будет «01»;
• «1», результат будет «10»;
Если устройства содержат в этой позиции двоичного разряда и «1» и «0», чтение приведет «00» битов, указывая на конфликт. Главное устройство в следующем (третьем такте) слоте Времени формирует разрядное значение 1 или 0, чтобы отобрать устройства, которые останутся в процессе выбора.
Все устройства у которых бит не соответствует биту сформированному главным устройством перейдут в состояние ожидания и будут находиться в нем пока они не получат импульс Сброса. После первой стадия выбора, будут следовать 63 читающих/выбора цикла, пока, наконец, главное устройство не определит Код ROM одного подчиненного устройства и обратиться к нему. Каждая стадия выбора состоит из двух слотов Времени считывания и один слот Времени записи. Полный процесс изучения и одновременная адресация — приблизительно три раза длина команды ROM Соответствия, но это позволяет выбрать из всех связанных устройств последовательно все коды ROM.
4. Что ж давайте напишем функцию, соответствующую этому алгоритму. Функция поиска датчиков.
if (n == 0) //переменная, для одного входа в цикл поиска всех датчиков
<
unsigned char p = 1; // переменная для цикла считыввания кода
unsigned char bit = 0×01; // начальная позиция бита
unsigned char New_conflict = 0; //переменная для нвой позиции бита
unsigned char last_conflict = 0; //переменная для старой позиции бита
for (i = 0; i < 2; i++) //обнулим массив
<
for (j = 0; j < 8; j++) //8-м байт
<
data[i][j] = 0×00;
>
>
j = 0; //обнуляем
i = 0; //обнуляем
unsigned char bit1, bit2; //для сравнения битов двух тайм слотов
do
<
New_conflict = 0;
n++;
init_devise (); // импульс сброса
send_command (0xf0); // команда поиска
// сигнал сброса и команда поиска необходимо подавать для каждого датчика
while (p <
bit1 = read_data (); //первый тайм-слот
bit2 = read_data (); //второй тайм-слот
if (bit1 bit2) /*сравниваем полученные биты , если обе единицы*/
Display (000); // датчиков нет на линии
else if ((bit1) (!bit2))
data[i][j] |= bit; //записываем бит
else if ((!bit1) (bit2))
data[i][j]
else if ((!bit1) (!bit2)) //Конфликт оба 0
<
/*сдесь будем сравнивать позиции битов, в номерах которых произошли конфликты в переменной N_conflict*/
if (p == last_conflict) /*если текущая позиция бита в котром произошел конфликт == позиции в предыдущем исчеслении (скорей всего 0-ая позиция), то запишем в адресс 1*/
data[i][j] |= bit;
else if (p > last_conflict) /* если номер позиции больше, номера предыдущего опроса, то запишем 0 и номер позиции конфликта обновим*/
<
data[i][j]
New_conflict = p;
>
/*если вдруг текущий номер позиции меньше, номера позиции предыдущего исчесления(Если вдруг текущий бит, при конфликте, при очередном исчеслении не дошел еще до номера конфликта предыдущего исчесления, содержит 0 , то это будет считаться новым конфликтом)*/
else if (!(data[i][j]
>
/* Далее запишем соответствующий бит, который при следующем исчеслении включит соответствующие устройства*/
if (data[i][j]
cli (); //Запретим общие прерывания
DDRC |= _BV (PC2); //1 — выход
PORTC //0
_delay_us (15); //задержка 15 мкс
DDRC //0 — вход
PORTC //0
_delay_us (45); sei (); // разрешаем прерывания
>
else //передаем 0
<
cli (); //Запретим общие прерывания
DDRC |= _BV (PC2); //1 — выход
PORTC //0
_delay_us (120); //задержка 120 мкс
DDRC //0 — вход
PORTC //0
_delay_us (1); //задержка 1 мкс ,перед записью ,бита
sei (); // разрешаем прерывания
>
p++; //увеличиваем на 1
bit if (!bit) //сдвиг проходит все 8 бит и значение равно 0
<
data[i][j++];
bit = 0×01;
>
> //выходит из цикла после обработки 64-х битов
last_conflict = New_conflict;
p = 1;
if (last_conflict != 0)
data[i++][j];
j = 0;
bit = 0×01;
> while (last_conflict != 0); /* пока номер бита конфликта не равен 0, если равен то все датчики найдены*/
Display (n); // выводим количество найденых датчиков
_delay_ms (1000);
>
Для подлинности целостности информации необходимо проверить переданный код. Для этих целей применяется CRC — это ( cyclic redundancy check) контроль при помощи циклического избыточного кода.
Основная идея алгоритма CRC состоит в представлении сообщения в виде огромного двоичного числа, делении его на другое фиксированное двоичное число и использовании остатка от этого деления в качестве контрольной суммы. Получив сообщение, приёмник должен выполнить аналогичное действие и сравнить полученный результат с принятой контрольной суммой.
Сообщение считается достоверным, если выполняется это равенство. В CRC алгоритме используется полиномиальная арифметика по модулю 2. Это означает, что действия, выполняемые во время вычисления CRC, являются арифметическими операциями без учёта переноса. То есть сложение и вычитание выполняются побитово без учёта переноса, благодаря чему эти две операции дают эквивалентный результат. Ниже представлена схема формирования контрольной суммы CRC-8. Порождающий многочлен g (x) = x8+x5+x4+1.
Устройство управления шиной может повторно вычислить циклический контроль избыточности и сравнить его со значениями циклического контроля избыточности от DS18B20, используя полиномиальный генератор, который показывается в иллюстрации выше. Эта схема состоит из сдвигового регистра и логического элемента XOR, биты сдвигового регистра инициализированы как 0. Старт с наименьшего значащего бита кода ROM или наименьшего значащего бита байта 0 в ОЗУ, один бит одновременно должен быть сдвинут в сдвиговом регистре. После смещения в 56-ом бите от ROM или наиболее значительного бита байта 7 от ОЗУ, полиномиальный генератор будет содержать перерасчетный циклический контроль избыточности. Затем, 8-битовый код ROM или сверхоперативный циклический контроль избыточности от датчика должен быть сдвинут в схеме. Если перерасчетный циклический контроль избыточности был правилен, сдвиговый регистр будет содержать все нули.
5. Функция проверки кода CRC.
i = 0; //обнулим, начнем проверрку с 0-х индексов
j = 0;
while (i != 2) /*обрабатываем количество устройствначинаем с последнего устройства*/
<
crc8 = 0;
for (j = 0; j < 7; j++)
<
unsigned char bit_crc; //локальная переменная
data_crc = data[i][j];
for (u = 0 ; u < 8; u++)
<
bit_crc = ((crc8 ^ data_crc)
if (bit_crc == 0)
crc8 >>= 1;
else
<
crc8 ^= 0×18; // 11000 , по модулю т.е. там где0 и 1 будут 1
crc8 >>= 1; //сдвгаем влево
crc8 |= 0×80; //+ 1000 0000
>
data_crc >>=1;
>
>
if (crc8 == data[i][j]) // если последний байт четности равныто хорошо
<
i++;
Display (i); //выводит количество
_delay_ms (1000);
j = 0;
>
else
Display (000); //На индикатор выведутся нули, если ошибки
>
Количество датчиков вычислено, начнем измерение температуры. Адреса датчиков у нас имеются. Необходимо обратится к датчику, с помощью команды соответствия, передать команду преобразование, считать данные с температурного регистра. На рисунке ниже представлены сверхоперативная память и регистр температуры.
TEMPERATURE REGISTER FORMAT
Здесь нам важно знать что при положительном результате S = 0, отрицательный S = 1. При 12-битном преобразовании все биты содержат значения, при 11 –битном 0-й неопределен, при 10 – битном 0-й и 1-й, при 9 – битном 0, 1 и 2 биты неопределенны. Это нам поможет при написании кода.
Этот код я связал с кодом с предыдущего поста, подключение семисегментного индикатора. На рисунке слева виден результат работы в железе на AVR. В последующих записях мы научились программу разбивать на библиотеки с возможностью настройки кода под свой «камень» и порты, там же исходники. Так что пробуем пишем, меняем, эксперементируем, оставляем комментарии. Здесь исходник выше приведенного кода и результатат в железе :
В следующей статье рассмотрим небольшой помощник для работы с микроконтроллерами — Atmega fusebit doctor. Который выручит в случаях, когда происходит неправильная конфигурация, либо другие непредвиденные ситуации и кажется что микроконтроллер «умер». Меня он выручил не раз. На этом все. До скорой встречи.
1. DS18B20 Programmable Resolution 1-Wire Digital Thermometer .DS18B20 русское описание работы с датчиком температуры. (2009).
Просмотрено 46619 раз.
Запись опубликована автором admin137 в рубрике Программы на Си для AVR с метками 1-Wire, AVR, CRC, ds18b20, Си. Добавьте в закладки постоянную ссылку.
Источник: www.ap-impulse.com
Как сделать калькулятор на C
В этой статье простым языком изложена вся необходимая информация для программирования калькулятора на языке C. Применяемая программа используется на лабораторных занятиях студентов инженерных специальностей первого года обучения. Так что любой студент, например изучающий математическое моделирование в биологии, сможет самостоятельно запрограммировать калькулятор. Попробуем сделать калькулятор и мы.
Цель этой программы
Сделать простой калькулятор на языке программирования C с помощью оператора switch .
Понятия, используемые в программе
Типы данных
Тип данных указывает на вид данных, которые может хранить переменная, например целочисленные типы, числа с плавающей запятой, символьные типы данных и т. д.
В этой программе использованы целочисленные и символьные типы данных — int и char соответственно.
int
Переменная int используется для хранения целых чисел.
Синтаксис для int : int variable_name =integer ; .
Например: int a=10; .
char
Самый распространенный тип данных на C. Он занимает в памяти один байт почти во всех компиляторах.
Синтаксис для char : char variable_name=”single character”; .
Например: char b=”x”; .
Операторы switch
Переключатель (оператор switch ) позволяет проверить переменную на соответствие по списку значений. Каждое значение называется случаем ( case ), и переменная, для которой задействуется оператор switch , проверяется для каждого случая внутри switch .
Синтаксис для switch :
switch(expression)
Алгоритм для этой программы
Шаг 1: начало.
Шаг 2: объявляется переменная n, a, b, c типа данных int .
Шаг 3: отображается меню для пользователя.
Шаг 4: читается значение n от пользователя.
Шаг 5: при вводе пользователем любого числа от 1 до 5 выполняется следующий шаг согласно случаю, соответствующему введенному числу.
Шаг 6:
a) случай 1. Читаются значения a и b. Высчитывается сумма a и b. Результат отображается с помощью break; .
б) случай 2. Читаются значения a и b. Высчитывается разность a и b. Результат отображается с помощью break; .
в) случай 3. Читаются значения a и b. Высчитывается произведение a и b. Результат отображается с помощью break; .
г) случай 4. Читаются значения a и b. Высчитывается частное от деления а на b. Результат отображается с помощью break; .
д) случай 5. Читаются значения a и b. Высчитывается квадрат а. Результат отображается с помощью break; .
е) default: отображается Invalid .
Шаг 7: конец.
Блок-схема
Что такое « #include »?
Заголовочный файл stdio. h расшифровывается как “standard input output” («стандартный ввод/вывод»). В нем содержится информация, связанная с функциями ввода/вывода.
Что такое « #include »?
#includeconio. h> — это заголовочный файл, используемый на C, в котором находятся встроенные функции, такие как getch() и clrscr() . Расшифровывается он как “console input ouput” («ввод/вывод на консоль»), т. е. он принимает ввод с клавиатуры и отображает его на экране.
Что такое « main »?
Функция main() — это точка входа любой программы на Си. Здесь начинается выполнение программы. При этом контроль выполнения переходит непосредственно в функцию main() . Функция main() есть в каждой программе на C.
Что такое « printf » и « scanf »?
Функция printf() задействуется для отображения вывода, а функция scanf() — для принятия пользовательского ввода. Они часто используются в языке C, в частностив заголовочных файлах в качестве встроенных библиотечных функций.
Что такое « switch » и « case »?
Оператор switch позволяет проверить переменную на соответствие по списку значений. Каждое значение называется случаем ( case ), а переменная, для которой задействуется оператор switch , проверяется для каждого случая case внутри switch .
Что такое оператор « break »?
break — это ключевое слово, которое используется в языке C для вывода управления программой из цикла. Оператор break задействуется внутри циклов или внутри оператора switch , прерывая циклы один за другим. То есть в случае вложенных циклов сначала он прерывает внутренний цикл, а затем переходит к внешним.
А для чего на C нужен « default »?
Операторы switch и case используются только для конкретных значений выполняемых операторов case и для проверяемого выражения внутри switch . Когда выражение в switch не соответствует ни одному случаю case , программа выполняет операторы default .
Что такое « ruturn 0 »?
return 0 в функции main означает, что программа выполнена успешно и определяемая пользователем функция возвращает false . return 1 в функции main означает, что программа не выполнена успешно и есть какая-то ошибка, а определяемая пользователем функция возвращает true .
Программа / исходный код
/*Программа для создания калькулятора Имя разработчика: Vigneswaran*/ #include #include int main() < int a,b,n; clrscr(); printf(«Enter two numbers:»); scanf(«%d %d»,b); printf(«Enter your choice:n 1.Additionn 2.Subtractionn 3.multiplicationn») printf(«4.Divisionn 5.Square of a numbern»); scanf(«%d», switch(n) < case 1: printf(«The sum of %d and %d is %d «,a,b,a+b); break; case 2: printf(«The Subtraction of %d and %d is %d»,a,b,a-b); break; case 3: printf(«The multiplication of %d and %d is %d»,a,b,a*b); break; case 4: printf(«The division of %d and %d is %d»,a,b,a-b); break; case 5: printf(«The Subtraction of %d and %d is %d»,a,b,a-b); break; default: printf(«Invalid operation»); >getch(); return 0; >
Выполненный вывод
Надеемся, что статья была для вас полезной и легкой.
Источник: nuancesprog.ru
Как написать код для AVR, программирование микроконтроллеров Atmel AVR на Си
Что такое микроконтроллер? Микроконтроллер это по сути микрокомпьютер с процессором, оперативной и постоянной памятью, портами ввода-вывода, во многих микроконтроллерах имеется аналого цифровой преобразователь.
Прежде всего для написания программ под Atmel AVR нужно установить программу Atmel Studio, скачать ее можно с официального сайта Atmel сайта Microchip (Microchip выкупил Atmel), программа полностью бесплатна:
Для того, чтобы проверить написанную программу и постоянно не собирать на настоящих физических компонентах для проверки — понадобится также программа, эмулирующая работу железа, и эта программа — это Proteus, но вот она уже не бесплатна.
(Примечание — иногда результат работы на реальном железе может отличаться от результата эмуляции железа, так что при окончательном, финальном варианте написанной программы, проверка на реальном железе — обязательна).
Atmel Studio установлена.
(если при запуске или установке возникает ошибка «Cannot find one or more components.Please reinstall the application» (Не найден один или несколько компонентов.Пожалуйста, переустановите приложение.)- необходимо удалить программу, переименовать папку C:ProgramDataPackage Cache (не следует ее удалять, так как в случае чего, можно ее снова переименовать в исходное имя, если некоторые приложения после этого перестали работать), тогда программа установится и запустится нормально).
В левом верхнем углу выбираем:
File => New => Project
Выбираем GCC C Executable Project(на изображении под цифрой 1), В низу, в поле Name(2) указываем имя нашего проекта, в поле Location(3) можем выбрать местоположение проекта или оставить путь по умолчанию, нажимаем OK.
Затем выбираем модель нашего микроконтроллера из списка, в нашем случае это ATMEGA8(можно выбрать Attiny13 или другой нужный и имеющийся у вас микроконтроллер):
В окне появится среда разработки написания кода, где уже будет стандартный код на Си и несколько закомментированных строк с указанием авторства и даты:
Под цифрой 1 находится окно написания кода, под цифрой 2 файлы с исходным кодом, библиотеки и все файлы, связанные с исходным кодом, в файле main.c находится текст нашего кода.
Что же делает этот код?
строка #include подключает стандартную библиотеку портов ввода, вывода микроконтроллеров AVR,
ее можно найти по пути(если вы не поменяли путь при установке) «C:Program FilesAtmelStudio7.0toolchainavr8avr8-gnu-toolchainavrincludeavr»
Функция main — стандартная входная функция Си, с который программа и начинает работу.
Внутри функции main находится цикл while, который длится бесконечно.
А в теле цикла ничего нет т.е. программа ничего не делает , просто идет бесконечный цикл, и выхода из функции main не происходит , поэтому там нет ключевого слова return, которое возвращает указанное значение.
Для того, чтобы скомпилировать написанный код, необходимо выбрать вверху Build => Build «Имя_Вашего_Проекта».
Если код без ошибок, то программа скомпилируется и внизу будет написано Build succeeded.
В итоге скомпилированная прошивка будет в формате .HEX и будет лежать по адресу(опять же, если вы не изменили стандартное месторасположение):
C:UsersИмя ПользователяDocumentsAtmel Studio7.0ИмяПроектаИмяПроектаDebugИмяПроекта.hex
Примечание.Если выбрать вариант сборки Release, то прошивка будет лежать в соответствующей папке т.е. не в папке Debug, а в папке Release.
Код , который ничего не делает это не очень интересно, напишем программу, которая мигает 2 раза в секунду светодиодом:
#define F_CPU 1000000UL // 1 MHz Здесь задаем частоту микроконтроллера #include //библиотека вводавывода #include //библиотека задержки int main(void) // начало основой программы { DDRD = 0xff; // установить все порты D(смотрите распиновку мк) как выводы while (1) { // бесконечный цикл PORTD = 0xff; // установить «1»(вкл) на всех линиях порта D _delay_ms(250); // ждем 250 миллисекуд PORTD = 0x00; // установить «0»(выкл) на всех линиях порта D _delay_ms(250); // ждем 250 миллисекунд } //закрывающая скобка бесконечного цикла } //скобка входной функции main
Компилируем код, получаем готовую прошивку.
Прошиваем этой прошивкой микроконтроллер, собираем схему на железе.
Если не знаете как прошивать, узнать можно здесь:
В следующей статье узнаем как проверить написанный код в Proteus т.е. будем эмулировать работу железа.
ОЦЕНИТЕ ДАННУЮ ПУБЛИКАЦИЮ:
Средний рейтинг / 5. Количество оценок:
Мы сожалеем, что эта публикация Вас не устроила.
Напишите, пожалуйста, что Вам конкретно не понравилось, как можно улучшить статью?(оценка будет засчитана только при наличии отзыва)
Источник: lampcore.ru