Например TDA7294

Форум РадиоКот :: Просмотр темы - Нескольно простых вопросов о программировании AVR на Си.
Форум РадиоКот
https://radiokot.ru/forum/

Нескольно простых вопросов о программировании AVR на Си.
https://radiokot.ru/forum/viewtopic.php?f=57&t=102861
Страница 1 из 75

Автор:  Vova777 [ Сб апр 12, 2014 16:38:45 ]
Заголовок сообщения:  Нескольно простых вопросов о программировании AVR на Си.

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"? Помогите мне понять синтаксис этой строки.

Автор:  oleg110592 [ Сб апр 12, 2014 17:34:19 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

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

Автор:  ARV [ Сб апр 12, 2014 18:27:15 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

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

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

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

все понятно?

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

Автор:  Vova777 [ Сб апр 12, 2014 18:46:35 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

oleg110592 писал(а):


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

Автор:  Vova777 [ Вс апр 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.

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

Автор:  ARV [ Вс апр 13, 2014 15:13:35 ]
Заголовок сообщения:  Re: Синтаксис двух строк кода на языке Си.

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

Автор:  Alkul [ Вс апр 13, 2014 20:09:50 ]
Заголовок сообщения:  Re: Синтаксис двух строк кода на языке Си.

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-ми разрядных контроллеров применение Си не оправдано.

Автор:  Flasher [ Вс апр 13, 2014 20:28:42 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

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

Автор:  zero648 [ Вс апр 13, 2014 20:41:54 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

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

Автор:  Alkul [ Вс апр 13, 2014 21:19:15 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

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

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

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

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

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

Автор:  Flasher [ Вс апр 13, 2014 21:28:10 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

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

Автор:  Alkul [ Вс апр 13, 2014 21:35:35 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

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

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

Автор:  ARV [ Вс апр 13, 2014 22:54:24 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

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

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

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

Автор:  AIpp [ Чт май 01, 2014 13:38:31 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

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

Автор:  Jack_A [ Пт май 02, 2014 10:43:07 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

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

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

Автор:  Леонид Иванович [ Пт май 02, 2014 10:56:28 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

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



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

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

Автор:  AIpp [ Пт май 02, 2014 12:40:38 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

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

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

Автор:  AIpp [ Пт май 02, 2014 12:44:10 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

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

Автор:  WishMasterMax [ Чт май 22, 2014 11:03:09 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

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

Автор:  ARV [ Чт май 22, 2014 11:13:11 ]
Заголовок сообщения:  Re: Нескольно простых вопросов о программировании AVR на Си.

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

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

Страница 1 из 75 Часовой пояс: UTC + 3 часа
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/