Сложный вопрос AVR на С про volatile to const

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Сложный вопрос AVR на С про volatile to const

Сообщение ARV »

:facepalm:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Сложный вопрос AVR на С про volatile to const

Сообщение alex68md »

Dimon, Refletor
" а сейчас ~*port читает с порта один раз в момент передачи в функцию, потом там в цикле проверяется одно и то же значение. Со ссылками будет то же самое."
т.е. даже если нам удастьтся передать всеми правдами и не правдами (как rvalue ссылку или даже как поинтер или еще как) инверсное значение состотояния порта, то в цикле будет участвовать не реальное каждый раз занаво считываемое значение а какойто временный необновляемый объект?
Реклама
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Сложный вопрос AVR на С про volatile to const

Сообщение Reflector »

[uquote="alex68md",url="/forum/viewtopic.php?p=3622565#p3622565"]т.е. даже если нам удастьтся передать всеми правдами и не правдами (как rvalue ссылку или даже как поинтер или еще как) инверсное значение состотояния порта, то в цикле будет участвовать не реальное каждый раз занаво считываемое значение а какойто временный необновляемый объект?[/uquote]
Допустим на входе порта одни нули, тогда результатом выполнения ~port или ~*port будет ~0 или 0xFFFF(для AVR). Дальше передавай это значение куда хочешь, никаких портов тут уже нет.
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Сложный вопрос AVR на С про volatile to const

Сообщение Dimon456 »

Где гарантия что там будет ~0 или 0xFFFF, может там будет 0xB3 или еще что?
К примеру у Леонардо на выводе PD5 висит светодиод и он конфигурируется как выход (USB то будете использовать), вы можете предсказать состояние этого светодиода? Может еще что на портД повесите.
Это ~port или это ~*port читает полностью порт, надо конкретный пин читать.

Вы читаете состояние пина порта, в зависимости от этого состояния принимаете решение 0 ждать на порту или 1, или опять не так?
Реклама
Эиком - электронные компоненты и радиодетали
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Сложный вопрос AVR на С про volatile to const

Сообщение alex68md »

Reflector , почему нет ?
если эта инверсия производиться только для сверки и не меняет реальный порт. то всё там нормально.
но я не понял в WHILE он (порт) будет каждый раз заново считываться и инвертироваться во время сверки ? по идее да. но лучше спрошу у более знающих

вот например

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

// Example program
#include <iostream>
#include <string>


void soft_reset(const uint8_t &port = 1, const uint8_t &pin = 1){
  
  uint8_t result = port & pin;
  printf("PINC = %hhu ", port);
  printf("PC6 = %hhu ", pin);
  printf("result = %hhu \n", result);

}

void isPIRLow(uint8_t &port, uint8_t &pin){
    soft_reset(port, pin);
//finish when PD0 low
}

void isPIRHigh(uint8_t &port, uint8_t &pin){
    soft_reset(~port, pin);
//finish when PD0 high
}


int main()
{
    //PINC ^= 1<<7;
    //PINC & 1<<7; //= 128

  uint8_t PINC = 0b10100001;
  printf("PINC = %hhu ", PINC);
  uint8_t PC6 = 1<<6;
  printf("PC6 = %hhu \n", PC6);
  
  uint8_t &port = PINC;
  uint8_t &pin = PC6;
  /////////////////////////////
  
  isPIRLow(port, pin);
  isPIRHigh(port, pin);


  printf("PINC = %hhu ", PINC);
  printf("PC6 = %hhu \n", PC6);
  PINC = 0b11100001;
  
  
  isPIRLow(port, pin);
  isPIRHigh(port, pin);
  
  
  printf("PINC = %hhu ", port);
  printf("PC6 = %hhu \n", pin);
   
}
показывает что просто сравнение uint8_t result = port & pin; не меняет порт даже если мы туда его передали через инверсию. или я не понял?

Добавлено after 5 minutes 11 seconds:
Dimon, всё так. но для проверки пина нам же нужно считать весь порт ? port&pin
у меня в WHILE как раз port&pin
Реклама
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Сложный вопрос AVR на С про volatile to const

Сообщение Dimon456 »

alex68md писал(а):Dimon, всё так. но для проверки пина нам же нужно считать весь порт ? port&pin
у меня в WHILE как раз port&pin
Все верно, но пока вы ждете 8 секунд необходимый импульс на определенном пине, а на PD5 USB решил 1 выставить, 4к коду, там не известно что выполняется, могут и прерывания USB использоваться
Спойлер

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

#include <mega32u4.h>

// Declare your global variables here

// USB general interrupt service routine
interrupt [USB_GENERAL] void usb_general_isr(void)
{
if (USBINT & (1<<VBUSTI))
   {
   // IVBUS Transition interrupt
   // Place your code here

   }
// Clear the interrupt flag
USBINT=(0<<VBUSTI);
}

// USB Endpoint interrupt service routine
interrupt [USB_ENDPOINT] void usb_endpoint_isr(void)
{
if (UEINTX & (1<<TXINI))
   {
   // Transmitter Ready interrupt
   // Place your code here

   }
if (UEINTX & (1<<STALLEDI))
   {
   // STALL interrupt
   // Place your code here

   }
if (UEINTX & (1<<RXOUTI))
   {
   // Received OUT Data interrupt
   // Place your code here

   }
if (UEINTX & (1<<RXSTPI))
   {
   // Received SETUP interrupt
   // Place your code here

   }
if (UEINTX & (1<<NAKOUTI))
   {
   // NAK OUT Received interrupt
   // Place your code here

   }
if (UEINTX & (1<<NAKINI))
   {
   // NAK IN Received interrupt
   // Place your code here

   }
// Clear the interrupt flags
UEINTX&=~((1<<NAKINI) | (1<<NAKOUTI) | (1<<RXSTPI) | (1<<RXOUTI) | (1<<STALLEDI) | (1<<TXINI));

if (UESTA0X & (1<<UNDERFI))
   {
   // Underflow Error interrupt
   // Place your code here

   }
if (UESTA0X & (1<<OVERFI))
   {
   // Overflow Error interrupt
   // Place your code here

   }
// Clear the interrupt flags
UESTA0X&=~((1<<OVERFI) | (1<<UNDERFI));
}
По этому

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

level = ((D_PIN&(1<<D_INT))>>D_INT);       	//получение состояния пина порта
результат выполнения этой функции будет либо 0 либо 1, лишнее отсеяли. Ни знаю, может красивее можно сделать, может макросом каким.

В компиляторе CVAVR есть специальная функция для этих целей
Изображение4 строчки ассемблерного кода.
Реклама
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Сложный вопрос AVR на С про volatile to const

Сообщение alex68md »

совершено верно level = ((D_PIN&(1<<D_INT))>>D_INT);
можно отбросить обратный шифт
level = PIND & 1 << 6; //64 это всеравно читается как true/high если 6ой бит у порта 1 и не важно какие остальные биты и что с ними там сделает USB
т.е. PORT & PIN я в while так и проверяю while (port&pin) но можно и обратный шифт сделать для ясности. ну это риторика

пока я не понял до конца вот этот вопрос

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

void soft_reset(volatile uint8_t&& port){
	while(port & 1);
}

soft_reset( ~PIND);
в цикле будет участвовать реальное каждый раз занаво считываемое значение или какойто закэшированный необновляемый объект?



PS:// пока переписал код под ваш с level
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Сложный вопрос AVR на С про volatile to const

Сообщение Reflector »

[uquote="alex68md",url="/forum/viewtopic.php?p=3622632#p3622632"]пока я не понял до конца вот этот вопрос[/uquote]
Что происходит как когда компилятор встречает ~port?
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Сложный вопрос AVR на С про volatile to const

Сообщение Dimon456 »

alex68md писал(а):в цикле будет участвовать реальное каждый раз занаво считываемое значение или какойто закэшированный необновляемый объект?
Нет, не будет он так работать.
Вот так будет

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

void soft_reset(volatile uint8_t *port){
   while(~(*port) & 1);
}

soft_reset( &PIND);
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Сложный вопрос AVR на С про volatile to const

Сообщение alex68md »

Dimon, блин значит придёться остаться на вашем коде с level. я просто хотел избавиться от еще одного аргумента в функции. но видно одним & не получиться и high и low проверять :(

Reflector, я это понимаю так>>
условно первая колонка время : далее что происходит
1мс : port // 1100
10мс : перелаем в soft_reset ~port //0011
11мс : проверяем в while (0011 & 1)
14мс : тк предыдущее true еще раз запрашиваем ~port и проверяем его в while (0011 & 1)
15мс : порт изменил свое значение на 1111 //на входе появился high например. это изменение порта в не программы
16мс : т.к. проверка на 14мс была true еще раз запрашиваем ~port и проверяем его в while (0000 & 1)
17мс : выходим из while
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Сложный вопрос AVR на С про volatile to const

Сообщение Reflector »

[uquote="alex68md",url="/forum/viewtopic.php?p=3622641#p3622641"]я это понимаю так>>
условно первая колонка время : далее что происходит
1мс : port // 1100
10мс : перелаем в soft_reset ~port //0011
11мс : проверяем в while (0011 & 1)
14мс : тк предыдущее true еще раз запрашиваем ~port и проверяем его в while (0011 & 1)[/uquote]
В функцию передается адрес, в цикле читается значение по этому адресу, если передали port, то это будет значение по адресу PINx, т.к. это реально существующий объект и этот адрес у него можно взять, но ~port - это выражение, можно только создать временную переменную, скопировать туда результат и передать адрес этой переменной. Потом читай по нему сколько хочешь, результат от этого не изменится.
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Сложный вопрос AVR на С про volatile to const

Сообщение alex68md »

большое спасибо всем!!!!

//сейчас подправлю немного
Последний раз редактировалось alex68md Чт апр 25, 2019 11:46:37, всего редактировалось 2 раза.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Сложный вопрос AVR на С про volatile to const

Сообщение ARV »

у вас что, по ходу программы опрашиваемый порт меняется? т.е. в одом случае вы должны чего-то ждать в PORTB, а в другом - в PORTD? если нет - к чему весь этот огород с передачей порта по его адресу? описали бы МАКРОС, и прописали бы его намертво в нужном месте. и с маской ожидания та же песня...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Сложный вопрос AVR на С про volatile to const

Сообщение alex68md »

нет, я везде проверяю PIND, в данном конкретном примере, т.к. там датчик/сенсор. огород с передачей адреса. чтобы в случае копировании кода на другой МК просто в макросе поменять пин,порт. красивее не придумал.
а с маской ожидания (уровня) можно как Dimon, вначале читаем состояние и проверяем инверсию. но я опять же с прицелом на универсальность жестко проверяю оба состояния. а то может датчик/сенсор или что там будет вдруг залипнет в одном состоянии или при переходе. да я понимаю что это возня в песочнице. ну так пошевелить мозгами, потренироваться никогда не вредно. сорри что так долго морочил вам голову.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Сложный вопрос AVR на С про volatile to const

Сообщение ARV »

alex68md писал(а):чтобы в случае копировании кода на другой МК просто в макросе поменять пин,порт
вот на этом и надо было остановиться :)

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

while((SENSOR_PORT & SENSOR_MASK) == SENSOR_VAL) //или по контексту
while((SENSOR_PORT & SENSOR_MASK) != SENSOR_VAL)
в любом проекте меняете эти три макроса и больше ничего не надо делать - все можно копипастить. и никакие ссылки не нужны, никакие указатели, никакие лишние многопараметровые функции. и код получится оптимальным и переносимым
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Сложный вопрос AVR на С про volatile to const

Сообщение Dimon456 »

ARV результат выполнения PIND & (1 << 1) даст либо 2 либо 0, соответственно програмер должен знать чему равно SENSOR_VAL.
Я подводил к результату либо 1 либо 0.

Пример, более компактный код, стырил с iomacros.h
Спойлер

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

#define D_PIN 	PIND
#define D_INT	5

#define bit_is_set_2(port, pin) ({                       \
         uint8_t __t;                                    \
         __asm__ __volatile__ (                          \
                 "clr %0" "\n\t"                         \
                 "sbic %1,%2" "\n\t"                     \
                 "inc %0"                                \
                 : "=r" (__t)                            \
                 : "I" ((uint8_t)(_SFR_IO_ADDR(port))),  \
                   "I" ((uint8_t)(pin))                  \
         );                                              \
         __t;                                            \
  })


while((level == bit_is_set_2(D_PIN,D_INT)));	\\ CP
while((level != bit_is_set_2(D_PIN,D_INT)));	\\ CPSE
while(!(level == bit_is_set_2(D_PIN,D_INT)));  \\ CPSE
while(!(level != bit_is_set_2(D_PIN,D_INT)));  \\ CP
while((level ^ bit_is_set_2(D_PIN,D_INT)));	 \\ CPSE
while(!(level ^ bit_is_set_2(D_PIN,D_INT)));	\\ CP
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Сложный вопрос AVR на С про volatile to const

Сообщение ARV »

Dimon456 писал(а):результат выполнения PIND & (1 << 1) даст либо 2 либо 0, соответственно програмер должен знать чему равно SENSOR_VAL
я это и написал. ваш вариант с 1 и 0 ничем абсолютно не отличается о варианта 0 и 2, или 0 и 8 - описал макрос и сравнивай с ним, результат будет или равно, или не равно. а чему конкретно равно/не равно - без разницы.

и да, ваш код намного компактней :))) а если учесть, что далеко не все порты доступны команде SBIC или SBIS, он еще и не совсем рабочий :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Сложный вопрос AVR на С про volatile to const

Сообщение Dimon456 »

ARV писал(а):и да, ваш код намного компактней :))) а если учесть, что далеко не все порты доступны команде SBIC или SBIS, он еще и не совсем рабочий
Это ж можно подкорректировать, две строчки поменять, делов то, два макроса использовать. О проблему нашли.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Сложный вопрос AVR на С про volatile to const

Сообщение ARV »

Dimon456 писал(а):делов то, два макроса использовать. О проблему нашли
два хуже, чем ни одного :)

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

Мой уютный бложик... заходите!
alex68md
Грызет канифоль
Сообщения: 275
Зарегистрирован: Сб янв 03, 2015 21:03:24

Re: Сложный вопрос AVR на С про volatile to const

Сообщение alex68md »

да ладно что вы сразу тролите :) яж только познаю многогранный мир с/с++
while((SENSOR_PORT & SENSOR_MASK) != SENSOR_VAL)
ну так это по сути тоже самое к чему я пришел выше. просто передаю значения в функцию а вы через макрос.

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

//остановился на таком варианте. красиво с одним while не получалось
void soft_reset(const uint8_t wdt_prescale, const volatile uint8_t *port, const uint8_t pin, const uint8_t level){
	wdt_enable(wdt_prescale);
	if (port == NULL) while (1);
	while ((*port & pin) ^ level);
	wdt_disable();
}
Ответить

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