Решил снять показания с dht-22 и вывести их на дисплей. При этом считываю показания датчика прерываниями int1. Но чтобы я не делал (врубал volatile, отключал оптимизацию) глобальная переменная i не меняется. Тестирую в протеусе 8. В качестве проверки вывожу на дисплей "5", но так как переменная не меняется, то остаётся "B". Прошу, помогите, я новичок. UPD: снял надпись "B", потому что она несколько раз должна была гасить "5", но по итогу на экране всё равно "1", то есть i вообще не меняется.
Код:
char data[5]={0, 0, 0, 0, 0}; volatile uint8_t lll=7; int n=0; ISR(INT1_vect) { switch(pre) { case 2: pre=3; TCNT0=0; break;
case 3: if (TCNT0>=80) { pre=4; position (1,20); str_send("1"); } else { pre=99; position (1,20); str_send("2"); }
case 4: pre=5; TCNT0=0; //TIMSK|=(1<<TOIE0); break;
case 5: if (TCNT0>=50) { pre=6; position (1,20); str_send("B"); TCNT0=0; } else { pre=100; position (1,20); str_send("C"); } break;
Но чтобы я не делал (врубал volatile, отключал оптимизацию)
В первую очередь нужно ВКЛЮЧИТЬ оптимизацию и логику внутри своего кода. И переменные называть нормально, и комментарии писать. А так вообще нефига не ясно, что за дичь тут происходит, и самое главное, зачем?
Так как то режет глаз изменение переменной pre внутри switch(pre).
Это нормальная конструкция. А режет глаз написание "как то" вместо "как-то" - это два разных смысла, для программиста неприемлемо игнорировать дефис.
Добавлено after 2 minutes 31 second: Между case 3 и case 4 пропущен break; Не знаю, что означает position(1, 20), но если это что-то типа строка-символ и автоматического сдвига нет, то высвечиваться всегда будет один символ.
Компания MEAN WELL пополнила ассортимент своей широкой линейки светодиодных драйверов новым семейством XLC для внутреннего освещения. Главное отличие – поддержка широкого спектра проводных и беспроводных технологий диммирования. Новинки представлены в MEANWELL.market моделями с мощностями 25 Вт, 40 Вт и 60 Вт. В линейке есть модели, работающие как в режиме стабилизации тока (СС), так и в режиме стабилизации напряжения (CV) значением 12, 24 и 48 В.
Спасибо Мартиану, действительно забыл break. Ещё день назад победил i, и она теперь меняется, но с p не выходит. Сейчас вроде всё закомментировал подробно. Помогите, прошу. Вот весь код.
case 3: if (TCNT0>=80) //если датчик в ответ отпустил линию на 80 мкс, то всё хорошо { pre=4; } else { pre=99; position (1,20); str_send(" Error"); } break;
case 4: pre=5; TCNT0=0; //ожидаем первый бит 80 мкс break;
case 5: if (TCNT0>=80) //если всё хорошо, то прерывание будет через 80 мкс, начало отсчёта сигнала "старт" { pre=6; TCNT0=0; } else { pre=100; position (1,20); str_send("Error"); } break;
case 6: if (TCNT0>=50) //если датчик прижал линию на >50 мкс, то начинаем фиксировать биты { pre=7; TCNT0=0; } else { pre=100; position (1,20); str_send("Error"); } break;
case 7: if (TCNT0>=70) //если больше 70 мкс, то "1" { data[p]|=(1<<i); } if (i!=0) //уменьшаем занчение i, отсчитывающей номер бита { i--; pre=6; TCNT0=0; } if (i==0) { p++; //если байт закончился, то начинаем следующий i=7; if (p==5) { pre=8; //если байты закончились, заканчиваем передачу TCNT0=0; } else { pre=6; //если нет, то заново переходим в 6 TCNT0=0; } } break;
case 8: if (TCNT0>=80) //если пауза 80 мкс, то заканчиваем передачу { pre=0; TIMSK|=(1<<TOIE0); TCNT0=250; } else { position(1, 20); str_send ("Error"); } break; } } void lcd() { while(status!=9); position (0, 0); str_send("Temperature:"); position (1,0); str_send("Humidity:"); position (0,20); str_send("Pressure:"); //position (1,20); //str_send("Radiation:"); } int main(void) { sei(); init_timer(); DDRD|=(1<<5)|(1<<6); DDRB|=(1<<4)|(1<<5)|(1<<6)|(1<<7); DDRD&=~(1<<3);
TCNT0=235; lcd(); //init_timer2(); //TCNT2=240; while (1) { } }
я делал else, но надеялся на чудо, когда менял его на if. Типо, может он решил, что else относится к другому if. Не помогло. А как в данной программе контролировать флаги прерываний не внутри прерываний? Ведь в main нельзя угадать момент.
как уже сказали коллеги выше, продолжайте оптимизацию. Ловить блох в неоптимизированном коде лень. например:
Код:
if (i!=0) //уменьшаем занчение i, отсчитывающей номер бита { i--; pre=6; TCNT0=0; } if (i==0) { p++; //если байт закончился, то начинаем следующий i=7; if (p==5) { pre=8; //если байты закончились, заканчиваем передачу TCNT0=0; } else { pre=6; //если нет, то заново переходим в 6 TCNT0=0; } }
очевидно же, что просится
Код:
if (i!=0) //уменьшаем занчение i, отсчитывающей номер бита { i--; pre=6; } if (i==0) { i=7; if (++p==5) { pre=8; //если байты закончились, заканчиваем передачу } else { pre=6; //если нет, то заново переходим в 6 } } TCNT0=0;
Здесь, кстати, могут отработать оба условия, если i = 1
Далее:
Код:
switch(status) { case 0: writeB(3); status=1; TCNT0=250; break;
case 1: //TCNT0=240; writeB(3); status=2; TCCR0=1; TCNT0=105; break;
case 2: //TCCR0=1; //TCNT0=125; writeB(3); status=3; TCNT0=195; break; ...
Если везде status становится больше на 1, то почему его не инкрементировать после switch один раз, а не в каждом case? Полагаю, даже такое сработает:
Код:
switch(status++) //а здесь написать комментарий, почему статус инкрементируется.
Последний раз редактировалось Martian Пн авг 14, 2023 16:40:31, всего редактировалось 2 раз(а).
это очень помогает, так как убирает ненужные строки, упрощает чтение (понимание кода), а также позволяют сделать логику менее ошибочной. например, veso74 предложил else. В случае с i == 1 с else и без него логика выполнения меняется.
Сейчас этот форум просматривают: Google Adsense [Bot] и гости: 14
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения