Потребовалась динамическая индикация на разных портах одновременно. Написал код, но цифры сливаются. Вывожу 123, так вот первый разряд 1 светит ярко,но на нем же проступает 2 и 3 тусклее. Помогите советом. Камень Мега 8, среда Avr Studio 4.
//создаем глобальные переменные для хранения разрядов выводимого числа volatile char R1=0; volatile char R2=0; volatile char R3=0;
//======динамическая индикация============
void segment (char N) { switch (N) { case 0: PORTD|=(1<<5)|(1<<6); PORTB|=(1<<0)|(1<<2)|(1<<3)|(1<<4); break; // число 0 case 1: PORTD|=(1<<5); PORTB|=(1<<4); break; // число 1 case 2: PORTD|=(1<<5)|(1<<6); PORTB|=(1<<1)|(1<<2)|(1<<3); break; // число 2 case 3: PORTD|=(1<<5)|(1<<6); PORTB|=(1<<1)|(1<<3)|(1<<4); break; // число 3 case 4: PORTD|=(1<<5); PORTB|=(1<<0)|(1<<1)|(1<<4); break; // число 4 case 5: PORTD|=(1<<6); PORTB|=(1<<0)|(1<<1)|(1<<3)|(1<<4); break; // число 5 case 6: PORTD|=(1<<6)|(1<<7); PORTB|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4); break; // число 6 case 7: PORTD|=(1<<5)|(1<<6); PORTB|=(1<<4); break; // число 7 case 8: PORTD|=(1<<6)|(1<<7)|(1<<5); PORTB|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4); break; // число 8 case 9: PORTD|=(1<<6)|(1<<7)|(1<<5); PORTB|=(1<<0)|(1<<1)|(1<<3)|(1<<4); break; // число 9 case 10: PORTB|=(1<<1); break; // знак минус case 11: PORTD|=(1<<6)|(1<<5); PORTB|=(1<<0)|(1<<1); break; // знак градуса } }
switch (segcounter) { case 0: segment(R1); break; // Выводим первый разряд case 1: segment(R2); break; // Выводим второй разряд case 2: segment(R3); break; // Выводим третий разряд }
реализация ужасна. ознакомьтесь хотя бы бегло с принципами генерации символов...
что касается паразитной засветки, то: 1. гашение индикатора осуществляется ТОЛЬКО подачей нужного уровня на ОБЩИЕ КАТОДЫ или АНОДЫ, сегменты трогать не надо. гасите сразу все общие линии одновременно, если линии на разных портах - последовательно, но обязательно все. 2. после гашения выводите новое состояние сегментов. 3. потом включаете НУЖНЫЙ ОБЩИЙ КАТОД/АНОД - только один.
у вас в коде наоборот: сначала зажигаете индикатор, а потом подаете новые сегменты. само собой, некоторое время на новом индикаторе горят старые сегменты...
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
switch (segcounter) { case 0: segment(R1); break; // Выводим первый разряд case 1: segment(R2); break; // Выводим второй разряд case 2: segment(R3); break; // Выводим третий разряд }
заменить на
Код:
switch (segcounter) { case 0: { segment(R1); PORTC|=(1<<5); break; // Выводим первый разряд } case 1: { segment(R2); PORTC|=(1<<2); break; // Выводим второй разряд } case 2: { segment(R3); PORTC|=(1<<4); break; // Выводим третий разряд } }
Использование модульных источников питания открытого типа широко распространено в современных устройствах. Присущие им компактность, гибкость в интеграции и высокая эффективность делают их отличным решением для систем промышленной автоматизации, телекоммуникационного оборудования, медицинской техники, устройств «умного дома» и прочих приложений. Рассмотрим подробнее характеристики и особенности трех самых популярных вариантов AC/DC-преобразователей MW открытого типа, подходящих для применения в промышленных устройствах - серий EPS, EPP и RPS представленных на Meanwell.market.
//создаем глобальные переменные для хранения разрядов выводимого числа volatile char R1=0; volatile char R2=0; volatile char R3=0;
//======динамическая индикация============
void segment (char N) { switch (N) { case 0: PORTD|=(1<<5)|(1<<6); PORTB|=(1<<0)|(1<<2)|(1<<3)|(1<<4); break; // число 0 case 1: PORTD|=(1<<5); PORTB|=(1<<4); break; // число 1 case 2: PORTD|=(1<<5)|(1<<6); PORTB|=(1<<1)|(1<<2)|(1<<3); break; // число 2 case 3: PORTD|=(1<<5)|(1<<6); PORTB|=(1<<1)|(1<<3)|(1<<4); break; // число 3 case 4: PORTD|=(1<<5); PORTB|=(1<<0)|(1<<1)|(1<<4); break; // число 4 case 5: PORTD|=(1<<6); PORTB|=(1<<0)|(1<<1)|(1<<3)|(1<<4); break; // число 5 case 6: PORTD|=(1<<6)|(1<<7); PORTB|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4); break; // число 6 case 7: PORTD|=(1<<5)|(1<<6); PORTB|=(1<<4); break; // число 7 case 8: PORTD|=(1<<6)|(1<<7)|(1<<5); PORTB|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4); break; // число 8 case 9: PORTD|=(1<<6)|(1<<7)|(1<<5); PORTB|=(1<<0)|(1<<1)|(1<<3)|(1<<4); break; // число 9 case 10: PORTB|=(1<<1); break; // знак минус case 11: PORTD|=(1<<6)|(1<<5); PORTB|=(1<<0)|(1<<1); break; // знак градуса } }
//Эта функция принимает как аргумент число которое необходимо вывести. Эта функция меняет глобальные переменные разрядов чисел в соответствии с аргументом функции void print_led (int chislo) { R1=chislo%10; // 1ый разряд R2=(chislo%100)/10; // 2ой разряд R3=(chislo%1000)/100; // 3ий разряд }
//======динамическая индикация конец======
// Прерывание по переполнению T2, динамическая индикация ISR (TIMER2_OVF_vect) {
PORTC &=~((1<<2)|(1<<4)|(1<<5));//гасим все разряды PORTB &=~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)); // Гасим все сегменты PORTD &=~((1<<5)|(1<<6)|(1<<7)); // Гасим все сегменты
switch (segcounter) { case 0: { segment(R1); PORTC|=(1<<5); break; // Выводим первый разряд } case 1: { segment(R2); PORTC|=(1<<2); break; // Выводим второй разряд } case 2: { segment(R3); PORTC|=(1<<4); break; // Выводим третий разряд } }
Исключил таймер для фикса бага. Получился такой код:
Код:
while(1) {
segment(R1); PORTC|=(1<<5); _delay_ms(200);
PORTC &=~(1<<5);//гасим все разряды segment(12); //потушить все сегменты
segment(R2); PORTC|=(1<<2); _delay_ms(200);
PORTC &=~(1<<2);//гасим все разряды segment(12); //потушить все сегменты
segment(R3); PORTC|=(1<<4); _delay_ms(200);
PORTC &=~(1<<4);//гасим все разряды segment(12); //потушить все сегменты
R1=1; R2=2; R3=3;
Сейчас более наглядно как цифры переключаются. Но все равно сразу по 3. Нет момента когда цифра выключена. По три разряда горит. Такое чувство, что внутри контроллера через диод подтекает что ли.
Всем спасибо, за помощь. Нашел проблему. В общем мой самый первый код рабочий. У меня катоды через ULN2003A включены, забыл ее запитать. Все работает. Вот код, может кому пригодится.
//создаем глобальные переменные для хранения разрядов выводимого числа volatile char R1=0; volatile char R2=0; volatile char R3=0;
//======динамическая индикация============
void segment (char N) {
switch (N) { case 0: PORTD|=(1<<5)|(1<<6); PORTB|=(1<<0)|(1<<2)|(1<<3)|(1<<4); break; // число 0 case 1: PORTD|=(1<<5); PORTB|=(1<<4); break; // число 1 case 2: PORTD|=(1<<5)|(1<<6); PORTB|=(1<<1)|(1<<2)|(1<<3); break; // число 2 case 3: PORTD|=(1<<5)|(1<<6); PORTB|=(1<<1)|(1<<3)|(1<<4); break; // число 3 case 4: PORTD|=(1<<5); PORTB|=(1<<0)|(1<<1)|(1<<4); break; // число 4 case 5: PORTD|=(1<<6); PORTB|=(1<<0)|(1<<1)|(1<<3)|(1<<4); break; // число 5 case 6: PORTD|=(1<<6); PORTB|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4); break; // число 6 case 7: PORTD|=(1<<5)|(1<<6); PORTB|=(1<<4); break; // число 7 case 8: PORTD|=(1<<6)|(1<<5); PORTB|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4); break; // число 8 case 9: PORTD|=(1<<6)|(1<<5); PORTB|=(1<<0)|(1<<1)|(1<<3)|(1<<4); break; // число 9 case 10: PORTB|=(1<<1); break; // знак минус case 11: PORTD|=(1<<6)|(1<<5); PORTB|=(1<<0)|(1<<1); break; // знак градуса case 12: PORTD|=0; PORTB|=0; break; // знак градуса } }
//Эта функция принимает как аргумент число которое необходимо вывести. Эта функция меняет глобальные переменные разрядов чисел в соответствии с аргументом функции void print_led (int chislo) { R1=chislo%10; // 1ый разряд R2=(chislo%100)/10; // 2ой разряд R3=(chislo%1000)/100; // 3ий разряд }
//======динамическая индикация конец======
// Прерывание по переполнению T2, динамическая индикация ISR (TIMER2_OVF_vect) {
PORTB &=~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)); // Гасим все сегменты PORTD &=~((1<<5)|(1<<6)|(1<<7)); // Гасим все сегменты PORTC &=~((1<<2)|(1<<4)|(1<<5));//гасим все разряды
switch (segcounter) { case 0: segment(R1); PORTC|=(1<<5); break; // Выводим первый разряд case 1: segment(R2); PORTC|=(1<<2); break; // Выводим второй разряд case 2: segment(R3); PORTC|=(1<<4); break; // Выводим третий разряд }
я уже столько раз писал - воспользуйтесь поиском по форуму. в конце-концов, загляните на мой сайт.
Вот этим все и сказано.
P.S. Да и сайт Ваш сплошная копипаста интернета. Своего либо нет, либо совсем мало. Динамической индикации посредством РАЗНЫХ битов разных портов там НЕТ.
Да и сайт Ваш сплошная копипаста интернета. Своего либо нет, либо совсем мало. Динамической индикации посредством РАЗНЫХ битов разных портов там НЕТ.
вы отдаете себе отчет, что вы такое сейчас сказанули? на моем сайте все проекты (кроме буквально пары) исключительно МОИ. это в интернете полно плагиата с моего сайта - все мои таймеры скоммуниздены практически на каждый радиолюбительский сайт. проекты, которые в былые времена я размещал на радиокоте - все скопированы на другие сайты, и большинство без указания авторства.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
СпойлерВот объясните - почему некотрые новички еще 2*2 как след написать не могут, а как затешутся в форум - сразу начинают поучать и раздавать шпиндюлей? Одно хорошо - их форумный век обычно недолог .
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 20
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения