Работа с портами в функциях. Порт как аргемент для функции

Обсуждаем контроллеры компании Atmel.
ZiperRUS
Родился
Сообщения: 18
Зарегистрирован: Сб июн 08, 2013 19:12:54

Работа с портами в функциях. Порт как аргемент для функции

Сообщение ZiperRUS »

Всем здравствуйте великодушно.
Пишу я вам в этот мерзопакостный вечер сейчас 19:47 мск с криком о помощи!!!
Столкнулся я с такой проблемой с таким недопонимаем своего любимого хобби.
В чём же дело можете вы задать вопрос мне , хорошо отвечаю суть вопроса суть моей тревоги вот в чём.

не могу я понять разобраться с использованием аббревиатур допустим( PORTB и PINB.5)
есть к примеру такая функция

void TestPort(port, pinb.5)
{
if(pinb.5)port=0;
else port=1;
}

как такое реализовать? то есть здесь в функцию передаётся два аргумента сам порт port-PORTB и для проверки пина порта на текущее состояние pinb.5-PINB.5
как передать в функцию такие аргументы для долнейщей рабы с ней в самой функции и для присвоения порту значений?
среда CodeVision

Помагите пожалуйста очень надо мне :)
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение ploop »

Вот до чего доводит использование CodeVision :)
Ваш pinb.5 в CodeVision - какой-то макрос, какой - смотрите.
Номер пина можно задать числом. Не обращая внимания на типы и прочее - что-то типа этого:

Код: Выделить всё

void TestPort(int port_in, int port_out, int pin)
{
if (port_in & (1<<pin))
  port_out=0;
  else port_out=1;
}
ZiperRUS
Родился
Сообщения: 18
Зарегистрирован: Сб июн 08, 2013 19:12:54

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение ZiperRUS »

ploop писал(а):Вот до чего доводит использование CodeVision :)
Ваш pinb.5 в CodeVision - какой-то макрос, какой - смотрите.
Номер пина можно задать числом. Не обращая внимания на типы и прочее - что-то типа этого:

Код: Выделить всё

void TestPort(int port_in, int port_out, int pin)
{
if (port_in & (1<<pin))
  port_out=0;
  else port_out=1;
}



нееее не видел я там таких макросов для этих целей. Там есть хидер #include <tiny2313.h>
вот его часть

sfrb PINB=0x16;
sfrb DDRB=0x17;
sfrb PORTB=0x18;
sfrb PINA=0x19;
sfrb DDRA=0x1a;
sfrb PORTA=0x1b;
sfrb EECR=0x1c;
sfrb EEDR=0x1d;
sfrb EEAR=0x1e;
sfrb PCMSK=0x20;
sfrb WDTCR=0x21;
sfrb TCCR1C=0x22;
sfrb GTCCR=0x23;
sfrb ICR1L=0x24;
sfrb ICR1H=0x25;

объявления в нём.
Но как их использовать в коде программы??? :?

пробовал так для проверки

void TestPort(int PORTB.0)
{

}

компилятор ругается
Error:........: missing ',' :shock:

хотя на это молчит

void TestPort(int PORTB)
{

}

Так в чём же дело? друзья
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение ploop »

Так в чём же дело? друзья

Мля, я же объяснил - PORTB - число, PORTB.1 -не число, это какая-то структура или макрос, знакомый только CVAVR. А вы его в параметр суёте.
fzr400gr
Первый раз сказал Мяу!
Сообщения: 36
Зарегистрирован: Вс сен 25, 2011 09:40:47

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение fzr400gr »

А вы обьясните для начала задачу поконкретнее, а то немного не понятно что вы хотите сделать в вашей функции.
Если порт В у вас разделен на входы и выходы то проще обращатся к ним как к отдельным выводам.
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение a_skr »

ошибаетесь.
и PORTB.5 и PINB.5 - числа (по крайней мере, результатом обращения к таким записям является число).
мы же можем записать int a = PINB.5;
вот рабочий код:

Код: Выделить всё

#include <tiny2313.h>

void test(char* port, char pin)
{
  if(pin) *port |= 1;
  else *port &= ~1;
}

void main(void)
{
  DDRB = 1; // выход
  PORTB = 1<<5; // подтяжка
  while (1)
  {
    test(&PORTB, PINB.5);
  }
}
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение uk8amk »

sfrb PORTB=0x18


вот рабочий код:

void test(char* port, char pin)
{
if(pin) *port |= 1;
else *port &= ~1;
}

test(&PORTB, PINB.5);


На мой взгляд было бы правильней:

Код: Выделить всё

void test(char* port, char pin)
{
  if(pin) *port |= (1<<pin);
  else *port &= ~(1<<pin);
}

test(&PORTB, 5);


Поскольку PINB.5 возвращает состояние бита порта.

Но вот тут мне не ясна одна деталь:

4. When using the I/O specific commands IN and OUT, the I/O addresses 0x00 - 0x3F must be used. When addressing I/O
Registers as data space using LD and ST instructions, 0x20 must be added to these addresses.


Выходит надо писать так:

Код: Выделить всё

test(&(PORTB+0x20), 5);


???

А автор случаем не с ардуины слезть пытается?
Поскольку вроде бы там есть очень похожая digitalwrite(port, pin).
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение a_skr »

На мой взгляд было бы правильней:
void test(char* port, char pin)
{
if(pin) *port |= (1<<pin);
else *port &= ~(1<<pin);
}
ерунда какая-то... ;)
вот рабочий код:
проверялся в протеусе.
Выходит надо писать так:
test(&(PORTB+0x20), 5);
компилятор умный:

Код: Выделить всё

; 0000 000F     test(&PORTB, PINB.5);
   LDI  R30,LOW(56) <- вот тут 0x38, а не 0x18
   ST   -Y,R30
   LDI  R30,0
   SBIC 0x16,5
   LDI  R30,1
   ST   -Y,R30
   RCALL _test

вообще, автор какой-то странный вопрос поставил.
все можно сделать проще и элегантней и правильней.
сформулируйте конечную цель - подскажем, как надо. ;)
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение ploop »

ошибаетесь.
и PORTB.5 и PINB.5 - числа

Возможно.
Но что эти обозначения представляют из себя внутри? У меня просто нет cvavr чтобы проверить. Сам пишу под avr-gcc.
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение a_skr »

Сам я тоже под WinAVR сижу, просто, некоторым надо было написать программы - вот и поигрался с ним пару раз. И вот такие вопросы тоже мне интересны. Как там внутри CV это устроено - хз. Но он предоставляет доступ к регистрам портов до 1F по аналогии с битовыми полями размером в один бит в структурах. Называет их "bit selector":
The bit level access to the I/O registers can be also accomplished by using bit selectors appended after the name of the I/O register.
Because bit level access to I/O registers is done using the CBI, SBI, SBIC and SBIS instructions, the register address must be in the 0 to 1Fh range for sfrb and in the 0 to 1Eh range for sfrw.
Example:
sfrb PORTA=0x1b;
...
/* set bit 0 of I/O Port A as output */
DDRA.0=1;
/* set bit 1 of I/O Port A as input */
DDRA.1=0;

PS. так, что результат записи ioreg.n - это 1 или 0. при присваивании соответствующий бит будет установлен или сброшен. вполне себе числа ;)
PPS.
Но вот тут мне не ясна одна деталь:
Цитата:
4. When using the I/O specific commands IN and OUT, the I/O addresses 0x00 - 0x3F must be used. When addressing I/O
Registers as data space using LD and ST instructions, 0x20 must be added to these addresses.
Выходит надо писать так:
Код:
test(&(PORTB+0x20), 5);
вот теперь понятно, что так писать не надо. в данном случае используются команды CBI, SBI, SBIC и SBIS, работающие с регистрами от 0 до 1F
ZiperRUS
Родился
Сообщения: 18
Зарегистрирован: Сб июн 08, 2013 19:12:54

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение ZiperRUS »

Проснувшись сегодня утром и ВКЛ. комп был воодушевлён ответами. Всем спасибо за помощь. С таким прекраснейшим настроением я приступил к водным процедурам))))

fzr400gr писал(а):А вы обьясните для начала задачу поконкретнее, а то немного не понятно что вы хотите сделать в вашей функции.


Задача функции такая. Есть у меня две функции одинаковые они полностью отличаются только они как раз что используют разные PIN и PORT.
первая использует PIND.5 PIND.0 PINB.3 и PORTD.0
вторая использует PIND.0 PIND.5 PINB.4 и PORTD.5

одинаковые PINы используются в разных местах кода.
Так вот для начала я хочу эти две функции объединить в одну, оптимизировать а нужные PINы и PORTы передавать ей в качестве параметров при вызове. или вот думаю можно так реалировать смену PINов в самой функции по команде через параметр, вот как то так:

void TestPort(int command)
{
port; // здесь мы объявили переменные для порта и пина, но какой ставить тип переменных ?
pin;

if(command==1)
{
port = PORTB; // здесь мы присваиваем переменным номер порта и пина в зависимости от команды
pin = PINB.5;
}

if(pin)port=0; // работаем с переменными пора и пина
else port=1;

}

вот так тоже делать пришла идея но как?

Вообще это устройство у меня стоит в авто уже года три назад я его сам собрал. его назначение это управление стёклами (стеклоподъёмник) и закрывает он их автоматически при постановке на сигнализацию. У меня там две функции есть одна управляет закрытием водительского окна , другая закрытием пассажирского окна, они одинаковые различаются только работой с разными пинами и портом. Поюзав это собственно ручно собранное замечательное устройство не один год и убедившись в его замечательной надёжности и нужности я решил сделать ему upgrade добавить дополнительно новые функции полезные и подключить его к блютузу.
В частности планируется задействовать в алгоритме ещё и открывание окон (щас только закрыванием онных оно отвечает). Не писать же ещё две такие же функции на открывание :?
поэтому я и решил написать одну функцию и в параметрах при вызове указывать ей какое окно открывать или закрывать. Вот в чём задумка!!!
Я понимаю некоторые могут подумать и сказать типа пиши четыре функции одинаковых и иди пей пиво светлое, тёмное кому как нравиться на вкус и цвет товарищей нет. Яб мог конечно так сделать еслиб был пивным алкоголиком но я не из них! Мне кажется это логически неправильно так делать. Да и ресурсы у контроллера не безграничные!!! щас стоит ATTINY2313 новую реализацию планирую реализовать на ATMEGA8 а то чёт ног у 2313 не хватает мне чуть чуть 8)

А автор случаем не с ардуины слезть пытается?

Неее я с ней дело никогда не имел. Видел только видюхи на ютубе, забавная вещица :)

Ну вот я вам соотечественники рассказал полностью откровенно ничего не скрывая свой замысел, какие будит идеи? заранее великодушно всем спасибо.
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение uk8amk »

ерунда какая-то...


Сорри, мой косяк.

компилятор умный:


CVAVR(у мя 1.25) не настолько. Такое выражение вызывает ошибку ассемблера.
Пришлось адреса подставлять вручную.

какие будит идеи?


Вот бегущий огонь с применением данного метода.
Вложения
main.c
(3.23 КБ) 589 скачиваний
ZiperRUS
Родился
Сообщения: 18
Зарегистрирован: Сб июн 08, 2013 19:12:54

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение ZiperRUS »

всех поздравляю с приходом пятницы развратницы :beer: много не гуляйте не злоупотребляйте!!!! так как завтра будет субботница развратница :beer: потом воскресница развратница :beer: . А в понедельник будет :shock: :o :(



uk8amk спасибо за исходник он мне помог.
в нём

volatile char *port; // переменная для хранения адреса порта
port = ((char*)0x38); //PORTB SRAM adress здесь адрес PORTB из хидера + 0x20
функцией port_set можно выставить любой пин порта port в 0 или 1

а как присвоить переменной адрес допустим PINB.5 ?

volatile char *pin;
pin = ??? // для PINB.5 что тут писать?
чтоб потом можно былоб так использовать:
if(pin)
{

}
else
{

}
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение a_skr »

НЕЛЬЗЯ получить адрес бита!
Возьмите адрес регистра (char* pin = &PINB) и номер бита, дальше - дело техники.
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение uk8amk »

а как присвоить переменной адрес допустим PINB.5 ?


А никак.
PINB.5 -- нет такого регистра. Есть только PINB. Нельзя вычислить и использовать адрес куска от регистра.

Есть инструкции установки индивидуального бита SBI/CBI. Но там тоже отдельно указывается порт и бит.

upd. Упс, уже опередили.
ZiperRUS
Родился
Сообщения: 18
Зарегистрирован: Сб июн 08, 2013 19:12:54

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение ZiperRUS »

друзья спасибо за оперативную помощь.
Из вашей информации к размышлению я понял: что нельзя получить адрес конкретного пина в регистре. :( хотя как то странно получается адрес регистра есть а адреса пина, бита этого регистра нет :shock: он же по любому должен занимать какое то адресное пространство в контроллере (это не поддерживается языком С или аппаратно невозможно получить доступ к адресу пина, бита регистра?). но суть не в этом !!!
подскажите тогда пожалуйста вот что
Возьмите адрес регистра (char* pin = &PINB) и номер бита

как можно через адрес PINB получить текущее состояние PINB.5 ???
в хидере (CodeVision 2.05.0) #include <tiny2313.h> адрес PINB обозначен как

sfrb PINB=0x16;

как из этого адреса получить текущее состояние PINB.5 ????
как узнать что в PINB.5 true или false ???
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение Аlex »

ZiperRUS
Родился
Сообщения: 18
Зарегистрирован: Сб июн 08, 2013 19:12:54

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение ZiperRUS »

Аlex писал(а):http://g.zeos.in/?q=%D0%91%D0%B8%D1%82%D0%BE%D0%B2%D1%8B%D0%B5%20%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B8%20%D0%B2%20%D0%A1%D0%B8
Ну или http://tinyurl.com/k9axbf3 на крайняк :)


юморист блин :)) дитя петросяна наверное или просто хорошее настроение у человека. :roll:
ладно будем думать, размышлять. думать это тоже полезно иногда делать напрягать мозг, умище.
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение uk8amk »

я понял: что нельзя получить адрес конкретного пина в регистре


Некоторые архитектуры(например современные ARM) это позволяют. AVR этого не умеют.

он же по любому должен занимать какое то адресное пространство в контроллере


Он и занимает. Каждый бит сидит в своём байте. Машинное слово - обычно минимальный размер адресуемой информации. 8 бит AVR могут адресовать за раз 1 байт информации.

как можно через адрес PINB получить текущее состояние PINB.5 ???


Наложить маску по OR или AND(операции & |).
Очень жаль, что вы об этом не знаете. Это основа работы с микроконтроллерами и цифровой техникой.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Работа с портами в функциях. Порт как аргемент для функц

Сообщение Аlex »

ZiperRUS писал(а):юморист блин :)) дитя петросяна
Ну а чего ? Куча народу толкуют Вам одно и тоже, а толку - нуль. Что ещё остаётся, как не дать ссылку на гугл ?
Ответить

Вернуться в «AVR»