Страница 3 из 4
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Ср апр 24, 2019 12:36:30
ARV
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Ср апр 24, 2019 15:07:36
alex68md
Dimon, Refletor
" а сейчас ~*port читает с порта один раз в момент передачи в функцию, потом там в цикле проверяется одно и то же значение. Со ссылками будет то же самое."
т.е. даже если нам удастьтся передать всеми правдами и не правдами (как rvalue ссылку или даже как поинтер или еще как) инверсное значение состотояния порта, то в цикле будет участвовать не реальное каждый раз занаво считываемое значение а какойто временный необновляемый объект?
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Ср апр 24, 2019 15:28:34
Reflector
[uquote="alex68md",url="/forum/viewtopic.php?p=3622565#p3622565"]т.е. даже если нам удастьтся передать всеми правдами и не правдами (как rvalue ссылку или даже как поинтер или еще как) инверсное значение состотояния порта, то в цикле будет участвовать не реальное каждый раз занаво считываемое значение а какойто временный необновляемый объект?[/uquote]
Допустим на входе порта одни нули, тогда результатом выполнения ~port или ~*port будет ~0 или 0xFFFF(для AVR). Дальше передавай это значение куда хочешь, никаких портов тут уже нет.
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Ср апр 24, 2019 16:38:56
Dimon456
Где гарантия что там будет ~0 или 0xFFFF, может там будет 0xB3 или еще что?
К примеру у Леонардо на выводе PD5 висит светодиод и он конфигурируется как выход (USB то будете использовать), вы можете предсказать состояние этого светодиода? Может еще что на портД повесите.
Это ~port или это ~*port читает полностью порт, надо конкретный пин читать.
Вы читаете состояние пина порта, в зависимости от этого состояния принимаете решение 0 ждать на порту или 1, или опять не так?
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Ср апр 24, 2019 16:49:14
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
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Ср апр 24, 2019 17:18:11
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 строчки ассемблерного кода.
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Ср апр 24, 2019 17:47:32
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
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Ср апр 24, 2019 17:53:25
Reflector
[uquote="alex68md",url="/forum/viewtopic.php?p=3622632#p3622632"]пока я не понял до конца вот этот вопрос[/uquote]
Что происходит как когда компилятор встречает ~port?
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Ср апр 24, 2019 18:05:15
Dimon456
alex68md писал(а):в цикле будет участвовать реальное каждый раз занаво считываемое значение или какойто закэшированный необновляемый объект?
Нет, не будет он так работать.
Вот так будет
Код: Выделить всё
void soft_reset(volatile uint8_t *port){
while(~(*port) & 1);
}
soft_reset( &PIND);
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Ср апр 24, 2019 18:20:20
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
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Чт апр 25, 2019 08:40:11
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 - это выражение, можно только создать временную переменную, скопировать туда результат и передать адрес этой переменной. Потом читай по нему сколько хочешь, результат от этого не изменится.
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Чт апр 25, 2019 10:18:18
alex68md
большое спасибо всем!!!!
//сейчас подправлю немного
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Чт апр 25, 2019 10:23:39
ARV
у вас что, по ходу программы опрашиваемый порт меняется? т.е. в одом случае вы должны чего-то ждать в PORTB, а в другом - в PORTD? если нет - к чему весь этот огород с передачей порта по его адресу? описали бы МАКРОС, и прописали бы его намертво в нужном месте. и с маской ожидания та же песня...
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Чт апр 25, 2019 11:00:28
alex68md
нет, я везде проверяю PIND, в данном конкретном примере, т.к. там датчик/сенсор. огород с передачей адреса. чтобы в случае копировании кода на другой МК просто в макросе поменять пин,порт. красивее не придумал.
а с маской ожидания (уровня) можно как Dimon, вначале читаем состояние и проверяем инверсию. но я опять же с прицелом на универсальность жестко проверяю оба состояния. а то может датчик/сенсор или что там будет вдруг залипнет в одном состоянии или при переходе. да я понимаю что это возня в песочнице. ну так пошевелить мозгами, потренироваться никогда не вредно. сорри что так долго морочил вам голову.
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Чт апр 25, 2019 11:10:28
ARV
alex68md писал(а):чтобы в случае копировании кода на другой МК просто в макросе поменять пин,порт
вот на этом и надо было остановиться

Код: Выделить всё
while((SENSOR_PORT & SENSOR_MASK) == SENSOR_VAL) //или по контексту
while((SENSOR_PORT & SENSOR_MASK) != SENSOR_VAL)
в любом проекте меняете эти три макроса и больше ничего не надо делать - все можно копипастить. и никакие ссылки не нужны, никакие указатели, никакие лишние многопараметровые функции. и код получится оптимальным и переносимым
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Чт апр 25, 2019 15:10:54
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
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Чт апр 25, 2019 15:19:28
ARV
Dimon456 писал(а):результат выполнения PIND & (1 << 1) даст либо 2 либо 0, соответственно програмер должен знать чему равно SENSOR_VAL
я это и написал. ваш вариант с 1 и 0 ничем абсолютно не отличается о варианта 0 и 2, или 0 и 8 - описал макрос и сравнивай с ним, результат будет или равно, или не равно. а чему конкретно равно/не равно - без разницы.
и да, ваш код намного компактней

а если учесть, что далеко не все порты доступны команде SBIC или SBIS, он еще и не совсем рабочий

Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Чт апр 25, 2019 16:18:35
Dimon456
ARV писал(а):и да, ваш код намного компактней

а если учесть, что далеко не все порты доступны команде SBIC или SBIS, он еще и не совсем рабочий
Это ж можно подкорректировать, две строчки поменять, делов то, два макроса использовать. О проблему нашли.
Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Чт апр 25, 2019 17:37:17
ARV
Dimon456 писал(а):делов то, два макроса использовать. О проблему нашли
два хуже, чем ни одного
но по сравнению с проблемой топикстартера это и вправду не проблема

Re: Сложный вопрос AVR на С про volatile to const
Добавлено: Чт май 09, 2019 12:41:44
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();
}