Передача аргментом ножки порта

Программирование микроконтроллеров AVR, PIC, ARM.
Разработка и изготовление печатных плат для модулей.

Передача аргментом ножки порта

Сообщение Hagrael » 16 авг 2011, 16:01

Здравствуйте, программисты! Я изучил C++, но ни разу не видел операции, которую сразу же увидел при программировании микроконтроллеров:
Код: Выделить всё
PORTC.1 = 0;

Что она делает, и можно ли каким-то образом передать эту ножку порта аргументом функции?
Аватара пользователя
Hagrael
 
Сообщения: 18
Зарегистрирован: 14 авг 2011, 15:42

Re: Передача аргментом ножки порта

Сообщение Grem » 16 авг 2011, 16:11

Устанавливает лог 0 на первый бит С порта.
avr123.nm.ru и читать до дыр :)
"There is nothing better than sliding down snow and flying through the air" (с) Shane McConkey.
Lieber ein Brett am Fuß als eins vorm Kopf, aber lieber ein Brett vorm Kopf als zwei am Fuß.
Аватара пользователя
Grem
 
Сообщения: 1530
Зарегистрирован: 16 май 2009, 12:50
Откуда: Россия
прог. языки: Java, C

Re: Передача аргментом ножки порта

Сообщение =DeaD= » 16 авг 2011, 16:14

Вообще говоря это не Си++ :) это некоторая нашлепка на него от CvAVR.

Правильный Си++ :) делает так (на примере установки бита, т.е. PORTC.1=1):

PORTx |= 1 << BIT_NUMBER;

PORTx - нужный нам порт (соотв. ему ячейка памяти, если я правильно помню как там что устроено), например PORTC, BIT_NUMBER - номер бита, например 1.

Т.е., например, PORTC |= 0x02;
Проект [[Open Robotics]] - Универсальные модули для построения роботов
Аватара пользователя
=DeaD=
 
Сообщения: 24218
Зарегистрирован: 06 окт 2004, 18:01
Откуда: Ебург
прог. языки: C++ / PHP / 1C
ФИО: Антон Ботов

Re: Передача аргментом ножки порта

Сообщение dccharacter » 16 авг 2011, 16:38

Передать одним аргументом, наверное, нельзя, а вот двумя - можно. Адрес регистра + маска.

Адрес можно передать как в явном виде (см. даташит), так и скорее всего взять его от имени порта (хотя не уверен - там в хидерах такое понакручено).

т.е.

unsigned char * addr_ptr;
addr_ptr = &PORTC; //хотя наверное в CvAVR PORTC - это само по себе что-то структуры
some_function (addr_ptr, mask);

Добавлено спустя 51 секунду:
=DeaD= писал(а):Т.е., например, PORTC |= 0x02;

Так он передаст не ножку в функцию, а беззнаковый чар
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: Передача аргментом ножки порта

Сообщение Hagrael » 16 авг 2011, 18:39

Grem, я начинаю читать книгу "Самоучитель разработчика устройств на микроконтроллерах AVR". Но все-таки интересно, dccharacter, как внутри применять этот код? Если таким образом:
Код: Выделить всё
addr_ptr.mask

то у меня выходит ошибка. Ваш код:
=DeaD=, ваш код:
Код: Выделить всё
PORTC |= 0x02;

как я понимаю, поставит на второй с конца бит 1. А если я пишу
Код: Выделить всё
PORTC.2 = 0;

то как тогда эта инструкция расшифруется?

Большое спасибо за быстрые отзывы!
Аватара пользователя
Hagrael
 
Сообщения: 18
Зарегистрирован: 14 авг 2011, 15:42

Re: Передача аргментом ножки порта

Сообщение Виталий » 16 авг 2011, 19:18

Вообще говоря это не Си++ это некоторая нашлепка на него от CvAVR.

Могли бы назвать PORTC.b1 и тогда уместились бы в C Bitfields. =)
Все новости о моих проектах http://savethebest.ru
Аватара пользователя
Виталий
 
Сообщения: 2114
Зарегистрирован: 08 окт 2004, 16:43
Откуда: St. Petersburg
Skype: quark-bot
ФИО: Клебан Виталий

Re: Передача аргментом ножки порта

Сообщение boez » 16 авг 2011, 19:56

Эта вся беда оттого, что в С работы с железом нету как таковой, а людям хочется :)

Запись PORTC.1 ошибочна с точки зрения С, любой _стандартный_ С компилятор должен выдавать ошибку. Но в некоторых компиляторах, заточенных именно под АВРки, как минимум в CVAVR, такое прокатывает. При этом это уже магия компилятора, соответственно поддержка "указателей на ножку" - тоже вопрос нестандартного расширения языка, насколько я знаю - такого нету.

Что касается все же передачи ножки в функцию - отдельно ссылку на порт можно передать как обычный указатель, поскольку в АВР порты - это ячейки памяти. Т.е. обращение к такому порту будет выглядеть например так:

Код: Выделить всё
void SetPinTo1(volatile unsigned char *port, unsigned char bit)
{
    *port |= (1<<bit);
}
void SetPinTo0(volatile unsigned char *port, unsigned char bit)
{
    *port &= ~(1<<bit);
}
void SetPin(volatile unsigned char *port, unsigned char bit, unsigned char val)
{
    *port = (*port&~(1<<bit))|((val&1)<<bit);
}


вызываться это дело должно как SetPinTo1(&PORTA,0) и работать чисто теоретически должно на любом компиляторе, разве что тип указателя может придется подкрутить.

как-то так, на WinAVR (компилятор gcc) компилится, будет ли работать - не проверял, не на чем.
boez
 
Сообщения: 1981
Зарегистрирован: 27 авг 2008, 10:45
Откуда: Харьков
прог. языки: С/С++

Re: Передача аргментом ножки порта

Сообщение MiBBiM » 16 авг 2011, 20:51

http://easyelectronics.ru/avr-uchebnyj- ... h-rom.html - информация по адресным пространствам.
Код: Выделить всё
PORTC.2 = 0;  =>  PORTC &= ~(1<<2);
Tomorrow will be. Better
Аватара пользователя
MiBBiM
 
Сообщения: 1866
Зарегистрирован: 29 окт 2007, 18:11
Откуда: Пермь
прог. языки: Brainfuck/Basic/Delphi/C++/Lisp/x86asm/JavaScript

Re: Передача аргментом ножки порта

Сообщение dccharacter » 16 авг 2011, 22:58

boez писал(а):
Код: Выделить всё
void SetPinTo1(volatile unsigned char *port, unsigned char bit)
{
    *port |= (1<<bit);
}




Не, ну а я чо сказал? :-)))
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: Передача аргментом ножки порта

Сообщение MiBBiM » 16 авг 2011, 23:12

есть ведь еще индусский подход:
Код: Выделить всё
enum ports_pins { PORTC1, PORTC2, PORTC3, PORTC4, PORTD1, PORTD2, PORTD3, PORTD4 };

void my_func (ports_pins out)
{
  switch(out) {
    case PORTC1: PORTC.1 = 1; break;
    case PORTC2: PORTC.2 = 1; break;
    case PORTC3: PORTC.3 = 1; break;
    case PORTC4: PORTC.4 = 1; break;
    case PORTD1: PORTD.1 = 1; break;
    case PORTD2: PORTD.2 = 1; break;
  }
}
Tomorrow will be. Better
Аватара пользователя
MiBBiM
 
Сообщения: 1866
Зарегистрирован: 29 окт 2007, 18:11
Откуда: Пермь
прог. языки: Brainfuck/Basic/Delphi/C++/Lisp/x86asm/JavaScript

Re: Передача аргментом ножки порта

Сообщение Vooon » 17 авг 2011, 00:56

2 boez: там кажется нужна была дополнительная магия. Ну и через mmap оно тормознее.
Если достаточно #define'а то лучше обойтись им.
Linux user | Firefox user
Аватара пользователя
Vooon
Site Admin
 
Сообщения: 3339
Зарегистрирован: 09 фев 2006, 15:36
Откуда: Москва
Skype: vooon341
прог. языки: Python, C, Bash, JavaScript, C++, PHP
ФИО: Владимир Ермаков

Re: Передача аргментом ножки порта

Сообщение Hagrael » 17 авг 2011, 08:25

Всем спасибо! Вопрос решен!
Аватара пользователя
Hagrael
 
Сообщения: 18
Зарегистрирован: 14 авг 2011, 15:42

Re: Передача аргментом ножки порта

Сообщение boez » 17 авг 2011, 10:48

Vooon писал(а):2 boez: там кажется нужна была дополнительная магия. Ну и через mmap оно тормознее.
Если достаточно #define'а то лучше обойтись им.

Это понятно, что если достаточно дефайнов - то хорошо. А магия там, насколько я знаю, спрятана в компилятор - в хидерах, если не баловаться с _SFR_ASM_COMPAT и ассемблером, все регистры определяются как
Код: Выделить всё
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
#define _MMIO_WORD(mem_addr) (*(volatile uint16_t *)(mem_addr))
#define _MMIO_DWORD(mem_addr) (*(volatile uint32_t *)(mem_addr))

А вот уже компилятор, если видит, что указатель константный и в пределах 0x20..0x5f, заменяет работу с памятью на in/out.

Это все про avr-gcc. Другими не балуюсь.
boez
 
Сообщения: 1981
Зарегистрирован: 27 авг 2008, 10:45
Откуда: Харьков
прог. языки: С/С++

Re: Передача аргментом ножки порта

Сообщение linvinus » 17 авг 2011, 18:20

Немного не по теме,но возможно автору пригодится.
когда нужно установить несколько бит на порту то операции с масками будут занимать больше чем один такт.
В avr есть аппаратный xor на порту, это запись не в PORTB а в PINB
подробнее http://hackaday.com/2011/07/09/hardware ... ntrollers/
R3 forum87/topic15337.html
R2 roboforum.ru/forum102/topic13980.html
R4 roboforum.ru/post336339.html#p336339
Делать надо хорошо - плохо получится само!
Аватара пользователя
linvinus
 
Сообщения: 1672
Зарегистрирован: 29 апр 2011, 12:37
Откуда: Москва
прог. языки: С


Вернуться в Микроконтроллеры

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6