Форум РадиоКот https://radiokot.ru/forum/ |
|
Пример работы с I/O портами AVR на C++ https://radiokot.ru/forum/viewtopic.php?f=57&t=84484 |
Страница 1 из 3 |
Автор: | ArtDen [ Сб фев 02, 2013 17:08:29 ] |
Заголовок сообщения: | Пример работы с I/O портами AVR на C++ |
Недавно столкнулся с C++ - библиотекой для работы с портами ввода/вывода на STM32. Очень удобная штука. Упрощает кучу вещей за счёт того позволяет определить вывод порта в одном месте программы. Был удивлён, что такой до сих пор нету для AVR-ок и по быстрому набросал вот такой код: http://muil.googlecode.com/svn/trunk/mcu/avr8/pin.hpp Использовать библиотеку очень просто. Вот пример моргания двумя светодиодами: Код: typedef Pin<'B', 0> LED1Pin; // определяем ногу для первого светодиода. Порт B, 0-я нога typedef Pin<'B', 1> LED2Pin; // определяем ногу для второго светодиода. Порт B, 1-я нога int main() { // Настраиваем ногу для первого светодиода LED1Pin::ConfOut(); // Нога работает на выход LED1Pin::Off(); // Нога выключена // Настраиваем ногу для второго светодиода LED2Pin::ConfOut(); // Нога работает на выход LED2Pin::On(); // Нога включена // Мигаем светодиодами for (;;) { LED1Pin::Cpl(); // Инвертируем состояние ноги первого светодиода LED2Pin::Cpl(); // Инвертируем состояние ноги второго светодиода _delay_ms(500); // Делаем задержку } } Библиотека работает под WinAVR. В других компиляторах не тестировал. Может кому пригодится. |
Автор: | blackx [ Сб фев 02, 2013 17:24:21 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
Спасибо, надо будет попробовать. Правда не встречал тут пока никого, кто бы под АВР на плюсах писал... |
Автор: | ArtDen [ Сб фев 02, 2013 17:44:24 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
blackx писал(а): Правда не встречал тут пока никого, кто бы под АВР на плюсах писал... Ну так надо начинать. Не всё время же на ассемблере или на си возиться ![]() |
Автор: | Аlex [ Сб фев 02, 2013 18:10:48 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
Цитата: Использовать библиотеку очень просто А для чего она нужна ? Какое в ней преимущество перед обычными макросами сброса/установки/инверсии бита ?PS: Можно посмотреть дизасм строки LED1Pin::Cpl(); ? |
Автор: | ArtDen [ Сб фев 02, 2013 18:27:29 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
Аlex писал(а): А для чего она нужна ? Какое в ней преимущество перед обычными макросами сброса/установки/инверсии бита ? Конкретно где получился LED1Pin не знаю, вот целиком дизассемблер программы, пример которой я показал:PS: Можно посмотреть дизасм строки LED1Pin::Cpl(); ? Код: sbi 0x04, 0 ; 4 cbi 0x05, 0 ; 5 sbi 0x04, 1 ; 4 sbi 0x05, 1 ; 5 ldi r22, 0x01 ; 1 ldi r23, 0x02 ; 2 ldi r20, 0xF4 ; 244 ldi r21, 0x01 ; 1 in r24, 0x05 ; 5 eor r24, r22 out 0x05, r24 ; 5 in r24, 0x05 ; 5 eor r24, r23 out 0x05, r24 ; 5 ldi r18, 0x88 ; 136 ldi r19, 0x13 ; 19 movw r24, r20 sbiw r24, 0x01 ; 1 brne .-4 ; 0x68 <main+0x22> subi r18, 0x01 ; 1 sbci r19, 0x00 ; 0 brne .-12 ; 0x66 <main+0x20> rjmp .-30 ; 0x56 <main+0x10> А нужна она вот для чего. Допустим, я делаю библиотеку (в виде класса) для работы с LCD-экраном нокии. Мне нужно чтобы она не была привязана к конкретным ногам МК. В этом случае я поступаю так: Код: template <typename RST_Pin, typename CE_Pin, typename DC_Pin, typename DIN_Pin, typename CLK_Pin> А затем использую этот класс вот так:class NOKIA5110LCD { public: ... // далее идут внутренности класса Код: // Определяем пины, которые будут использоваться для работы с LCD-экраном:
typedef Pin<'A', 0> RST_Pin; typedef Pin<'A', 1> CE_Pin; typedef Pin<'A', 2> DC_Pin; typedef Pin<'A', 3> DIN_Pin; typedef Pin<'A', 4> CLK_Pin; // Определяем LCD: typedef NOKIA5110LCD<RST_Pin, CE_Pin, DC_Pin, DIN_Pin, CLK_Pin> LCD; // Настраиваем пины: RST_Pin::ConfOut(); CE_Pin::ConfOut(); DC_Pin::ConfOut(); DIN_Pin::ConfOut(); CLK_Pin::ConfOut(); // Работаем с LCD LCD::init(); ... |
Автор: | YS [ Сб фев 02, 2013 18:36:05 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
Цитата: А нужна она вот для чего. Допустим, я делаю библиотеку (в виде класса) для работы с LCD-экраном нокии. Мне нужно чтобы она не была привязана к конкретным ногам МК. А дефайны - уже не модно? Код: ... PORT|=RST_PINMASK; ... PORT&=~E_PINMASK; Как по мне, не надо насильно пихать ООП туда, где оно не нужно. ![]() Код: RST_Pin::ConfOut(); CE_Pin::ConfOut(); DC_Pin::ConfOut(); DIN_Pin::ConfOut(); CLK_Pin::ConfOut(); С дефайнами будет в одну строку. Код: PORT|=RST_PIN | CE_PIN | DC_PIN | DIN_PIN | CLK_PIN; И уложится компилятором в гораздо более компактный код. Скорее всего, в две инструкции - загрузку константы (RST_PIN | CE_PIN | DC_PIN | DIN_PIN | CLK_PIN) и ее вывод в DDRn. UPD: Переписал программу из первого поста на pure C. Исходно: Код: typedef Pin<'B', 0> LED1Pin; // определяем ногу для первого светодиода. Порт B, 0-я нога typedef Pin<'B', 1> LED2Pin; // определяем ногу для второго светодиода. Порт B, 1-я нога int main() { // Настраиваем ногу для первого светодиода LED1Pin::ConfOut(); // Нога работает на выход LED1Pin::Off(); // Нога выключена // Настраиваем ногу для второго светодиода LED2Pin::ConfOut(); // Нога работает на выход LED2Pin::On(); // Нога включена // Мигаем светодиодами for (;;) { LED1Pin::Cpl(); // Инвертируем состояние ноги первого светодиода LED2Pin::Cpl(); // Инвертируем состояние ноги второго светодиода _delay_ms(500); // Делаем задержку } } Дизасм строчек Код: LED1Pin::Cpl(); // Инвертируем состояние ноги первого светодиода LED2Pin::Cpl(); // Инвертируем состояние ноги второго светодиода Код: in r24, 0x05 ; 5 eor r24, r22 out 0x05, r24 ; 5 in r24, 0x05 ; 5 eor r24, r23 out 0x05, r24 ; 5 pure C: Код: void main(void) { LED_DDR=LED1_PIN | LED2_PIN; LED_PORT=0; while (1) { LED_PORT^=(LED1_PIN | LED2_PIN); _delay_ms(500); } } Дизасм строчки Код: LED_PORT^=(LED1_PIN | LED2_PIN); Код: 16: LED_PORT^=(LED1_PIN | LED2_PIN); +00000029: B185 IN R24,0x05 In from I/O location +0000002A: 2784 EOR R24,R20 Exclusive OR +0000002B: B985 OUT 0x05,R24 Out to I/O location Три команды. |
Автор: | ArtDen [ Сб фев 02, 2013 19:00:29 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
YS писал(а): А дефайны - уже не модно? Да я не заставляю на эту либу всех переходить. Кому нравиться - он и на ассемблере пишет ![]() |
Автор: | YS [ Сб фев 02, 2013 19:07:36 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
Цитата: Кому нравиться - он и на ассемблере пишет Дыг а для тех, для кого ассемблер - пища зело твердая, есть Ардуино с Вайрингом. ![]() |
Автор: | HHIMERA [ Сб фев 02, 2013 19:11:47 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
ArtDen писал(а): Конкретно где получился LED1Pin не знаю, вот целиком дизассемблер программы, Хорошее начало... ![]() Цитата: Недавно столкнулся с C++ - библиотекой для работы с портами ввода/вывода на STM32. Очень удобная штука. Хм... Цитата: А нужна она вот для чего. Допустим, я делаю библиотеку (в виде класса) для работы с LCD-экраном нокии. Мне нужно чтобы она не была привязана к конкретным ногам МК. Зашибись... берём STM32, вяжем к нему 5-ти вольтовый 16х2 как попало, а потом удивляемся... ![]() Или... привязываем как причудилось к новым PIC'ам и кричим "ПИК гавно, генератор не запускается, ADC глючит"... ![]() |
Автор: | ArtDen [ Сб фев 02, 2013 19:17:33 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
HHIMERA, не понял твою мысль |
Автор: | Аlex [ Сб фев 02, 2013 19:18:59 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
Цитата: Мне нужно чтобы она не была привязана к конкретным ногам МК Это я уже понял. А преимущество перед дефайнами то в чём ?Цитата: Конкретно где получился LED1Pin не знаю Ну вот... как же так ? Использовать и не знать во что разворачивается...
|
Автор: | ArtDen [ Сб фев 02, 2013 19:27:40 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
Аlex писал(а): Это я уже понял. А преимущество перед дефайнами то в чём ? В том, что 1. Код проще читается. Не надо напрягать мозги при виде RST_PORT &= ~RST_PINMASK;. Выражение RST_Pin::Off(); гораздо понятнее. 2. Нереально допустить такое ошибки как RST_PORT &= RST_PINMASK; Аlex писал(а): Ну вот... как же так ? Использовать и не знать во что разворачивается... С каких это пор знание ассемблера обязательно для программирования на МК? ![]() |
Автор: | ILYAUL [ Сб фев 02, 2013 19:30:12 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
Цитата: Конкретно где получился LED1Pin не знаю Bot Код: in r24, 0x05 ; 5 eor r24, r22 out 0x05, r24 ; 5 in r24, 0x05 ; 5 eor r24, r23 out 0x05, r24 ; 5 Это пиз-ец Код: out 0x05, r24 ; 5 in r24, 0x05 ; 5 Цитата: С каких это пор знание ассемблера обязательно для программирования на МК? Что бы всегда можно было написать Цитата: Это пиз-ец Да!И не писать вот это Цитата: Конкретно где получился LED1Pin не знаю
|
Автор: | YS [ Сб фев 02, 2013 19:50:09 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
Цитата: Код проще читается. Не надо напрягать мозги при виде RST_PORT &= ~RST_PINMASK;. Выражение RST_Pin::Off(); гораздо понятнее. Спорно. Когда таких записей штук пять-восемь, от XXX_Pin::SomeMethod() начинает рябить в глазах. В то время как настройка одного порта логическими операциями записывается в одну-две строчки в любом случае. Кроме того, для каждой такой ООП-шной строчки, как выясняется, компилятор генерирует отдельный набор команд доступа к порту, что раздувает программу. Вообще, если запись some_var&=~SOME_DEFINE заставляет человка заметно напрягать мозг, значит ему все еще необходимо учиться многим элементарным вещам. ![]() Цитата: Нереально допустить такое ошибки как RST_PORT &= RST_PINMASK; Можно сделать макрос Код: Цитата: С каких это пор знание ассемблера обязательно для программирования на МК? С тех самых пор, как их изобрели. Вообще, даже занимаясь программированием x86 очень полезно знать ассемблер. А для ма-а-а-аленьких контроллеров типа AVR это просто обязательно. Нормальное обучение программированию контроллеров должно начинаться с ассемблера. Все сказанное справедливо, конечно, только для случая, когда человек и правда хочет что-то понимать и быть компетентным в предметной области. Для дилетантов всегда есть Ардуино. ![]() "Wiring and Processing have spawned another project, Arduino, which uses the Processing IDE, with a simplified version of the C++ language, as a way to teach artists and designers how to program microcontrollers." http://en.wikipedia.org/wiki/Wiring_(de ... t_platform) |
Автор: | Аlex [ Сб фев 02, 2013 19:52:52 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
Цитата: В том, что 1. Код проще читается. Не надо напрягать мозги при виде RST_PORT &= ~RST_PINMASK;. Выражение RST_Pin::Off(); гораздо понятнее. 2. Нереально допустить такое ошибки как RST_PORT &= RST_PINMASK; Код: ......... ......... CLR_BIT(RST_PORT, RST_PIN); Цитата: С каких это пор знание ассемблера обязательно для программирования на МК? С тех пор, когда Вы начали их изучать.ЗЫ: Опередили меня ![]() |
Автор: | HHIMERA [ Сб фев 02, 2013 19:54:57 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
ArtDen писал(а): HHIMERA, не понял твою мысль А что тут непонятного??? Во первых... У многих МК не все пины толерантны к 5Вольтам... так что... не "привязываемся к пинам" - часто мнимое... Во вторых... Если дисплей, тот же, от Нокии, вешать по человечески на SPI, то вариантов - раз-два... и всё... В общем... мысль, что можно совать что попало и куда попало "не привязываясь", у некоторых (у новичков в частности) вызывает ассоциации и призывы к прямому действию... что чревато... Ну вот как-то так... |
Автор: | ArtDen [ Сб фев 02, 2013 20:03:07 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
Аlex писал(а): CLR_BIT(RST_PORT, RST_PIN); Что тут напряжного ? То, что можно по ошибке написать Код: CLR_BIT(DIN_PORT, RST_PIN); и если порты у DIN и RST - разные, то потом долго чесать голову, почему у меня ничего не работает.PS: И можно всё-таки пояснить зачем нужно знать ассемблер, чтобы программировать на МК? HHIMERA писал(а): А что тут непонятного??? Во первых... У многих МК не все пины толерантны к 5Вольтам... так что... не "привязываемся к пинам" - часто мнимое... И как это относится к вопросу библиотеки C++ для работы с портами AVR?! ![]() |
Автор: | Аlex [ Сб фев 02, 2013 20:04:01 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
Цитата: я делаю библиотеку (в виде класса) для работы с LCD-экраном нокии С вашей библиотекой Вы будете ждать прорисовку экрана до бесконечности, тем более на низкоскоростных МК.Цитата: То, что можно по ошибке написать как можно по ошибке написать ненужное ? С таким подходм вообще не стоит садиться за программирование, т.к. по ошибке можно место if написать for ![]() Цитата: PS: И можно всё-таки пояснить зачем нужно знать ассемблер, чтобы программировать на МК? Что-бы потом не задавать глупых вопросов, типа "почему у меня это делается медленно, я же всего лишь одну строчку написал ?"....
|
Автор: | HHIMERA [ Сб фев 02, 2013 20:11:06 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
ArtDen писал(а): 1. Код проще читается. Не надо напрягать мозги при виде RST_PORT &= ~RST_PINMASK;. Выражение RST_Pin::Off(); гораздо понятнее. С понятием "абстракция" знакомы??? ![]() Цитата: 2. Нереально допустить такое ошибки как RST_PORT &= RST_PINMASK; Не бывает нереальных ошибок... все они реальные... |
Автор: | ArtDen [ Сб фев 02, 2013 20:13:49 ] |
Заголовок сообщения: | Re: Пример работы с I/O портами AVR на C++ |
HHIMERA писал(а): С понятием "абстракция" знакомы??? Да. Только при чём здесь это? Выражайте свою мысль яснее.
![]() |
Страница 1 из 3 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |