Обявления

Для полноценной работы рекомендуется пройти регистрацию.

Рекламные сообщения будут удаляться вместе с пользователем. Что есть реклама - буду решать я.

Динамическая индикация

Обсуждение проектов, не вошедших в предыдущие категории

Динамическая индикация

Сообщение Denis_K » 05 окт 2018 13:14

Пытаюсь написать код для таймера под свои нужды, но никак не выходит с индикацией... Разряды не перебираются по одному, а меняются сразу три цифры...
Например: пишу на вывод число 123, а выводится сначала 1, затем 2 и потом 3 на трех разрядах(111 >> 222 >> 333), все это зациклено. Хотя по задумке :) должно быть 1 в первом разряде, 2 во втором и 3 в третьем с числом на выходе 123. Что я делаю не так?

Добавлено спустя 3 часа 16 минут 17 секунд:
Вот код без скачивания...


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

#define F_CPU 8000000L

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

unsigned int i;
unsigned int R1=0, R2=0, R3=0;

void segchar (unsigned int seg)
{
   switch(seg)
   {
      case 1: PORTC = 0b11011111;                                       //PC1
              PORTB = 0b11110111;
      break;
      case 2: PORTC = 0b11011101;
              PORTB = 0b11011100;
      break;                                           //PC2                           //PC5
      case 3: PORTC = 0b11011101;
              PORTB = 0b11010101;
      break;
      case 4: PORTC = 0b11011011;
              PORTB = 0b11010111;
      break;                                                         //PB5
      case 5: PORTC = 0b11111001;
              PORTB = 0b11010101;
      break;
      case 6: PORTC = 0b11111001;
              PORTB = 0b11010100;
      break;                                        //PB0                           //PB3
      case 7: PORTC = 0b11011101;
              PORTB = 0b11110111;
      break;
      case 8: PORTC = 0b11011001;
              PORTB = 0b11010100;
      break;                                                      //PB1
      case 9: PORTC = 0b11011001;
              PORTB = 0b11010101;
      break;
      case 0: PORTC = 0b11011001;
              PORTB = 0b11110101;
      break;
   }   
}

void timer_ini(void)
{   
   TCCR1B |= (1<<WGM12);
   TIMSK1 |= (1<<OCIE1A);   
   OCR1AH = 0b00001111;
   OCR1AL = 0b00001010;
   TCCR1B |= (1<<CS12);
}

unsigned int n_count=0;

ISR (TIMER1_COMPA_vect)
{   
    if(n_count==0) {PORTC|=(1<<PORTC0);PORTC&=~(1<<PORTC3);PORTC&=~(1<<PORTC4);segchar(R1);}      
   if(n_count==1) {PORTC|=(1<<PORTC3);PORTC&=~(1<<PORTC4);PORTC&=~(1<<PORTC0);segchar(R2);}      
   if(n_count==2) {PORTC|=(1<<PORTC4);PORTC&=~(1<<PORTC0);PORTC&=~(1<<PORTC3);segchar(R3);}
      
   n_count++;
   if (n_count>2) n_count=0;
}

void ledprint(unsigned int number)
{   
   R1=number/100;         
   R2=(number%100)/10;     
   R3=(number%100)%10;    
}

int main(void)
{
   unsigned int butcount=0, butstate=0;
   timer_ini();
   DDRD = 0b00010000;
   DDRB = 0b11111111;
   DDRC = 0b11111111;
   PORTD = 0b00100000;
   PORTC = 0b11100110;
   PORTB = 0b11111111;
   i=0;
   sei();
   ledprint(123);
   
   while(1)
   {      
   }
   }
Вложения
main.rar
(935 байт) Скачиваний: 2
Denis_K
Частенько бываю
 
Сообщения: 73
Зарегистрирован: 16 июн 2017 13:48
Откуда: Краснодарский край

Re: Динамическая индикация

Сообщение IYra » 06 окт 2018 13:23

Denis_K писал(а): Вот код без скачивания...

1. В коде желательно больше комментариев. Особенно там где настраивается таймер.

2. Еще хорошо бы нарисовать модель в Протеусе и пройтись с отладчиком
IYra
Живу тут
 
Сообщения: 693
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Динамическая индикация

Сообщение Denis_K » 06 окт 2018 15:03

IYra, здравствуйте. Я бы с радостью воспользовался отладчиком, но к сожалению еще не научился им пользоваться :) А модель нарисованная есть...
Вот прокомментировал код:
Код: Выделить всё

#define F_CPU 8000000L

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

unsigned int i;
unsigned int R1=0, R2=0, R3=0;  // переменные разрядов

void segchar (unsigned int seg) // формирование цифры
{
   switch(seg) // сегменты находятся на портС и портВ
   {
      case 1: PORTC = 0b11011111;      //1                                 
              PORTB = 0b11110111;
      break;
      case 2: PORTC = 0b11011101;      //2
              PORTB = 0b11011100;
      break;                                           
      case 3: PORTC = 0b11011101;      //3
              PORTB = 0b11010101;
      break;
      case 4: PORTC = 0b11011011;      //4
              PORTB = 0b11010111;
      break;                                                         
      case 5: PORTC = 0b11111001;      //5
              PORTB = 0b11010101;
      break;
      case 6: PORTC = 0b11111001;      //6
              PORTB = 0b11010100;
      break;                                       
      case 7: PORTC = 0b11011101;      //7
              PORTB = 0b11110111;
      break;
      case 8: PORTC = 0b11011001;      //8
              PORTB = 0b11010100;
      break;                                                     
      case 9: PORTC = 0b11011001;      //9
              PORTB = 0b11010101;
      break;
      case 0: PORTC = 0b11011001;      //0
              PORTB = 0b11110101;
      break;
   }
}

void timer_ini(void)
{   
   TCCR1B |= (1<<WGM12);   // устанавливаем режим СТС
   TIMSK1 |= (1<<OCIE1A);  // разрешаем прерывания Т1   
   OCR1AH = 0b00001111;    // число для сравнения
   OCR1AL = 0b01000010;
   TCCR1B |= (1<<CS12);    // устанавливаем делитель
}

unsigned int n_count=0;

ISR (TIMER1_COMPA_vect) // вход в прерывание Т1
{   
    if(n_count==0) {PORTC|=(1<<PORTC0);PORTC&=~(1 <<PORTC3);PORTC&=~(1<<PORTC4);segchar(R1);}    // включаем первый разряд
   if(n_count==1) {PORTC|=(1<<PORTC3);PORTC&=~(1<<PORTC4);PORTC&=~(1<<PORTC0);segchar(R2);}    // включаем второй разряд   
   if(n_count==2) {PORTC|=(1<<PORTC4);PORTC&=~(1<<PORTC0);PORTC&=~(1<<PORTC3);segchar(R3);} // включаем третий разряд
      
   n_count++;
   if (n_count>2) n_count=0; // переключаем разряды 0,1,2
}

void ledprint(unsigned int number)
{   
   R1=number/100;          // сотни
   R2=(number%100)/10;     // десятки
   R3=(number%100)%10;       // единицы
}

int main(void)
{
   timer_ini();         // инициализация таймера
   DDRD = 0b00010000;   // установка портов на выход
   DDRB = 0b11111111;
   DDRC = 0b11111111;
   PORTD = 0b00100000;
   PORTC = 0b11100110;
   PORTB = 0b11111111;
   i=0;
   sei();               // разрешение прерываний
   ledprint(123);       // вывод числа 123
   
   while(1)
    {   
      
       }
   }
Denis_K
Частенько бываю
 
Сообщения: 73
Зарегистрирован: 16 июн 2017 13:48
Откуда: Краснодарский край

Re: Динамическая индикация

Сообщение IYra » 06 окт 2018 15:06

Denis_K писал(а): А модель нарисованная есть...

Ну так выкладывай - посмотрим
IYra
Живу тут
 
Сообщения: 693
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Динамическая индикация

Сообщение Denis_K » 06 окт 2018 15:13

Вот модель

Добавлено спустя 2 часа 14 минут 9 секунд:
Попробовал так:
Код: Выделить всё
ISR (TIMER1_COMPA_vect)
{   
   
   
    if(n_count==0) {PORTC|=(1<<PORTC0);PORTC&=~(1<<PORTC3);PORTC&=~(1<<PORTC4);segchar(ledprint(R1));}      
   if(n_count==1) {PORTC|=(1<<PORTC3);PORTC&=~(1<<PORTC4);PORTC&=~(1<<PORTC0);segchar(ledprint(R2));}      
   if(n_count==2) {PORTC|=(1<<PORTC4);PORTC&=~(1<<PORTC0);PORTC&=~(1<<PORTC3);segchar(ledprint(R3));}
      
   n_count++;
   if (n_count>2) n_count=0;
}

Теперь переключаются разряды, но как то раз через два... может тут лучше применить switch? я уже запутался...
Вложения
TOO_48.rar
(55.63 КБ) Скачиваний: 2
Denis_K
Частенько бываю
 
Сообщения: 73
Зарегистрирован: 16 июн 2017 13:48
Откуда: Краснодарский край

Re: Динамическая индикация

Сообщение IYra » 06 окт 2018 17:53

Denis_K писал(а):
Код: Выделить всё
ISR (TIMER1_COMPA_vect)
{   
    if(n_count==0) {PORTC|=(1<<PORTC0);PORTC&=~(1<<PORTC3);PORTC&=~(1<<PORTC4);segchar(ledprint(R1));}      
   if(n_count==1) {PORTC|=(1<<PORTC3);PORTC&=~(1<<PORTC4);PORTC&=~(1<<PORTC0);segchar(ledprint(R2));}      
   if(n_count==2) {PORTC|=(1<<PORTC4);PORTC&=~(1<<PORTC0);PORTC&=~(1<<PORTC3);segchar(ledprint(R3));}
      
   n_count++;
   if (n_count>2) n_count=0;
}


1. Что-то с таймером. Прерывание срабатывает каждые 130 мс. А должно максимум 10 мс. Надо уменьшать
2. Собери без оптимизации. В файле с расширением elf(отладочный) прочерки
IYra
Живу тут
 
Сообщения: 693
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Динамическая индикация

Сообщение Denis_K » 06 окт 2018 19:56

1) Делитель в настройке таймера я умышленно увеличил, что бы визуально наблюдать смену разрядов, т.к. таймер уже полностью собранный :) .
При уменьшении времени все три цифры сливаются в "8".
2)Собрал без оптимизации, все тоже самое, только размер вырос с 2кб до 4кб...

Добавлено спустя 28 минут 16 секунд:
Почему-то вот здесь if(n_count==0) {PORTC|=(1<<PORTC0);PORTC&=~(1<<PORTC3);PORTC&=~(1<<PORTC4);segchar(ledprint(R1));} не тухнут РС3 и РС4... все три разряда постоянно включены.

Добавлено спустя 14 часов 22 минуты 17 секунд:
Выяснилось, что при использовании одного портВ для вывода цифр - все работает, только комбинирую с портС, то разряды не переключаются...
Применил маску для портС:
Код: Выделить всё
switch(seg)
   {
      case 1: PORTC ^= 0b00100000;                                       
                 PORTB = 0b11110111;
      break;
      case 2: PORTC ^= 0b00100010;
                 PORTB = 0b11011100;
      break;                                                                   
      case 3: PORTC ^= 0b00100010;
                 PORTB = 0b11010101;
      break;
      case 4: PORTC ^= 0b00100100;
                 PORTB = 0b11010111;
      break;                                                       
      case 5: PORTC ^= 0b00000110;
                 PORTB = 0b11010101;
      break;
      case 6: PORTC ^= 0b00000110;
                 PORTB = 0b11010100;
      break;                                                                   
      case 7: PORTC ^= 0b00100010;
                 PORTB = 0b11110111;
      break;
      case 8: PORTC ^= 0b00100110;
                 PORTB = 0b11010100;
      break;                                                     
      case 9: PORTC ^= 0b00100110;
                 PORTB = 0b11010101;
      break;
      case 0: PORTC ^= 0b00100110;
                 PORTB = 0b11110101;
      break;
   }

но теперь не правильно загораются сегменты... :(
Denis_K
Частенько бываю
 
Сообщения: 73
Зарегистрирован: 16 июн 2017 13:48
Откуда: Краснодарский край

Re: Динамическая индикация

Сообщение IYra » 07 окт 2018 12:48

Denis_K писал(а):Почему-то вот здесь if(n_count==0) {PORTC|=(1<<PORTC0);PORTC&=~(1<<PORTC3);PORTC&=~(1<<PORTC4);segchar(ledprint(R1));} не тухнут РС3 и РС4... все три разряда постоянно включены.


Функция segchar() устанавливает все в 1
case 1: PORTC = 0b11011111; //1
PORTB = 0b11110111;
поэтому 0 нужно устанавливать побитово
PORTC&=~(1<<PORTC5);
IYra
Живу тут
 
Сообщения: 693
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Динамическая индикация

Сообщение Denis_K » 07 окт 2018 14:29

Спасибо, IYra. Я поздно до этого дошел :) ...
Сделал так:
Код: Выделить всё
switch(seg)
   {
      case 1: PORTC&=~(1<<PORTC5);                                       
              PORTB&=~(1<<PORTB3);
      break;
      case 2: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC5);
            PORTB&=~(1<<PORTB0);
            PORTB&=~(1<<PORTB1);
              PORTB&=~(1<<PORTB5);
      break;                                                                   
      case 3: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC5);
            PORTB&=~(1<<PORTB1);
            PORTB&=~(1<<PORTB3);
            PORTB&=~(1<<PORTB5);
      break;
      case 4: PORTC&=~(1<<PORTC2);
              PORTC&=~(1<<PORTC5);
              PORTB&=~(1<<PORTB3);
              PORTB&=~(1<<PORTB5);
      break;                                                       
      case 5: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC2);
              PORTB&=~(1<<PORTB1);
              PORTB&=~(1<<PORTB3);
              PORTB&=~(1<<PORTB5);
      break;
      case 6: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC2);
              PORTB&=~(1<<PORTB0);
              PORTB&=~(1<<PORTB1);
              PORTB&=~(1<<PORTB3);
            PORTB&=~(1<<PORTB5);
      break;                                                           
      case 7: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC5);
              PORTB&=~(1<<PORTB3);
      break;
      case 8: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC2);
              PORTC&=~(1<<PORTC5);
              PORTB&=~(1<<PORTB0);
              PORTB&=~(1<<PORTB1);
              PORTB&=~(1<<PORTB3);
              PORTB&=~(1<<PORTB5);
      break;                                                   
      case 9: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC2);
              PORTC&=~(1<<PORTC5);
              PORTB&=~(1<<PORTB1);
              PORTB&=~(1<<PORTB3);
              PORTB&=~(1<<PORTB5);
      break;
      case 0: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC2);
              PORTC&=~(1<<PORTC5);
              PORTB&=~(1<<PORTB0);
              PORTB&=~(1<<PORTB1);
              PORTB&=~(1<<PORTB3);
      break;
   }

Но теперь если в ledprint(111) или ledprint(555) и т.д., то индикация работает нормально, а если ledprint(123), то первую цифру выводит, а последующие - каша из сегментов...

Добавлено спустя 46 минут 32 секунды:
Файл .elf
Вложения
TOOmega48_2.rar
(3.93 КБ) Скачиваний: 2
Denis_K
Частенько бываю
 
Сообщения: 73
Зарегистрирован: 16 июн 2017 13:48
Откуда: Краснодарский край

Re: Динамическая индикация

Сообщение IYra » 07 окт 2018 16:12

Denis_K писал(а):Но теперь если в ledprint(111) или ledprint(555) и т.д., то индикация работает нормально, а если ledprint(123), то первую цифру выводит, а последующие - каша из сегментов...

Перед тем как устанавливать сегменты их нужно все очистить(то есть установить еденичку)
PORTC|=(1<<PORTC1);
PORTB|=(1<<PORTB3); и т.д.

И для отладки нужен main.c и .elf
IYra
Живу тут
 
Сообщения: 693
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Динамическая индикация

Сообщение Denis_K » 07 окт 2018 16:38

Добавлено спустя 5 минут 3 секунды:
Вот настройки портов:
Код: Выделить всё
DDRD = 0b00010000;
   DDRB = 0b111111;
   DDRC = 0b1111111;
   PORTD = 0b00100000;
   PORTC = 0b1111111;
   PORTB = 0b111111;

Вроде бы все соответствует... на разрядах не стал выставлять "0" из- за обратного напряжения на сегментах...
Вложения
TOO.rar
(4.75 КБ) Скачиваний: 2
Denis_K
Частенько бываю
 
Сообщения: 73
Зарегистрирован: 16 июн 2017 13:48
Откуда: Краснодарский край

Re: Динамическая индикация

Сообщение IYra » 07 окт 2018 17:28

IYra писал(а):
Denis_K писал(а):Но теперь если в ledprint(111) или ledprint(555) и т.д., то индикация работает нормально, а если ledprint(123), то первую цифру выводит, а последующие - каша из сегментов...

Перед тем как устанавливать сегменты их нужно все очистить(то есть установить еденичку)
PORTC|=(1<<PORTC1);
PORTB|=(1<<PORTB3); и т.д.

Не точно выразился. Каждый раз !!!
То есть в начале функции segchar() надо чистить все сегменты
PORTC|=(1<<PORTC1);
PORTB|=(1<<PORTB3); и т.д.
а уж потом рисовать новое.
Или для каждой цифры чистить только свое (так будет быстрее выполняться)
IYra
Живу тут
 
Сообщения: 693
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Динамическая индикация

Сообщение Denis_K » 07 окт 2018 18:22

IYra, спасибо! Получилось!
Написал так:
Код: Выделить всё
switch(seg)
   {
      case 1: PORTC&=~(1<<PORTC5);                                       
              PORTB&=~(1<<PORTB3);
         
            PORTC|=(1<<PORTC1);
            PORTC|=(1<<PORTC2);
            PORTB|=(1<<PORTB5);
            PORTB|=(1<<PORTB0);
            PORTB|=(1<<PORTB1);
            PORTB|=(1<<PORTB2);
            
            
      break;
      case 2: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC5);
            PORTB&=~(1<<PORTB0);
            PORTB&=~(1<<PORTB1);
              PORTB&=~(1<<PORTB5);
            
            PORTC|=(1<<PORTC2);
            PORTB|=(1<<PORTB3);
            
      break;                                                                   
      case 3: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC5);
            PORTB&=~(1<<PORTB1);
            PORTB&=~(1<<PORTB3);
            PORTB&=~(1<<PORTB5);
            
            PORTC|=(1<<PORTC2);
            PORTB|=(1<<PORTB0);
            
      break;
      case 4: PORTC&=~(1<<PORTC2);
              PORTC&=~(1<<PORTC5);
              PORTB&=~(1<<PORTB3);
              PORTB&=~(1<<PORTB5);
            
            PORTC|=(1<<PORTC1);
            PORTB|=(1<<PORTB0);
            PORTB|=(1<<PORTB1);
            
      break;                                                       
      case 5: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC2);
              PORTB&=~(1<<PORTB1);
              PORTB&=~(1<<PORTB3);
              PORTB&=~(1<<PORTB5);
            
            PORTC|=(1<<PORTC5);
            PORTB|=(1<<PORTB0);
            
      break;
      case 6: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC2);
              PORTB&=~(1<<PORTB0);
              PORTB&=~(1<<PORTB1);
              PORTB&=~(1<<PORTB3);
            PORTB&=~(1<<PORTB5);
            
            PORTC|=(1<<PORTC5);
            
      break;                                                           
      case 7: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC5);
              PORTB&=~(1<<PORTB3);
            
            PORTC|=(1<<PORTC2);
            PORTB|=(1<<PORTB5);
            PORTB|=(1<<PORTB2);
            PORTB|=(1<<PORTB0);
            PORTB|=(1<<PORTB1);
            
      break;
      case 8: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC2);
              PORTC&=~(1<<PORTC5);
              PORTB&=~(1<<PORTB0);
              PORTB&=~(1<<PORTB1);
              PORTB&=~(1<<PORTB3);
              PORTB&=~(1<<PORTB5);
            
      break;                                                   
      case 9: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC2);
              PORTC&=~(1<<PORTC5);
              PORTB&=~(1<<PORTB1);
              PORTB&=~(1<<PORTB3);
              PORTB&=~(1<<PORTB5);

            PORTB|=(1<<PORTB0);
            
      break;
      case 0: PORTC&=~(1<<PORTC1);
              PORTC&=~(1<<PORTC2);
              PORTC&=~(1<<PORTC5);
              PORTB&=~(1<<PORTB0);
              PORTB&=~(1<<PORTB1);
              PORTB&=~(1<<PORTB3);
            
            PORTB|=(1<<PORTB5);

      break;
   }
Denis_K
Частенько бываю
 
Сообщения: 73
Зарегистрирован: 16 июн 2017 13:48
Откуда: Краснодарский край


Вернуться в Разное



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

cron