Например TDA7294

Форум РадиоКот • Просмотр темы - ATmega8, динамическая индикация, switch case и десятичная то
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Вс июл 27, 2025 14:25:12

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 97 ]  1, , , ,  
Автор Сообщение
Не в сети
 Заголовок сообщения: ATmega8, динамическая индикация, switch case и десятичная то
СообщениеДобавлено: Сб сен 28, 2024 16:49:42 
Родился

Зарегистрирован: Сб сен 28, 2024 16:19:04
Сообщений: 12
Рейтинг сообщения: 0
Доброго всем времени суток.
Начал недавно изучать программирование AVR на Си. Поднакопил немного знаний и решил сделать свое первое устройство, нагрузку для разряда АКБ.
Набросал в протеусе вот такую схемку
[img][url=https://img.radiokot.ru/files/158040/medium/3kcp23hfco.jpg][/img]
Написал в AtmelStudio вот такой код
Спойлер
Код:
#define F_CPU 8000000UL //частота МК
#include <avr/io.h>
#include <util/delay.h> //библиотека задержек
#include <avr/interrupt.h> //библиотека прерываний

//---------- динамической индикации------------------------------
unsigned char n = 0; //переменная количества вхождений в прерывание
unsigned char r1_1000 = 0; //переменная значения разряда тысяч
unsigned char r2_100 = 0; //переменная значения разряда сотен
unsigned char r3_10 = 0; //переменная значения разряда десятков
unsigned char r4_1 = 0; //переменная значения разряда единиц
//----------

//---------- времени---------------------------------------------
unsigned char sec = 0; //переменная количества секунд
unsigned char min = 0; //переменная количества минут
unsigned char hour = 0; //переменная количества часов
//----------

//---------- кнопок (внешние прерывания)----------
unsigned char button_1 = 0; //переменная количества секунд
unsigned char button_2 = 0; //переменная количества минут
//----------

unsigned int temp = 0; //переменная хранения значения температуры
float volt = 0; //переменная хранения значения напряжения АКБ
unsigned char n_ADC = 0; //переменная количества преобразований АЦП

//---------- индикация и отображение информации----------------
void LED_DISP_pin_setup(void) //функция настройки пинов LED индикатора
{
   //настройка сегментов A, B, Dp, C, G
   DDRB |= (1<<4) | (1<<3) | (1<<2) | (1<<1) | (1<<0); //режим работы - выход
   PORTB &= ~((1<<4) | (1<<3) | (1<<2) | (1<<1) | (1<<0)); //низкий потенциал на пинах
   //настройка сегментов E, D, F
   DDRD |= (1<<7) | (1<<6) | (1<<5); //режим работы - выход
   PORTD &= ~((1<<7) | (1<<6) | (1<<5)); //низкий потенциал на пинах
   //настройка разрядов 1-4
   DDRC |= (1<<3) | (1<<2) | (1<<1) | (1<<0); //режим работы - выход
   PORTC |= (1<<3) | (1<<2) | (1<<1) | (1<<0); //высокий потенциал на пинах
}

void Timer0_setup(void) //функция настройки нулевого таймер-счетчика
{
   //включение таймер-счетчика с делителем на 64
   TCCR0 |= (1<<CS01) | (1<<CS00);
   TCCR0 &= ~(1<<CS02);
   //настройка прерывания по переполнению счетого регистра
   TIMSK |= (1<<TOIE0);
   //обнуление счетного регистра
   TCNT0 = 0;
}

void show_volt(unsigned int znach_volt)
{
   r1_1000 = znach_volt / 1000; //определение значения десятков вольт
   r2_100 = znach_volt % 1000 / 100; //определение значения единиц вольт
   r3_10 = znach_volt % 100 / 10; //определение значения десятоых долей вольта
   r4_1 = 12; //знак напряжения
}

void show_temp(unsigned int znach_temp)
{
   r1_1000 = znach_temp / 10; //
   r2_100 = znach_temp % 10; //
   r3_10 = 10;
   r4_1 = 11;
}

void show_min_sec(unsigned int znach_min, unsigned char znach_sec)
{
   r1_1000 = znach_min / 10; //определение значения десятков минут
   r2_100 = znach_min % 10; //определение значения единиц минут
   r3_10 = znach_sec / 10; //определение значения десятков секунд
   r4_1 = znach_sec % 10; //определение значения единиц секунд
}

void show_hour_min(unsigned int znach_hour, unsigned char znach_min)
{
   r1_1000 = znach_hour / 10; //определение значения десятков часов
   r2_100 = znach_hour % 10; //определение значения единиц часов
   r3_10 = znach_min / 10; //определение значения десятков минут
   r4_1 = znach_min % 10; //определение значения единиц минут
}

void digits(unsigned char n) //функция отображения цифр
{
   //выключаем сегменты
   PORTB &= ~((1<<4) | (1<<3) | (1<<2) | (1<<1) | (1<<0)); //низкий потенциал на пинах
   PORTD &= ~((1<<7) | (1<<6) | (1<<5)); //низкий потенциал на пинах
   switch(n)
   {
      case 0: PORTB |= (1<<3) | (1<<1) | (1<<0);
            PORTD |= (1<<7) | (1<<6) | (1<<5);
            break;
      case 1: PORTB |= (1<<3) | (1<<1);
            break;
      case 2: PORTB |= (1<<4) | (1<<1) | (1<<0);
            PORTD |= (1<<6) | (1<<5);
            break;
      case 3: PORTB |= (1<<4) | (1<<3) | (1<<1) | (1<<0);
            PORTD |= (1<<6);
            break;
      case 4: PORTB |= (1<<4) | (1<<3) | (1<<1);
            PORTD |= (1<<7);
            break;
      case 5: PORTB |= (1<<4) | (1<<3) | (1<<0);
            PORTD |= (1<<7) | (1<<6);
            break;
      case 6: PORTB |= (1<<4) | (1<<3) | (1<<0);
            PORTD |= (1<<7) | (1<<6) | (1<<5);
            break;
      case 7: PORTB |= (1<<3) | (1<<1) | (1<<0);
            break;
      case 8: PORTB |= (1<<4) | (1<<3) | (1<<1) | (1<<0);
            PORTD |= (1<<7) | (1<<6) | (1<<5);
            break;
      case 9: PORTB |= (1<<4) | (1<<3) | (1<<1) | (1<<0);
            PORTD |= (1<<7) | (1<<6);
            break;
      case 10: PORTB |= (1<<4) | (1<<1) | (1<<0); //знак градуса
             PORTD |= (1<<7);
             break;
      case 11: PORTB |= (1<<0);               //знак цельсия
             PORTD |= (1<<7) | (1<<6) | (1<<5);
             break;
      case 12: PORTB |= (1<<3) | (1<<1);         //знак напряжения
             PORTD |= (1<<7) | (1<<6) | (1<<5);
             break;
   }
}

ISR(TIMER0_OVF_vect) //макрос обработки прерывания нулевого таймер-счтечика
{
   if(++n > 4) n = 1;
   if (n == 1) //отображение в первом разряде
   {
      PORTC |= (1<<3) | (1<<2) | (1<<1);
      PORTC &= ~(1<<0);
      digits(r1_1000);
   }
   else if (n == 2) //отображение во втором разряде
   {
      PORTC |= (1<<3) | (1<<2) | (1<<0);
      PORTC &= ~(1<<1);
      digits(r2_100);
   }
   else if (n == 3) //отображение в третьем разряде
   {
      PORTC |= (1<<3) | (1<<1) | (1<<0);
      PORTC &= ~(1<<2);
      digits(r3_10);
   }
   else if (n == 4) //отображение в четвертом разряде
   {
      PORTC |= (1<<2) | (1<<1) | (1<<0);
      PORTC &= ~(1<<3);
      digits(r4_1);
   }
}
//----------

//---------- одной секунды--------------------------------------------------
void Timer1_setup(void)
{
   //включение таймер-счетчика с делителем на 256
   TCCR1B |= (1<<CS12);
   TCCR1B &= ~((1<<CS11) | (1<<CS10));
   //разрешаем прерывание по совпадению
   TIMSK |= (1<<OCIE1A);
   //разрешаем автоматическое обнуление счетного регистра при совпадении
   TCCR1B |= (1<<WGM12);
   //обнуляем счетный регистр
   TCNT1 = 0;
   //записываем в счетный регистр значение кличества тактов равное одной секунде
   OCR1A = 31250;
}

ISR(TIMER1_COMPA_vect)
{
   sec++;
   if (sec == 60)
   {
      sec = 0;
      min++;
   }
   else if (min == 60)
   {
      min = 0;
      hour++;
   }
}
//----------

//---------- прерывания----------------------------------------------------
void External_interrupts_pin_setup(void)
{
   DDRD &= ~((1<<3) | (1<<2));
   PORTD |= (1<<3) | (1<<2);
}

void External_interrupts_setup(void)
{
   //настройка прерывания INT0 по спаду
   MCUCR |= (1<<ISC01);
   MCUCR &= ~(1<<ISC00);
   //настройка прерывания INT1 по спаду
   MCUCR |= (1<<ISC11);
   MCUCR &= ~(1<<ISC10);
   //разрешаем внешние прерывания INT0 и INT1
   GICR |= (1<<INT1) | (1<<INT0);
}

ISR(INT0_vect) //макрос обработки прерывания, изменение отображаемой информации
{
   if (++button_1 > 3) button_1 = 1;
}

ISR(INT1_vect)
{
   
}
//----------

//----------
void ADC_pin_setup(void)
{
   DDRC &= ~((1<<5) | (1<<4)); //пин PD4 и PD5 в режим работы вход
   PORTC &= ~((1<<5) | (1<<4)); //высокое входное сопротивление на пинах PD4 и PD5
}

void ADC_setup()
{
   //разрешаем работу АЦП
   ADCSRA |= (1<<ADEN);
   //непрерывный режим работы АЦП
   ADCSRA |= (1<<ADFR);
   //частота дискретизации 125 кГц (частота МК 8 МГЦ, делитель 64)
   ADCSRA |= (1<<ADPS2) | (1<<ADPS1);
   ADCSRA &= ~(1<<ADPS0);
   //подключаем внешний ИОН - 5В
   //ADMUX |= (1<<REFS0);
   //ADMUX &= ~(1<<REFS1);
   //подключаем внутренний ИОН - 2,56В
   ADMUX |= (1<<REFS1) | (1<<REFS0);
   //выравнивание результата преобразования в регистре ADC по правой стороне
   ADMUX &= ~(1<<ADLAR);
   //настраиваем 5-й канал АЦП
   ADMUX |= (1<<MUX2) | (1<<MUX0);
   ADMUX &= ~((1<<MUX3) | (1<<MUX1));
   //разрешаем преобразование АЦП
   ADCSRA |= (1<<ADSC);
   //разрешаем прерывание от АЦП
   ADCSRA |= (1<<ADIE);
}

void ADC_set_chanel(unsigned char chanel) //функция выбора канала АЦП
{
   switch(chanel)
   {
      case 0: //4-й канал
            ADMUX |= (1<<MUX2);
            ADMUX &= ~((MUX3) | (MUX1) | (MUX0));
            break;
      case 1: //5-й канал
            ADMUX |= (1<<MUX2) | (1<<MUX0);
            ADMUX &= ~((1<<MUX3) | (1<<MUX1));
   }
}

ISR(ADC_vect)
{
    n_ADC++; //этотвариант работает
    if (n_ADC == 1)
    {
       temp = (ADC*2.56/1024)*100;
    }
    else if (n_ADC == 2)
    {
       volt = (ADC*2.56/1024.0*5.3)*100;
       n_ADC = 0;
    }
    ADC_set_chanel(n_ADC);
}
//----------

int main(void)
{
    LED_DISP_pin_setup();
   Timer0_setup();
   Timer1_setup();
   External_interrupts_pin_setup();
   External_interrupts_setup();
   ADC_pin_setup();
   ADC_setup();
   
   sei(); //глобальное разрешение прерываний
    while (1)
    {
      if (button_1 == 1)
      {
         show_min_sec(min, sec);
      }
      else if (button_1 == 2)
      {
         show_temp(temp);
      }
      else if (button_1 == 3)
      {
         show_volt(volt);
      }
    }
}

После включения, при нажатии на кнопку (подключена к пину PD2) изменяется отображаемая информация на семисегментном индикаторе. Поле первого нажатия отображается время прошедшее с момента включения, после второго - температура, после третьего - напряжение на АКБ.
И вот тут возник вопрос. А как включить десятичную точку во втором разряде при отображении напряжения?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 18:18:52 
Модератор
Аватар пользователя

Карма: 153
Рейтинг сообщений: 2917
Зарегистрирован: Сб авг 14, 2010 15:05:51
Сообщений: 18741
Откуда: г. Озерск, Челябинская обл.
Рейтинг сообщения: 0
Медали: 1
Лучший человек Форума 2017 (1)
так добавь точку к цифре по ИЛИ.

_________________
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 20:37:58 
Прорезались зубы
Аватар пользователя

Зарегистрирован: Чт фев 28, 2013 14:16:10
Сообщений: 222
Рейтинг сообщения: 0
Очень у вас хорошо читаемый код получился. Хотя могут, конечно, набежать и сказать, что не по феншую, и какие-то непонятные константы в тексте тут и там)

По мне так лучше держать сразу отображаемый код в переменных, а не цифру от 0 до 9. Хоть у вас и в двух разных регистрах сегменты, но все равно по номерам битов от 0 до 7 - простой char получается. Лучше переделать иначе с точкой будет слишком кучеряво.

Я последний раз точку делал так:

Код:
char get_code(char c, char pt)
{
   if(pt) pt=0b10000000;   // добавить точку
   switch(c)
   {
      case 0: return 0b00111111 | pt;


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 20:53:04 
Друг Кота

Карма: 68
Рейтинг сообщений: 1961
Зарегистрирован: Сб дек 18, 2021 19:25:32
Сообщений: 12867
Рейтинг сообщения: 0
Если занести всё в массив, то вместо кучи хорошо читаемых строчек
switch(c)
{
case 0...

была бы одна плохо читаемая PORTB |= MyArray[c];


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 21:57:03 
Мучитель микросхем
Аватар пользователя

Карма: 1
Рейтинг сообщений: 38
Зарегистрирован: Ср янв 11, 2012 18:20:26
Сообщений: 473
Рейтинг сообщения: -3
народ до сих пор динамикой занимается..
есть копеечные готовые модули типа MAX7219, TM1637 и др..


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 21:59:01 
Потрогал лапой паяльник

Карма: -15
Рейтинг сообщений: -26
Зарегистрирован: Пн июн 03, 2024 22:29:24
Сообщений: 314
Рейтинг сообщения: 0
MAX7219-это круто , это просто ! TM1637 это какое то дерьмище вообще не получилось ничего ...


Последний раз редактировалось Thinnnfor Сб сен 28, 2024 22:03:18, всего редактировалось 1 раз.

Вернуться наверх
 
Распродажа паяльного оборудования ATTEN!
Паяльные станции, паяльники и аксессуары по самой выгодной цене.

По промокоду radiokot скидка 10%
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 22:03:03 
Мучитель микросхем
Аватар пользователя

Карма: 1
Рейтинг сообщений: 38
Зарегистрирован: Ср янв 11, 2012 18:20:26
Сообщений: 473
Рейтинг сообщения: 0
Thinnnfor писал(а):
TM1637 это какое то дерьмище вообще не поличилось ничего ...

если не получилось - не значит, что дермище))
вручную интерфейс мутить нужно


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 22:04:07 
Друг Кота

Карма: 68
Рейтинг сообщений: 1961
Зарегистрирован: Сб дек 18, 2021 19:25:32
Сообщений: 12867
Рейтинг сообщения: 2
а не поличилось, патамучто "GyverTM1637 — бибилотека для 7 сегментного дисплея на чипе TM1637 с кучей приколюх" (орфография сохранена)
и пака одна дурака макака совитует хирню, дргая дурака макака не мажит то же думот. да здраствуят адурина! с кучей приколюх


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 22:15:38 
Потрогал лапой паяльник

Карма: -15
Рейтинг сообщений: -26
Зарегистрирован: Пн июн 03, 2024 22:29:24
Сообщений: 314
Рейтинг сообщения: 0
Я не пользуюсь библиотеками , тем более ардуино ! Ардуино не пользуюсь из принципа ! У меня CV AVR !

Добавлено after 5 minutes 3 seconds:
Re: ATmega8, динамическая индикация, switch case и десятичная то
CV AVR для авр, для микрочипов PIC CCS


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 22:16:17 
Мучитель микросхем
Аватар пользователя

Карма: 1
Рейтинг сообщений: 38
Зарегистрирован: Ср янв 11, 2012 18:20:26
Сообщений: 473
Рейтинг сообщения: 0
Martian, ты увенный и сам себе веришь)
если что я асме пишу)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 22:17:09 
Друг Кота

Карма: 68
Рейтинг сообщений: 1961
Зарегистрирован: Сб дек 18, 2021 19:25:32
Сообщений: 12867
Рейтинг сообщения: 0
У-ух! (почесал себе зад)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 22:29:07 
Сверлит текстолит когтями

Карма: 12
Рейтинг сообщений: 124
Зарегистрирован: Вт июн 07, 2011 08:03:18
Сообщений: 1214
Рейтинг сообщения: 0
Не перевелись ведь люди в русских селеньях!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 22:29:52 
Потрогал лапой паяльник

Карма: -15
Рейтинг сообщений: -26
Зарегистрирован: Пн июн 03, 2024 22:29:24
Сообщений: 314
Рейтинг сообщения: 0
shonty писал(а):
если что я асме пишу)

Ну ....респект и уважуха !!!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 22:32:47 
Сверлит текстолит когтями

Карма: 12
Рейтинг сообщений: 124
Зарегистрирован: Вт июн 07, 2011 08:03:18
Сообщений: 1214
Рейтинг сообщения: 0
Дурак дураком. Соболезную.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 22:39:59 
Потрогал лапой паяльник

Карма: -15
Рейтинг сообщений: -26
Зарегистрирован: Пн июн 03, 2024 22:29:24
Сообщений: 314
Рейтинг сообщения: 0
Ассемблер - это круто !

Добавлено after 56 seconds:
Re: ATmega8, динамическая индикация, switch case и десятичная то
Когда то под z80 тоже писал , давно это было !


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 23:01:04 
Мучитель микросхем
Аватар пользователя

Карма: 1
Рейтинг сообщений: 38
Зарегистрирован: Ср янв 11, 2012 18:20:26
Сообщений: 473
Рейтинг сообщения: 0
Martian писал(а):
У-ух! (почесал себе зад)
OKF писал(а):
Дурак дураком. Соболезную.
а что вы такие все взволнованные? :shock: :) :)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Сб сен 28, 2024 23:38:33 
Потрогал лапой паяльник

Карма: -15
Рейтинг сообщений: -26
Зарегистрирован: Пн июн 03, 2024 22:29:24
Сообщений: 314
Рейтинг сообщения: 0
Всё норм ! динамическая индикация , индицирует динамически ! Всё хорошо !!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Вс сен 29, 2024 06:46:43 
Нашел транзистор. Понюхал.

Карма: 4
Рейтинг сообщений: 20
Зарегистрирован: Чт сен 19, 2024 19:18:28
Сообщений: 159
Рейтинг сообщения: 0
Вообще, это обычный путь начинающего - одиночные светодиоды, семисегментный индикатор в один разряд, и наконец - динамическая индикация на семисегментниках. Всё по классике, это же изучение. Затем должен быть двустрочный знакосинтезирующий ЖК-дисплей, желательно не на I2C, а на параллельной шине.
А вот ассемблер нынче не нужен. Его можно знать, но писать на нем - смысла нет никакого.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Вс сен 29, 2024 07:20:30 
Мучитель микросхем
Аватар пользователя

Карма: 1
Рейтинг сообщений: 38
Зарегистрирован: Ср янв 11, 2012 18:20:26
Сообщений: 473
Рейтинг сообщения: 0
Базилюк писал(а):
А вот ассемблер нынче не нужен. Его можно знать, но писать на нем - смысла нет никакого.
То, что я пишу на асме, я бы и не стал здесь упоминать, это не тема данного обсуждения.
Сказал лишь для того, что бы развеять "уверенность" мартиана что все сидят на ардуине и на библиотеках:
Martian писал(а):
а не поличилось, патамучто "GyverTM1637 — бибилотека для 7 сегментного дисплея на чипе TM1637 с кучей приколюх" (орфография сохранена)
и пака одна дурака макака совитует хирню, дргая дурака макака не мажит то же думот. да здраствуят адурина! с кучей приколюх
к чему эта реплика вообще? :shock:

По поводу есть смысл или нет, то это обычный холивар на тему асм/яву, гимп/фотошоп, линукс/виндовс...
А писАть я могу хоть на тетрадке в клеточку, главное результат.

:beer:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATmega8, динамическая индикация, switch case и десятична
СообщениеДобавлено: Вс сен 29, 2024 08:26:45 
Нашел транзистор. Понюхал.

Карма: 4
Рейтинг сообщений: 20
Зарегистрирован: Чт сен 19, 2024 19:18:28
Сообщений: 159
Рейтинг сообщения: 0
Ардуина существует уже больше 15 лет, поэтому немудрено, что многие её используют. Я вот например использую готовые платы от WeAct, китайцы научились ставить на них мощные МК.


По поводу затронутой темы с дин.идникацией. Я тоже в своих первых опытах писал нечто подобное :) Однако, затем переделал на таблицу. То есть, список зажигаемых сегментов можно представить в виде таблицы - индексированный одномерный массив на 10 элементов.
То есть, примерно так:
Код:
/* Распиновка сегментов на одном порту (можно в любом порядке пинов) */
#define SEGA   (1 << 0)
#define SEGB   (1 << 1)
#define SEGC   (1 << 2)
#define SEGD   (1 << 3)
#define SEGE   (1 << 4)
#define SEGF   (1 << 5)
#define SEGG   (1 << 6)
#define SEGp   (1 << 7)

/* Сборка сегментов в символ семисегментника */
#define CH0      (SEGA | SEGB | SEGC | SEGD | SEGE | SEGF | SEGG)
#define CH1      (SEGA | SEGB                                   )
#define CH2      (SEGA | SEGB |        SEGD | SEGE |        SEGG)
#define CH3      (SEGA | SEGB | SEGC | SEGD |               SEGG)
#define CH4      (       SEGB | SEGC |               SEGF | SEGG)
#define CH5      (SEGA |        SEGC | SEGD |        SEGF | SEGG)
#define CH6      (SEGA |        SEGC | SEGD | SEGE | SEGF | SEGG)
#define CH7      (SEGA | SEGB | SEGC                            )
#define CH8      (SEGA | SEGB | SEGC | SEGD | SEGE | SEGF | SEGG)
#define CH9      (SEGA | SEGB | SEGC | SEGD |        SEGF | SEGG)
#define SEG_OFF   0

/* Распиновка разрядов (можно в любом порядке пинов) */
#define D0      (1 << 0)
#define D1      (1 << 1)
#define D2      (1 << 2)
#define D3      (1 << 3)

#define ALLDIGIT_OFF   GPIOB = D0 | D1 | D2 | D3

/**
 * Получение списка включаемых пинов для сегментов символа
 * @param ch - отображаемая цифра (0 - 9)
 * @return Значение для записи в выходной порт
 */

uint8_t GetSegments(uint8_t ch)
{
   const uint8_t digits[10] = {CH0, CH1, CH2, CH3, CH4, CH5, CH6, CH7, CH8, CH9};
   return digits[ch];
}

/**
 * Фаза дин.индикации. Отображение цифры в указанном разряде
 * @param digit - номер разряда индикатора
 * @param ch - отображаемая цифра
 * @param dot - признак десятичной точки
 */

void Phase(uint8_t digit, uint8_t ch, bool dot)
{
   ALLDIGIT_OFF; // выключение всех разрядов
   GPIOA = GetSegments(ch);    // выходы сегментов
   
   /* добавление в порт десятичной точки */
   if(dot)
      GPIOA |= SEGp;

   /* Выбор разряда */
   switch(digit) {
   case 0:
      GPIOB &= ~D0;   // включение разряда 0
      break;
   case 1:
      GPIOB &= ~D1;   // включение разряда 1
      break;
   case 2:
      GPIOB &= ~D2;   // включение разряда 2
      break;
   case 3:
      GPIOB &= ~D3;   // включение разряда 3
      break;
   }
}

(GPIOA и GPIOB написаны условно)
И затем функцию Phase() вызывать через заданные промежутки времени в соответствии с порядком индикации (можно даже и в любом порядке разрядов). В функцию передаем номер выбираемого разряда, отображаемую цифру и признак включения десятичной точки в разряде.
Да, в эту функцию можно еще добавить параметр - признак гашения цифры, и по этому признаку гасить все сегменты в разряде, то есть, не отображать его.


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 97 ]  1, , , ,  

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

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


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y