Сложный вопрос AVR на С про volatile to const
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Сложный вопрос AVR на С про volatile to const
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
Re: Сложный вопрос AVR на С про volatile to const
Dimon, Refletor
" а сейчас ~*port читает с порта один раз в момент передачи в функцию, потом там в цикле проверяется одно и то же значение. Со ссылками будет то же самое."
т.е. даже если нам удастьтся передать всеми правдами и не правдами (как rvalue ссылку или даже как поинтер или еще как) инверсное значение состотояния порта, то в цикле будет участвовать не реальное каждый раз занаво считываемое значение а какойто временный необновляемый объект?
" а сейчас ~*port читает с порта один раз в момент передачи в функцию, потом там в цикле проверяется одно и то же значение. Со ссылками будет то же самое."
т.е. даже если нам удастьтся передать всеми правдами и не правдами (как rvalue ссылку или даже как поинтер или еще как) инверсное значение состотояния порта, то в цикле будет участвовать не реальное каждый раз занаво считываемое значение а какойто временный необновляемый объект?
Re: Сложный вопрос AVR на С про volatile to const
[uquote="alex68md",url="/forum/viewtopic.php?p=3622565#p3622565"]т.е. даже если нам удастьтся передать всеми правдами и не правдами (как rvalue ссылку или даже как поинтер или еще как) инверсное значение состотояния порта, то в цикле будет участвовать не реальное каждый раз занаво считываемое значение а какойто временный необновляемый объект?[/uquote]
Допустим на входе порта одни нули, тогда результатом выполнения ~port или ~*port будет ~0 или 0xFFFF(для AVR). Дальше передавай это значение куда хочешь, никаких портов тут уже нет.
Допустим на входе порта одни нули, тогда результатом выполнения ~port или ~*port будет ~0 или 0xFFFF(для AVR). Дальше передавай это значение куда хочешь, никаких портов тут уже нет.
Re: Сложный вопрос AVR на С про volatile to const
Где гарантия что там будет ~0 или 0xFFFF, может там будет 0xB3 или еще что?
К примеру у Леонардо на выводе PD5 висит светодиод и он конфигурируется как выход (USB то будете использовать), вы можете предсказать состояние этого светодиода? Может еще что на портД повесите.
Это ~port или это ~*port читает полностью порт, надо конкретный пин читать.
Вы читаете состояние пина порта, в зависимости от этого состояния принимаете решение 0 ждать на порту или 1, или опять не так?
К примеру у Леонардо на выводе PD5 висит светодиод и он конфигурируется как выход (USB то будете использовать), вы можете предсказать состояние этого светодиода? Может еще что на портД повесите.
Это ~port или это ~*port читает полностью порт, надо конкретный пин читать.
Вы читаете состояние пина порта, в зависимости от этого состояния принимаете решение 0 ждать на порту или 1, или опять не так?
Re: Сложный вопрос AVR на С про volatile to const
Reflector , почему нет ?
если эта инверсия производиться только для сверки и не меняет реальный порт. то всё там нормально.
но я не понял в WHILE он (порт) будет каждый раз заново считываться и инвертироваться во время сверки ? по идее да. но лучше спрошу у более знающих
вот например
показывает что просто сравнение uint8_t result = port & pin; не меняет порт даже если мы туда его передали через инверсию. или я не понял?
Добавлено after 5 minutes 11 seconds:
Dimon, всё так. но для проверки пина нам же нужно считать весь порт ? port&pin
у меня в WHILE как раз port&pin
если эта инверсия производиться только для сверки и не меняет реальный порт. то всё там нормально.
но я не понял в 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);
}
Добавлено after 5 minutes 11 seconds:
Dimon, всё так. но для проверки пина нам же нужно считать весь порт ? port&pin
у меня в WHILE как раз port&pin
- Реклама
Re: Сложный вопрос AVR на С про volatile to const
Все верно, но пока вы ждете 8 секунд необходимый импульс на определенном пине, а на PD5 USB решил 1 выставить, 4к коду, там не известно что выполняется, могут и прерывания USB использоватьсяalex68md писал(а):Dimon, всё так. но для проверки пина нам же нужно считать весь порт ? port&pin
у меня в WHILE как раз port&pin
Спойлер
Код: Выделить всё
#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); //получение состояния пина портаВ компиляторе CVAVR есть специальная функция для этих целей
4 строчки ассемблерного кода.Re: Сложный вопрос AVR на С про volatile to const
совершено верно level = ((D_PIN&(1<<D_INT))>>D_INT);
можно отбросить обратный шифт
level = PIND & 1 << 6; //64 это всеравно читается как true/high если 6ой бит у порта 1 и не важно какие остальные биты и что с ними там сделает USB
т.е. PORT & PIN я в while так и проверяю while (port&pin) но можно и обратный шифт сделать для ясности. ну это риторика
пока я не понял до конца вот этот вопрос
в цикле будет участвовать реальное каждый раз занаво считываемое значение или какойто закэшированный необновляемый объект?
PS:// пока переписал код под ваш с level
можно отбросить обратный шифт
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
[uquote="alex68md",url="/forum/viewtopic.php?p=3622632#p3622632"]пока я не понял до конца вот этот вопрос[/uquote]
Что происходит как когда компилятор встречает ~port?
Что происходит как когда компилятор встречает ~port?
Re: Сложный вопрос AVR на С про volatile to const
Нет, не будет он так работать.alex68md писал(а):в цикле будет участвовать реальное каждый раз занаво считываемое значение или какойто закэшированный необновляемый объект?
Вот так будет
Код: Выделить всё
void soft_reset(volatile uint8_t *port){
while(~(*port) & 1);
}
soft_reset( &PIND);Re: Сложный вопрос AVR на С про volatile to const
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, я это понимаю так>>
условно первая колонка время : далее что происходит
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
[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 - это выражение, можно только создать временную переменную, скопировать туда результат и передать адрес этой переменной. Потом читай по нему сколько хочешь, результат от этого не изменится.
условно первая колонка время : далее что происходит
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
большое спасибо всем!!!!
//сейчас подправлю немного
//сейчас подправлю немного
Последний раз редактировалось alex68md Чт апр 25, 2019 11:46:37, всего редактировалось 2 раза.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Сложный вопрос AVR на С про volatile to const
у вас что, по ходу программы опрашиваемый порт меняется? т.е. в одом случае вы должны чего-то ждать в PORTB, а в другом - в PORTD? если нет - к чему весь этот огород с передачей порта по его адресу? описали бы МАКРОС, и прописали бы его намертво в нужном месте. и с маской ожидания та же песня...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Сложный вопрос AVR на С про volatile to const
нет, я везде проверяю PIND, в данном конкретном примере, т.к. там датчик/сенсор. огород с передачей адреса. чтобы в случае копировании кода на другой МК просто в макросе поменять пин,порт. красивее не придумал.
а с маской ожидания (уровня) можно как Dimon, вначале читаем состояние и проверяем инверсию. но я опять же с прицелом на универсальность жестко проверяю оба состояния. а то может датчик/сенсор или что там будет вдруг залипнет в одном состоянии или при переходе. да я понимаю что это возня в песочнице. ну так пошевелить мозгами, потренироваться никогда не вредно. сорри что так долго морочил вам голову.
а с маской ожидания (уровня) можно как Dimon, вначале читаем состояние и проверяем инверсию. но я опять же с прицелом на универсальность жестко проверяю оба состояния. а то может датчик/сенсор или что там будет вдруг залипнет в одном состоянии или при переходе. да я понимаю что это возня в песочнице. ну так пошевелить мозгами, потренироваться никогда не вредно. сорри что так долго морочил вам голову.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Сложный вопрос AVR на С про volatile to const
вот на этом и надо было остановитьсяalex68md писал(а):чтобы в случае копировании кода на другой МК просто в макросе поменять пин,порт
Код: Выделить всё
while((SENSOR_PORT & SENSOR_MASK) == SENSOR_VAL) //или по контексту
while((SENSOR_PORT & SENSOR_MASK) != SENSOR_VAL)если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Сложный вопрос AVR на С про volatile to const
ARV результат выполнения PIND & (1 << 1) даст либо 2 либо 0, соответственно програмер должен знать чему равно SENSOR_VAL.
Я подводил к результату либо 1 либо 0.
Пример, более компактный код, стырил с iomacros.h
Я подводил к результату либо 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
я это и написал. ваш вариант с 1 и 0 ничем абсолютно не отличается о варианта 0 и 2, или 0 и 8 - описал макрос и сравнивай с ним, результат будет или равно, или не равно. а чему конкретно равно/не равно - без разницы.Dimon456 писал(а):результат выполнения PIND & (1 << 1) даст либо 2 либо 0, соответственно програмер должен знать чему равно SENSOR_VAL
и да, ваш код намного компактней
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Сложный вопрос AVR на С про volatile to const
Это ж можно подкорректировать, две строчки поменять, делов то, два макроса использовать. О проблему нашли.ARV писал(а):и да, ваш код намного компактнейа если учесть, что далеко не все порты доступны команде SBIC или SBIS, он еще и не совсем рабочий
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Сложный вопрос AVR на С про volatile to const
два хуже, чем ни одногоDimon456 писал(а):делов то, два макроса использовать. О проблему нашли
но по сравнению с проблемой топикстартера это и вправду не проблема
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Сложный вопрос AVR на С про volatile to const
да ладно что вы сразу тролите
яж только познаю многогранный мир с/с++
ну так это по сути тоже самое к чему я пришел выше. просто передаю значения в функцию а вы через макрос.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();
}

