Обсуждаем контроллеры компании Atmel.
Ответить

Нескольно простых вопросов о программировании AVR на Си.

Сб апр 12, 2014 16:38:45

1. Как правильно называется язык Си, на котором программируются контроллеры AVR (Atmega8 в частности) через программную среду AVR Studio 4 и 5? Что это - С, С++, С# или какая-то другая разновидность языка Си?

2. Не могу понять синтаксис этого долбаного языка. Например, что значит эта запись:
Код:
while ((PIND& (1<<PD0))==1){}

Ну цикл "while() {}" - это мне понятно.

Я не могу понять условие цикла. Там запись: "((PIND& (1<<PD0))==1)". Судя по всему, это проверяет состояние регистра PIND (в частности бита PD0) на равенство (==) единице. Но ппц, что это за запись у них? Зачем нужен "&"? Зачем нужен "(1<<PD0)"?

Почему бы не написать по-русски: (PIND(PD0) == 1) и поставить это в условие цикла "while"? Помогите мне понять синтаксис этой строки.

Re: Нескольно простых вопросов о программировании AVR на Си.

Сб апр 12, 2014 17:34:19

1 Си Си++
2 http://eugenemcu.ru/publ/2-1-0-53

Re: Нескольно простых вопросов о программировании AVR на Си.

Сб апр 12, 2014 18:27:15

Vova777 писал(а):Почему бы не написать по-русски: (PIND(PD0) == 1)

потому, что это не русский язык, а язык Си...

PIND - это с точки зрения языка Си обычная переменная
чтобы проверить какой-то бит в обычной переменной, надо выполнить битовую операцию над этой переменно - язык Си других вариантов не предусматривает
& - это битовое И
в результате мы получаем либо 0, либо не ноль. в языке Си "не ноль" для логических операций всегда приравнивается к 1.
== это логическая операция проверки на равенство

все понятно?

то, что написали вы с точки зрения компилятора Си будет означать "вызвать функцию PIND с аргументом PD0 и сравнить ее результат с 1. в сущности, все верно, кроме того, что PIND не функция, а переменная, т.е. это ошибочная запись.

Re: Нескольно простых вопросов о программировании AVR на Си.

Сб апр 12, 2014 18:46:35

oleg110592 писал(а):1 Си Си++
2 http://eugenemcu.ru/publ/2-1-0-53


Искренне Вам благодарен!

Синтаксис двух строк кода на языке Си.

Вс апр 13, 2014 10:57:49

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

Что значит запись:
Код:
PORTC &= ~(1 << RS);   // RS = 0

Взять число "1" (0b00000001), сдвинуть его влево на заданное кол-во бит ("RS"), инвертировать результат операции ("~"), затем провести над результатом и регистром "PORTC" операцию "побитового И" ("&"), а затем поместить результат в регистр "PORTC" ("=").

1) Т.е., если "RS=0", сдвиг числа "0b00000001" влево на "0" битов в результате даст это же число, т.е. "0b00000001".
2) В результате инверсии, получится число "0b11111110".
3) Побитовое И числа 0b11111110 и регистра PORTC (данный регистр полостью настроен на выход, состояние в данный момент "0b10000001") даст число "0b10000000" - которое и будет записано в регистр PORTC. Т.е., таким образом, я сбросил PC0.

Я все правильно интерпретировал?


- - - - - - - - - -


Что значит еще одна запись:
Код:
PORTC |= (1 << EN);    // EN = 1

Взять число "1" (0b00000001), сдвинуть его влево на заданное кол-во бит ("EN"), затем провести над результатом и регистром "PORTC" операцию "побитового ИЛИ" ("|"), а затем поместить результат в регистр "PORTC" ("=").

1) Т.е., если "EN=1", сдвиг числа "0b00000001" влево на "1" битов в результате даст число "0b00000010".
2) Побитовое ИЛИ числа 0b00000010 и регистра PORTC (данный регистр полостью настроен на выход, состояние в данный момент "0b10000001") даст число "0b10000011" - которое и будет записано в регистр PORTC. Т.е., таким образом я установил PC1.

Тут я тоже все правильно интерпретировал?

Re: Синтаксис двух строк кода на языке Си.

Вс апр 13, 2014 15:13:35

вы все интерпретировали правильно. первая запись служит для сброса в порту (переменной) бита RS, вторая для установки. в AVR-GCC, так же известном как WinAVR или AVR Toolchain, для выбора нужного бита используется макрос "Bit Value":
Код:
#define _BV(x) (1<<(x))
то есть ваши записи более кратко записываются так:
Код:
PORTC &= ~_BV(RS);
PORTC |= _BV(RS);

Re: Синтаксис двух строк кода на языке Си.

Вс апр 13, 2014 20:09:50

ARV писал(а):вы все интерпретировали правильно.

Вы невнимательно прочли то, что написал тредстартер.
То, что у него "совпал" ответ - случайность.
Вы пишете совершенно верно:
ARV писал(а):первая запись служит для сброса в порту (переменной) бита RS

А автор-то пишет совсем иное! Он какими-то сдвигами занимается. Получается, что эта команда влияет на ВСЕ биты регистра, к которому применяется? Но это ведь не так!


Vova777 писал(а):Я все правильно интерпретировал?

Нет.
Не происходит в этих операциях никаких сдвигов.
Запись (1 << RS) означает, что в бит RS (который должен быть определен заранее) заносится лог.1
Эта запись имеет смысл только с командой побитового ИЛИ (ассемблерная команда ori), так как значение остальных бит при этом равно нулю, только при команде or остальные биты не исказятся.
Например, запись:
Код:
.equ RS=4

ori R16,(1<<RS)

означает установку (запись лог.1) именно в 4-ый бит регистра R16, на остальные биты это не оказывает совершенно никакого влияния.

Запись ~(1<<RS) означает, что бит RS обнуляется. Запись имеет смысл только с командой побитового И (ассемблерная команда andi)
Например, запись
Код:
.equ RS=6

andi R16,~(1<<RS)

означает обнуление шестого бита регистра R16, остальные биты при этом не меняются.

Еще раз обращаю внимание, что при записи (1 << RS) значение остальных бит, кроме четвертого (если бит RS определен как четвертый) равно нулю. Именно поэтому запись
Код:
ori R16,(1<<RS)

корректна, а запись
Код:
andii R16,(1<<RS)
приведет к сбросу всех бит, кроме бита RS

Совершенно также обстоит и с записью ~(1<<RS), при которой бит RS сброшен (равен лог.0), а остальные биты установлены (равны лог.1).

Добавлю, что эти записи можно комбинировать (покажу на примере ассемблера):
Код:
ori R16,(1<<RS)|(1<<EN)

Данная запись установит в регистре R16 биты RS и EN. Повторюсь, что биты RS и EN должны быть заранее определены командой
Код:
.equ


Все, написанное выше, неверно. См. мое сообщение ниже.

Vova777 писал(а):Я только изучаю язык Си для микроконтроллеров AVR.

Я рекомендовал бы Вам обратить свой взгляд на ассемблер. Для 8-ми разрядных контроллеров применение Си не оправдано.
Последний раз редактировалось Alkul Вс апр 13, 2014 21:24:24, всего редактировалось 1 раз.

Re: Нескольно простых вопросов о программировании AVR на Си.

Вс апр 13, 2014 20:28:42

Alkul, не навязывайте свое недопонимание остальным участникам.

Re: Нескольно простых вопросов о программировании AVR на Си.

Вс апр 13, 2014 20:41:54

Не происходит в этих операциях никаких сдвигов.
Здрасте, приехали..., а что тогда означают стрелки ">>" и "<<", если подумать логически? Это и есть сдвиг, и двигает это все препроцессор, в результате всех логических операций в выражении, согласно приоритетам, получается некое число, которое и присваивается в конечном итоге операнду.
Запись (1 << RS) означает, что в бит RS (который должен быть определен заранее) заносится лог.1
Интересно, что произойдет, если записать так (0b101<<RS)?, получается, что в бит RS Я могу запихать такое число? Как раз эта запись означает сдвинуть число 0b101 влево на RS бит.

Re: Нескольно простых вопросов о программировании AVR на Си.

Вс апр 13, 2014 21:19:15

zero648 писал(а):Интересно, что произойдет, если записать так (0b101<<RS)?, получается, что в бит RS Я могу запихать такое число? Как раз эта запись означает сдвинуть число 0b101 влево на RS бит.

Согласен.
выполнение
Код:
ldi R16,(0b101<<2)

дает результат 0x14
Значит, Вы правы. Действительно сдвиг числа 0b101 (т.е., 0x05) влево на 2 как раз и даст результат 0x14 (0b00010100).
Согласен, был не прав.

"Век живи, век учись",- сказал поручик Ржевский. :))

P.S. Моё предыдущее сообщение ошибочно, но радикально править я его не буду, дабы не нарушать понимаемость всей ветки.

Re: Нескольно простых вопросов о программировании AVR на Си.

Вс апр 13, 2014 21:28:10

Последний пункт тоже не верен.

Re: Нескольно простых вопросов о программировании AVR на Си.

Вс апр 13, 2014 21:35:35

Flasher писал(а):Последний пункт тоже не верен.

Это вопрос спорный. Сможете доказать?

Re: Нескольно простых вопросов о программировании AVR на Си.

Вс апр 13, 2014 22:54:24

если последнее замечание касается вот этого "пункта"
Flasher писал(а):Я рекомендовал бы Вам обратить свой взгляд на ассемблер. Для 8-ми разрядных контроллеров применение Си не оправдано.
то я могу обосновать его "спорность" :)

в частности, я давно и успешно применяю Си для AVR, причем даже для малютки attiny13 (а есть примеры применения Си даже для attiny15, в котором нет ОЗУ!), при этом задачи я решаю не самые примитивные. Си позволяет сосредоточиться на алгоритме, что помогает при решении сложных задач.

тем не менее я не подвергаю сомнению желательность (а может, и необходимость) изучения ассемблера. но это отнюдь не первостепенная задача для начинающего.

Re: Нескольно простых вопросов о программировании AVR на Си.

Чт май 01, 2014 13:38:31

На ассемблере полезно и нужно начинать программировать, чтобы понимать во что в итоге скомпилится Си-шный код. Но писать на ассемблере постоянно - это непроизводительно и только ради искусства. Поддержка и модификация такого кода требует слишком дофига времени. Есть у меня такой многолетний проект, начиналось с малого - в итоге почти полностью заняло память программ в 16-й меге (писалось при том очень аккуратно и продумано). Какие-то глобальные изменения в этом шедевре (особенно когда не прикасался полгода-год) - это стон и слёзы, ну и приличное количество времени а значит и денег заказчика. Правда, не уверен что будучи написан на Си этот проект в его нынешнем виде влез бы в 16-ю мегу. Возможно только за счёт большей степени абстракции в каких-то местах.
В итоге, когда стали попадаться проекты где стоимость (=время) разработки софта критична - перешёл на Си, чем весьма доволен. Даже для мелких процев и простых проектов (в них играет большую роль переносимость кода - когда например решал подобную задачу для AVR, а нужно написать под 51-й или ПИК - код копипастится с минимальными изменениями). Да и держать в голове весь зоопарк ассемблеров лениво.

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт май 02, 2014 10:43:07

AIpp писал(а): Какие-то глобальные изменения в этом шедевре (особенно когда не прикасался полгода-год) - это стон и слёзы

Думается, дело не только в языке программирования. На Си тоже можно наворотить дикие конструкции, которые 7 мудрецов не разберут.
Структурировать прогу ( уж не 10-метровую простыню листинга без единого call ), не скупиться на комментарии ( "Ну здесь все и так понятно" - это сегодня, а завтра ? ), применять интуитвно понятные макросы - и АСМовый текст будет так же легко ( или почти так же ) читаем человеком, знающим данную архитектуру. А уж если не полениться, отмазываясь нехваткой времени, нарисовать схемы алгоритмов - то солнышко и благодать . :)

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт май 02, 2014 10:56:28

Vova777 писал(а):
Код:
while ((PIND& (1<<PD0))==1){}



Так писать нежелательно. Пока там PD0, это работает. Но стоит заменить PD0 на PD1, как работать перестанет - в этом случае значение выражения будет равно или 0, или 2, но никогда 1. Лучше написать так:

Код:
while (PIND & (1 << PD0)) {}

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт май 02, 2014 12:40:38

Jack_A писал(а): Думается, дело не только в языке программирования. На Си тоже можно наворотить дикие конструкции, которые 7 мудрецов не разберут.
Структурировать прогу ( уж не 10-метровую простыню листинга без единого call ), не скупиться на комментарии ( "Ну здесь все и так понятно" - это сегодня, а завтра ? ), применять интуитвно понятные макросы - и АСМовый текст будет так же легко ( или почти так же ) читаем человеком, знающим данную архитектуру. А уж если не полениться, отмазываясь нехваткой времени, нарисовать схемы алгоритмов - то солнышко и благодать . :)

Всё вышеописанное было сделано, комментарии почти в каждой строке, процедуры использованы по-полной, макросы имеют место, и папочка с блок-схемами (правда от руки) лежит в тумбочке. Просто структура и алгоритма и окружения весьма сложная. Не очень удачные архитектурные решения там тоже есть, но они связаны с тем что функциональность от исходной разраслась в несколько раз, причём изначально это не планировалось. А рефакторить асмовый код этот тоже тот ещё вынос мозга.
Допускаю, что задавшись целью можно было сделать несколько лучше, но это потребовало бы кучу времени на изобретение велосипедов, которые в Си имеются из коробки.
В общем, можно - но не выгодно.
По наблюдениям, ASM очень хорошо воспринимается теми, кто пришёл в программирование МК из электроники и мыслит больше сигналами и последовательностями, чем структурами и алгоритмами. Мне как человеку, пришедшему от настольных компов - он кажется недостаточно абстрактным, слишком мало структуры и слишком много реализации.
Естественно, что есть места, где и ассемблерные вставки нужны, есть процессоры где использование Си в лоб малоэффективно (те же мелкие ПИКи без полноценных ветвлений - хотя если знать систему команд, то становится понятным и как писать программу на Си так, чтобы она не скомпилировалась в тормозного монстра) - но в общем и целом считаю Си для коммерческих разработок, особенно крупных более эффективным инструментом. Однако ассемблер знать и понимать для разработчика под МК совершенно необходимо. Как для анализа листингов, так и для написания правильного, эффективного и предсказуемого сишного кода.
Наворотить можно на любом языке, здесь вы правы. Но вот сложность НЕ наворотить везде разная.

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт май 02, 2014 12:44:10

В данном случае более наглядно:
Код:
while ((PIND&(1<<PD0))!=0){}

Re: Нескольно простых вопросов о программировании AVR на Си.

Чт май 22, 2014 11:03:09

Доброго времени суток всем! Темы не нашел подходящей поэтому напишу тут, подскажите хорошую IDE и компилятор для AVRок под С, писал на cvavr, но ограничении эволюционки и зачастую непонятность ошибок заставили подумать о том на что можно пересесть другое, смотрю в сторону студии но встречал плохие отзывы о ней. Что посоветуете?

Re: Нескольно простых вопросов о программировании AVR на Си.

Чт май 22, 2014 11:13:11

Хорошая и бесплатная IDE - это Eclipse
Хороший и бесплатный компилятор - это WinAVR или более новая врсия Atmel AVR Toolchain (то же самое, но обновленное). Еще есть разновидности avr-gcc - которые местами превосходят и AVR Toolchain, но их надо искать в сети

Есть еще монстр Atmel Studio 6 - лично я с нею дел не имел, потому не могу советовать.
Ответить