| Форум РадиоКот 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 писал(а): 1 Си Си++ 2 http://eugenemcu.ru/publ/2-1-0-53 Искренне Вам благодарен! |
|
| Автор: | 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/ |
|


