Например TDA7294

Форум РадиоКот • Просмотр темы - Как оптимизировать разбитие 16бит-числа на составляющие ?
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Ср апр 24, 2024 15:47:52

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


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



Начать новую тему Ответить на тему  [ Сообщений: 14 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Как оптимизировать разбитие 16бит-числа на составляющие ?
СообщениеДобавлено: Пт май 25, 2018 04:27:34 
Потрогал лапой паяльник
Аватар пользователя

Карма: 3
Рейтинг сообщений: 3
Зарегистрирован: Ср май 03, 2017 03:22:26
Сообщений: 303
Рейтинг сообщения: 0
Есть функция
Код:
PrintNumber(uint16_t NeberChar,uint8_t NumberTimers)

функция принимает число NeberChar (которое может быть от 0 до 60 000), это число надо вывести на индикатор.
Функция справляется на ура конечно со своим делом, но
почему то мне кажется что деление в лоб не лучшая идея по скорости выполнения.
Код:
data1=NeberChar%10;
data2=(NeberChar%100)/10;
data3=(NeberChar%1000)/100;
data4=(NeberChar%10000)/1000;
data5=(NeberChar/10000);


Мб есть у кого какие идеи ?

//Функция вывода динамической индикации.
Код:
void PrintNumber(uint16_t NeberChar,uint8_t NumberTimers)
{
   /***Разбитие числа на разряды***/
   /*data1->младший,data5->Старший,data6 отдельный разряд*/
   data1=NeberChar%10;
   data2=(NeberChar%100)/10;
   data3=(NeberChar%1000)/100;
   data4=(NeberChar%10000)/1000;
   data5=(NeberChar/10000);
   data6=NumberTimers; //1..4
   AnodCount++;
   switch (AnodCount)
   {
   case 1:
   ANOD1=0;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
   PrintChar(data1);
      break;
   case 2:
   if (((data2+data3+data4+data5)!=0)|| (ModTimer == 0)) //если сумма старших раааазрядов !=0 то выводим разряд иначе гасим.
   {
      ANOD1=1;ANOD2=0;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
      PrintChar(data2);
   } else PrintChar(99); //гасим разряд.
      break;
   case 3:
   if (((data3+data4+data5)!=0)|| (ModTimer == 0)) //если сумма старших раааазрядов !=0 то выводим разряд иначе гасим.
   {
      ANOD1=1;ANOD2=1;ANOD3=0;ANOD4=1;ANOD5=1;ANOD6=1;
      PrintChar(data3);
   } else PrintChar(99); //гасим разряд.
      break;
   case 4:
   if ((data4+data5)!=0) //если сумма старших раааазрядов !=0 то выводим разряд иначе гасим.
   {
      ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=0;ANOD5=1;ANOD6=1;
      PrintChar(data4);
   } else PrintChar(99); //гасим разряд.
      break;
   case 5:
   if (data5!=0) //если сумма старших раааазрядов !=0 то выводим разряд иначе гасим.
   {
      ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=0;ANOD6=1;
      PrintChar(data5);
   } else PrintChar(99); //гасим разряд.
      break;
   case 6:
   if (data6!=0) //если сумма раааазряда !=0 то выводим разряд иначе гасим.
   {
      ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=0;
      PrintChar(data6);
   } else PrintChar(99); //гасим разряд.
   AnodCount=0;
      break;
   }
}

_________________
andrei23061996@gmail.com
.................................................................................................................


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
СообщениеДобавлено: Пт май 25, 2018 06:26:51 
Собутыльник Кота
Аватар пользователя

Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2694
Откуда: г. Чайковский
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Возможно будет иметь смысл применить двоично десятичный формат числа. Тогда для динамической индикации ничего преобразовывать не надо будет.

_________________
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
СообщениеДобавлено: Пт май 25, 2018 07:20:53 
Потрогал лапой паяльник
Аватар пользователя

Карма: 3
Рейтинг сообщений: 3
Зарегистрирован: Ср май 03, 2017 03:22:26
Сообщений: 303
Рейтинг сообщения: 0
Z_h_e, Если можно привести пример буду благодарен ).
сейчас индикация выводиться через 595 регистр по spi
Код:
/Функция вывода символов
static void PrintChar (uint8_t Number)
{
   switch (Number)
   {
      case 0:
      SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
      case 1:
      SEG_PORT=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
      case 2:
      SEG_PORT=(0<<SEGA)|(0<<SEGB)|(1<<SEGC)|(0<<SEGD)|(0<<SEGE)|(1<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
      case 3:
      SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(1<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
      case 4:
      SEG_PORT=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
      case 5:
      SEG_PORT=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
      case 6:
      SEG_PORT=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
      case 7:
      SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
      case 8:
      SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
      case 9:
      SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
      case 99: //OFF Все сегменты
      SEG_PORT=(1<<SEGA)|(1<<SEGB)|(1<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
   }
   if ((ModTimer == 0)&&(AnodCount == 3))
   {

      SEG_PORT &=~(1<<SEGH);
   }
}
//Функция вывода динамической индикации.
void PrintNumber(uint16_t NeberChar,uint8_t NumberTimers)
{
   /***Разбитие числа на разряды***/
   /*data1->младший,data5->Старший,data6 отдельный разряд*/
   uint8_t data1=NeberChar%10;
   uint8_t data2=(NeberChar%100)/10;
   uint8_t data3=(NeberChar%1000)/100;
   uint8_t data4=(NeberChar%10000)/1000;
   uint8_t data5=(NeberChar/10000);
   uint8_t data6=NumberTimers; //1..4
   AnodCount++;
   switch (AnodCount)
   {
   case 1:
   ANOD1=0;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
   PrintChar(data1);
      break;
   case 2:
   if (((data2+data3+data4+data5)!=0)|| (ModTimer == 0)) //если сумма старших раааазрядов !=0 то выводим разряд иначе гасим.
   {
      ANOD1=1;ANOD2=0;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
      PrintChar(data2);
   } else PrintChar(99); //гасим разряд.
      break;
   case 3:
   if (((data3+data4+data5)!=0)|| (ModTimer == 0)) //если сумма старших раааазрядов !=0 то выводим разряд иначе гасим.
   {
      ANOD1=1;ANOD2=1;ANOD3=0;ANOD4=1;ANOD5=1;ANOD6=1;
      PrintChar(data3);
   } else PrintChar(99); //гасим разряд.
      break;
   case 4:
   if ((data4+data5)!=0) //если сумма старших раааазрядов !=0 то выводим разряд иначе гасим.
   {
      ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=0;ANOD5=1;ANOD6=1;
      PrintChar(data4);
   } else PrintChar(99); //гасим разряд.
      break;
   case 5:
   if (data5!=0) //если сумма старших раааазрядов !=0 то выводим разряд иначе гасим.
   {
      ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=0;ANOD6=1;
      PrintChar(data5);
   } else PrintChar(99); //гасим разряд.
      break;
   case 6:
   if (data6!=0) //если сумма раааазряда !=0 то выводим разряд иначе гасим.
   {
      ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=0;
      PrintChar(data6);
   } else PrintChar(99); //гасим разряд.
   AnodCount=0;
      break;
   }
}

_________________
andrei23061996@gmail.com
.................................................................................................................


Последний раз редактировалось 7seg Пт май 25, 2018 07:37:52, всего редактировалось 1 раз.

Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
СообщениеДобавлено: Пт май 25, 2018 07:34:06 
Друг Кота
Аватар пользователя

Карма: 32
Рейтинг сообщений: 234
Зарегистрирован: Пт янв 29, 2010 10:27:40
Сообщений: 3851
Откуда: Москва
Рейтинг сообщения: 0
Можно по очереди отнимать от NeberChar сначала по 10 000, и количество возможных вычитаний (т.е. пока результат остается>0) записать в data1, потом начать отнимать по 1000, результат соответственно в data2, потом соответственно 100 и 10, остаток сохраняется в data5. Я так всегда вывожу результат. В худшем случае получите чуть более 200 тактов на все вычисление (максимум вычитаний для числа типа "59999"), в лучшем около 40 (если "0"). Думаю это немного быстрее чем "4 остатка от деления+4 обычных деления" 16-разрядного числа.
Спойлер
Код:
//код на асме для общего пониманию принципа, си не люблю
HEXTODEC10000:
//YH:YL - число для преобразования
//data1-data5 - результат
       .def data1=R16
       .def data2=R17
       .def data3=R18
       .def data4=R19
       .def data5=R10

   CLR   data1 //очищаем результат
   CLR   data2
   CLR   data3
   CLR   data4
   LDW   ZH,ZL,10000 //грузим константу для вычитания 10 000
S10000:   SUB   YL,ZL //вычитаем
   SBC   YH,ZH
   BRCS   X1000 //проверяем остаток (>0 - прокатило)
   INC   data1 //прокатило, увеличиваем десятки тысяч
   RJMP   S10000 //продолжаем вычитать
X1000:   ADD   YL,ZL //непрокатило, возвращаем 10 000
   ADC   YH,ZH
   LDW   ZH,ZL,1000 //переходим на тысячи
S1000:   SUB   YL,ZL
   SBC   YH,ZH
   BRCS   X100
   INC   data2
   RJMP   S1000
X100:   ADD   YL,ZL
   ADC   YH,ZH
   LDW   ZH,ZL,100 //теперь сотни
S100:   SUB   YL,ZL
   SBC   YH,ZH
   BRCS   X10
   INC   data3
   RJMP   S100
X10:   ADD   YL,ZL
   ADC   YH,ZH
S10:   SUBI   YL,10 //десятки
   BRCS   X1
   INC   data4
   RJMP   S10
X1:   SUBI   YL,-10
   MOV   data5,YL //остаток копируем напрямую
   RET

_________________
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)


Последний раз редактировалось Engineer_Keen Пт май 25, 2018 07:42:18, всего редактировалось 1 раз.

Вернуться наверх
 
Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
СообщениеДобавлено: Пт май 25, 2018 07:42:02 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
ваш код, 7seg, - лютый трэш.
вы хоть почитайте о том, как организуется преобразование чисел в символьное представление, как организуется динамическая (и не динамическая) индикация на 7-сегментниках... как вообще пишутся программы - про циклы, например, дефайны и т.п.
вопрос у вас настолько примитивный, что просто удивительно, как вы его еще задать смогли - я даже про гугление не говорю, здесь, на радиокоте статей и сообщений на форуме - просто жри не лопни!
ну как же вы так-то, а?

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
СообщениеДобавлено: Пт май 25, 2018 08:24:20 
Потрогал лапой паяльник
Аватар пользователя

Карма: 3
Рейтинг сообщений: 3
Зарегистрирован: Ср май 03, 2017 03:22:26
Сообщений: 303
Рейтинг сообщения: 0
ARV, естественно все задефайнено.
Дефайны и листинг под спойлером.

Спойлер
Код:
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
/*_________________BEGIN_TARGET_DEFINE_____________________*/
#define ENABLE_TIM1      TIMSK|= (1<<2)
#define DISABLE_TIM1   TIMSK&= ~(1<<2)

#define ENABLE_SM   PORTC|= (1<<1)
#define DISABLE_SM   PORTC&= ~(1<<1)
#define ENABLE_SB   PORTC|= (1<<2)
#define DISABLE_SB   PORTC&= ~(1<<2)
#define ENABLE_PW   PORTC|= (1<<3)
#define DISABLE_PW   PORTC&= ~(1<<3)
#define ENABLE_OW   PORTC|= (1<<4)
#define DISABLE_OW   PORTC&= ~(1<<4)

/******************Описание DEFINE SPI**********************/
#define SPI_PORT PORTB
#define SPI_DDR DDRB
#define SPI_MISO 6
#define SPI_MOSI 5
#define SPI_SCK 7
#define SPI_SS 4
/*********Кодировка семи сегментного индикатора.*************/
//_____*/
#define SEG_PORT  TwoOUT.ByteRegister 
//__________________Катоды___________________________________*/
#define SEGA 0
#define SEGB 1
#define SEGC 2
#define SEGD 3
#define SEGE 4
#define SEGF 5
#define SEGG 6
#define SEGH 7
//__________________Аноды____________________________________*/
#define ANOD1  OneOUT.Register.DO0
#define ANOD2  OneOUT.Register.DO1
#define ANOD3  OneOUT.Register.DO2
#define ANOD4  OneOUT.Register.DO3
#define ANOD5  OneOUT.Register.DO4
#define ANOD6  OneOUT.Register.DO5
#define DISPLAY_MOD_TIM  OneOUT.Register.DO6
#define DISPLAY_MOD_JOB  OneOUT.Register.DO7
/*****************SETING_DEFINE_BTN_AND_GRC*****************/
#define BTN_LOCK_TIME      20      //время фиксации дребезга
#define BTN_LONG_TIME      1000   //время фиксации длинного нажатия
//**__________________порт чтения кнопок___________________*/
#define BTN_PORT1         PORTA
#define BTN_DDR1         DDRA
#define BTN_PIN1         PINA
#define BTN_PORT2         PORTD
#define BTN_DDR2         DDRD
#define BTN_PIN2         PIND
#define BTN_PORT3         PORTC
#define BTN_DDR3         DDRC
#define BTN_PIN3         PINC
//**________________пины чтения кнопок___________________**/
//_____*/
#define BTN_LINE_RA      (1<<0) //Режим РУЧ/АВТ  (PA)
#define BTN_LINE_ST      (1<<1) //Режим СЧЕТЧИК/ТАЙМЕР
#define BTN_LINE_PR      (1<<2) //MOD PROGRAMMING
#define BTN_LINE_EN      (1<<3) //BTN_ENTER
#define BTN_LINE_UP      (1<<4) //BTN_UP
#define BTN_LINE_DN      (1<<5) //BTN_DOWN
#define BTN_LINE_SM      (1<<6) //BTN_SW_СМЫКАНИЕ
#define BTN_LINE_SB      (1<<7) //BTN_SW_ШТОК_БАРЫ
//_____*/
#define BTN_LINE_S1      (1<<0) //BTN_START_1   (PD)
#define BTN_LINE_S2      (1<<1) //BTN_START_2
#define GRK_LINE_SM      (1<<2) //ГЕРКОН_СМЫКАНИЕ
#define BTN_LINE_PW      (1<<3) //BTN_ПРЕД_ВЫДУВ
#define BTN_LINE_OW      (1<<4) //BTN_ОСНОВНОЙ_ВЫДУВ
#define GRK_LINE_ZM_IP   (1<<5) //ГЕРКОН_ЗАМОК_ИСХ.ПОЛОЖЕНИЕ
#define GRK_LINE_ZM_RP   (1<<6) //ГЕРКОН_ЗАМОК_РАБ.ПОЛОЖЕНИЕ
#define BTN_LINE_ZM      (1<<7) //BTN_SWITCH_ЗАМОК
//_____*/
#define DAT_LINE_PWR   (1<<6) //ДАТЧИК_PWR (PC)
#define BTN_LINE_MOD   (1<<7) //BTN_MOD_ZM/NO_ZM
//_______Биты короткого нажатия -> BtnFlags_1_____________*/
#define BTN_SHRT_RA      (1<<0) //Режим РУЧ/АВТ
#define BTN_SHRT_ST      (1<<1) //Режим СЧЕТЧИК/ТАЙМЕР      
#define BTN_SHRT_PR      (1<<2) //MOD PROGRAMMING      
#define BTN_SHRT_EN      (1<<3) //BTN_ENTER
#define BTN_SHRT_UP      (1<<4) //BTN_UP
#define BTN_SHRT_DN      (1<<5) //BTN_DOWN
#define BTN_SHRT_SM      (1<<6) //BTN_SW_СМЫКАНИЕ
#define BTN_SHRT_SB      (1<<7) //BTN_SW_ШТОК_БАРЫ
//_______Биты короткого нажатия -> BtnFlags_2______________*/
#define BTN_SHRT_S1      (1<<0) //BTN_START_1
#define BTN_SHRT_S2      (1<<1) //BTN_START_2
#define GRK_SHRT_SM      (1<<2) //ГЕРКОН_СМЫКАНИЕ
#define BTN_SHRT_PW      (1<<3) //BTN_ПРЕД_ВЫДУВ
#define BTN_SHRT_OW      (1<<4) //BTN_ОСНОВНОЙ_ВЫДУВ
#define GRK_SHRT_ZM_IP   (1<<5) //ГЕРКОН_ЗАМОК_ИСХ.ПОЛОЖЕНИЕ
#define GRK_SHRT_ZM_RP   (1<<6) //ГЕРКОН_ЗАМОК_РАБ.ПОЛОЖЕНИЕ
#define BTN_SHRT_ZM      (1<<7) //BTN_SWITCH_ЗАМОК
//_______Биты короткого нажатия -> BtnFlags_3______________*/
#define DAT_SHRT_PWR   (1<<0) //ДАТЧИК_PWR
#define BTN_SHRT_MOD   (1<<1) //BTN_MOD_ZM/NO_ZM
//_______Биты длинного нажатия -> BtnFlags_3_______________*/
#define BTN_LONG_UP      (1<<12) //BTN_UP_LONG
#define BTN_LONG_DN      (1<<13) //BTN_DOWN_LONG
/*_________________END_TARGET_DEFINE_______________________*/
/***********************************************************/

/***********************************************************/
//________________(глобальные переменные)___________________*/
volatile uint16_t BtnFlags_1=0;
volatile uint16_t BtnFlags_2=0;
volatile uint16_t BtnFlags_3=0;
volatile uint8_t AnodCount=0;         //Счетчик Анодов Сем.Сег.Идникатора.
volatile uint8_t ModTimer = 0;         //Режим работы таймера.
volatile uint16_t CountMS=0;         //Переменная счетчик MS
volatile uint8_t FlagsEnDiplay=0;      //Флаг для работы с Сем.Сег.Идникатором.
volatile uint8_t ModDebug=0xFF;         //Ручной режим работы (отладка)(включен по дефолту)
volatile uint8_t ModAuto=0x00;         //Автоматический режим работы

void InitTimer0_OVF()
{
   TCNT0|=217; //Прерывания настроено на 1.25ms
   TIMSK|=(1<<TOIE0);//Разрешить прерывание по переполнению таймера 0.
   TCCR0|=(1<<CS02)|(0<<CS01)|(1<<CS00); //Настройка пред делителя. 100 .clk\256
}
void InitTimer1_OVF()
{
   TCCR1B|=(1<<CS12)|(0<<CS11)|(0<<CS10);   //Пред делитель
   TIMSK|=(1<<TOIE1);                   //Разрешить прерывание по переполнению таймера 1
   //TCNT1=65521;   
   TCNT1=65505   ;                  //Начальное значение таймера
}
void SPI_Init(void)
{
   /*настройка портов ввода-вывода все выводы, кроме MISO выходы*/
   SPI_DDR |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(0<<SPI_MISO);
   SPI_PORT |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(1<<SPI_MISO);
   SPCR = (1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(0<<SPR1)|(0<<SPR0);
   SPSR = (0<<SPI2X);
}
//----------
//Функции чтения данных о нажатии кнопок
uint16_t MaskGetOne (void)
{
   cli();
   uint16_t temp1 = BtnFlags_1;
   BtnFlags_1 = 0;
   sei();
   return temp1;
}
uint16_t MaskGetTwo (void)
{
   cli();
   uint16_t temp2 = BtnFlags_2;
   BtnFlags_2 = 0;
   sei();
   return temp2;
}
uint16_t MaskGetThree (void)
{
   cli();
   uint16_t temp3 = BtnFlags_3;
   BtnFlags_3 = 0;
   sei();
   return temp3;
}
//----------
//ФУНКЦИЯ ОБРАБОТКИ НАЖАТИЙ КЛАВИШ (вызывать в прерывании)
//короткое нажатие устанавливает бит BTN_SHRT_X глобальной переменной BtnFlags
//длинное нажатие устанавливает бит BTN_LONG_X глобальной переменной BtnFlags
void BtnExe (void)
{
   static uint8_t BtnLockBit;         //защелка (защита от дребезга)
   static uint8_t BtnLockCoun;         //счетчик защелки (защита от дребезга)
   static uint8_t BtnLongCoun;               //счетчик длинного нажатия
   static uint8_t BtnLastState_1;      //последнее состояние кнопок перед отпусканием
   static uint8_t BtnLastState_2;      //последнее состояние кнопок перед отпусканием
   static uint8_t BtnLastState_3;      //последнее состояние кнопок перед отпусканием
   
   uint8_t mask_1 = 0;
   uint8_t mask_2 = 0;
   uint8_t mask_3 = 0;
   
   if (!(BTN_PIN1 & BTN_LINE_RA))      mask_1 = BTN_SHRT_RA;
   if (!(BTN_PIN1 & BTN_LINE_ST))      mask_1 = BTN_SHRT_ST;
   if (!(BTN_PIN1 & BTN_LINE_PR))      mask_1 = BTN_SHRT_PR;
   if (!(BTN_PIN1 & BTN_LINE_EN))      mask_1 = BTN_SHRT_EN;
   if (!(BTN_PIN1 & BTN_LINE_UP))      mask_1 = BTN_SHRT_UP;
   if (!(BTN_PIN1 & BTN_LINE_DN))      mask_1 = BTN_SHRT_DN;
   if (!(BTN_PIN1 & BTN_LINE_SM))      mask_1 = BTN_SHRT_SM;
   if (!(BTN_PIN1 & BTN_LINE_SB))      mask_1 = BTN_SHRT_SB;
   
   if(!(BTN_PIN2 & BTN_LINE_S1))      mask_2 = BTN_SHRT_S1;
   if(!(BTN_PIN2 & BTN_LINE_S2))      mask_2 = BTN_SHRT_S2;
   if(!(BTN_PIN2 & GRK_LINE_SM))      mask_2 = GRK_SHRT_SM;
   if(!(BTN_PIN2 & BTN_LINE_PW))      mask_2 = BTN_SHRT_PW;
   if(!(BTN_PIN2 & BTN_LINE_OW))      mask_2 = BTN_SHRT_OW;
   if(!(BTN_PIN2 & GRK_LINE_ZM_IP))   mask_2 = GRK_SHRT_ZM_IP;
   if(!(BTN_PIN2 & GRK_LINE_ZM_RP))   mask_2 = GRK_SHRT_ZM_RP;
   if(!(BTN_PIN2 & BTN_LINE_ZM))      mask_2 = BTN_SHRT_ZM;
   
   if(!(BTN_PIN3 & DAT_LINE_PWR))      mask_3 = DAT_SHRT_PWR;
   if(!(BTN_PIN3 & BTN_LINE_MOD))      mask_3 = BTN_SHRT_MOD;

   if((mask_1)||(mask_2)||(mask_3))                     //опрос состояния кнопки
   {                           
      if (BtnLockCoun < (BTN_LOCK_TIME/10))         //клавиша нажата
      {
         BtnLockCoun++;
         return;                              //защелка еще не досчитала - возврат
      }
      BtnLastState_1 = mask_1;
      BtnLastState_2 = mask_2;
      BtnLastState_3 = mask_3;
      BtnLockBit =1;                           //нажатие зафиксировано
      if (BtnLongCoun >= (BTN_LONG_TIME/10))
      {
         return;   //возврат, т.к. счетчик длин.нажат. досчитал до максимума еще раньше
      }
      if (++BtnLongCoun >= (BTN_LONG_TIME/10))
      {
         if (mask_1)
         {
            BtnFlags_1|= (BtnLastState_1<<8);   //счетчик досчитал до максимума - устанавливаем биты длинного нажатия
         }
         if (mask_2)
         {
            BtnFlags_2 |= (BtnLastState_2<<8);
         }
         if (mask_3)
         {
            BtnFlags_3 |= (BtnLastState_3<<8);
         }
      }
   }
   else                                    //клавиша отжата
   {                              
      if (BtnLockCoun)
      {
         BtnLockCoun --;
         return;                              //защелка еще не обнулилась - возврат
      }
      if (! BtnLockBit) return;                  //СТАТИЧЕСКИЙ ВОЗВРАТ
      BtnLockBit =0;                           //отжатие зафиксировано
      if (BtnLongCoun < (BTN_LONG_TIME/10))
      {
         if(!(mask_1))
         {
            BtnFlags_1 |= BtnLastState_1;   
         }         //установка бита короткого нажатия
         if (!(mask_2))
         {
            BtnFlags_2 |= BtnLastState_2;
         }
         if (!(mask_3))
         {
            BtnFlags_3 |= BtnLastState_3;
         }
      }
      BtnLongCoun = 0;                        //сброс счетчика длительности нажатия
   }
}
struct UnionBits 
{
   unsigned DO0: 1;
   unsigned DO1: 1;
   unsigned DO2: 1;
   unsigned DO3: 1;
   unsigned DO4: 1;
   unsigned DO5: 1;
   unsigned DO6: 1;
   unsigned DO7: 1;
};
union Byte {
   uint8_t  ByteRegister;
   struct UnionBits Register;
};
union Byte OneOUT; //аноды
union Byte TwoOUT; //Катоды
uint8_t SPI_UpdataByte(uint8_t data)
{
   uint8_t report;
   SPDR = data;
   while(!(SPSR & (1<<SPIF)));
   report = SPDR;
   return report;
}
void SpiUpdateRegister()
{
   SPI_PORT &= ~(1<<SPI_SS);
   SPI_UpdataByte(OneOUT.ByteRegister);
   SPI_UpdataByte(TwoOUT.ByteRegister);
   SPI_PORT |= (1<<SPI_SS);
}
void StartInitIO()
{
   OneOUT.ByteRegister=0x00;
   TwoOUT.ByteRegister=0x00;
}
//Функция вывода символов
static void PrintChar (uint8_t Number)
{
   switch (Number)
   {
      case 0:
      SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
      case 1:
      SEG_PORT=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
      case 2:
      SEG_PORT=(0<<SEGA)|(0<<SEGB)|(1<<SEGC)|(0<<SEGD)|(0<<SEGE)|(1<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
      case 3:
      SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(1<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
      case 4:
      SEG_PORT=(1<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
      case 5:
      SEG_PORT=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
      case 6:
      SEG_PORT=(0<<SEGA)|(1<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
      case 7:
      SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
      case 8:
      SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
      case 9:
      SEG_PORT=(0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(1<<SEGE)|(0<<SEGF)|(0<<SEGG)|(1<<SEGH);break;
      case 99: //OFF Все сегменты
      SEG_PORT=(1<<SEGA)|(1<<SEGB)|(1<<SEGC)|(1<<SEGD)|(1<<SEGE)|(1<<SEGF)|(1<<SEGG)|(1<<SEGH);break;
   }
   if ((ModTimer == 0)&&(AnodCount == 3))
   {

      SEG_PORT &=~(1<<SEGH);
   }
}
//Функция вывода динамической индикации.
void PrintNumber(uint16_t NeberChar,uint8_t NumberTimers)
{
   /***Разбитие числа на разряды***/
   /*data1->младший,data5->Старший,data6 отдельный разряд*/
   uint8_t data1=NeberChar%10;
   uint8_t data2=(NeberChar%100)/10;
   uint8_t data3=(NeberChar%1000)/100;
   uint8_t data4=(NeberChar%10000)/1000;
   uint8_t data5=(NeberChar/10000);
   uint8_t data6=NumberTimers; //1..4
   AnodCount++;
   switch (AnodCount)
   {
   case 1:
   ANOD1=0;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
   PrintChar(data1);
      break;
   case 2:
   if (((data2+data3+data4+data5)!=0)|| (ModTimer == 0)) //если сумма старших раааазрядов !=0 то выводим разряд иначе гасим.
   {
      ANOD1=1;ANOD2=0;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=1;
      PrintChar(data2);
   } else PrintChar(99); //гасим разряд.
      break;
   case 3:
   if (((data3+data4+data5)!=0)|| (ModTimer == 0)) //если сумма старших раааазрядов !=0 то выводим разряд иначе гасим.
   {
      ANOD1=1;ANOD2=1;ANOD3=0;ANOD4=1;ANOD5=1;ANOD6=1;
      PrintChar(data3);
   } else PrintChar(99); //гасим разряд.
      break;
   case 4:
   if ((data4+data5)!=0) //если сумма старших раааазрядов !=0 то выводим разряд иначе гасим.
   {
      ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=0;ANOD5=1;ANOD6=1;
      PrintChar(data4);
   } else PrintChar(99); //гасим разряд.
      break;
   case 5:
   if (data5!=0) //если сумма старших раааазрядов !=0 то выводим разряд иначе гасим.
   {
      ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=0;ANOD6=1;
      PrintChar(data5);
   } else PrintChar(99); //гасим разряд.
      break;
   case 6:
   if (data6!=0) //если сумма раааазряда !=0 то выводим разряд иначе гасим.
   {
      ANOD1=1;ANOD2=1;ANOD3=1;ANOD4=1;ANOD5=1;ANOD6=0;
      PrintChar(data6);
   } else PrintChar(99); //гасим разряд.
   AnodCount=0;
      break;
   }
}
void InitIO_MC(void)
{
   DDRA|=0x00; // Config InPut
   PORTA|=0x00;
   DDRB|=0xFF; // Config OutPut
   PORTB=0x00;
   DDRC|=(0<<PC7)|(0<<PC6)|(1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2)|(1<<PC1)|(1<<PC0);
   PORTC|=0x00;
   DDRD|=0x00;  // Config IntPut
   PORTD|=0x00;
}
//uint8_t TempCount=0;
ISR (TIMER0_OVF_vect)
{
   TCNT0|=217;
   SpiUpdateRegister();
   BtnExe();
   FlagsEnDiplay=1;
}
ISR (TIMER1_OVF_vect)
{
   TCNT1=65505;
   CountMS++;
}
char temptest=0;
uint8_t FlagSM=0;
uint8_t FlagBtnSM=0;
uint8_t FlagSB=0;
uint8_t FlagBtnSB=0;
uint8_t FlagPW=0;
uint8_t FlagBtnPW=0;
uint8_t FlagOW=0;
uint8_t FlagBtnOW=0;
void InputMaskUpdate(uint16_t InputOne,uint16_t InputTwo,uint16_t InputThree)
{
   switch(InputOne)
   {
      case BTN_SHRT_RA:
         ModAuto=~ModAuto;
         ModDebug=~ModDebug;
         DISPLAY_MOD_JOB=ModAuto;
         break;
      case BTN_SHRT_ST:
         ModTimer=~ModTimer;
         DISPLAY_MOD_TIM=ModTimer;
         break;
      case BTN_SHRT_PR:
         break;
      case BTN_SHRT_EN:
         break;
      case BTN_SHRT_UP:temptest++;
         break;
      case BTN_SHRT_DN:temptest--;
         break;
      case BTN_LONG_UP:temptest+=10;
         break;
      case BTN_SHRT_SM:
         FlagBtnSM=~FlagBtnSM;
         break;
      case BTN_SHRT_SB:
         FlagBtnSB=~FlagBtnSB;
         break;
      case BTN_LONG_DN:temptest-=10;
         break;
      default:break;
   }
   switch(InputTwo)
   {
      case BTN_SHRT_S1:
         break;
      case BTN_SHRT_S2:
         break;
      case GRK_SHRT_SM:
         break;
      case BTN_SHRT_PW:
         FlagBtnPW=~FlagBtnPW;
         break;
      case BTN_SHRT_OW:
         FlagBtnOW=~FlagBtnOW;
         break;
      case GRK_SHRT_ZM_IP:
         break;
      case GRK_SHRT_ZM_RP:
         break;
      case BTN_SHRT_ZM:
         break;
      default:break;
   }
   switch(InputThree)
   {
      case DAT_LINE_PWR:
         break;
      case BTN_SHRT_MOD:
         break;
      default:break;
   }
}
int main(void)
{
   InitIO_MC(); //Иницилизация портов.
   _delay_ms(999);
   _delay_us(977);
   SPI_Init();
   StartInitIO();
   SpiUpdateRegister();
   InitTimer1_OVF();
   InitTimer0_OVF();
   volatile uint16_t InputMaskOne=0;
   volatile uint16_t InputMaskTwo=0;
   volatile uint16_t InputMaskThree=0;
   sei();
    while(1)
    {
      if (FlagsEnDiplay)
      {
         PrintNumber((CountMS/10),1);
         FlagsEnDiplay=0;
      }
      InputMaskOne = MaskGetOne();
      InputMaskTwo = MaskGetTwo();
      InputMaskThree = MaskGetThree();
      InputMaskUpdate(InputMaskOne,InputMaskTwo,InputMaskThree);
      if (ModDebug)
      {
         if (FlagBtnSM)
         {
            ENABLE_SM;
         } else DISABLE_SM;
         
         if (FlagBtnSB)
         {
            ENABLE_SB;
         } else DISABLE_SB;
         
         if (FlagBtnPW)
         {
            while(!(PIND&BTN_LINE_PW))
            {
               ENABLE_PW;
            }
         }else DISABLE_PW;
         
         if (FlagBtnOW)
         {
            ENABLE_OW;
         }else if (PIND&BTN_LINE_OW) DISABLE_OW;
      }
      if (ModAuto)
      {
         
      }
      
    }
   return 0;
}

_________________
andrei23061996@gmail.com
.................................................................................................................


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
СообщениеДобавлено: Пт май 25, 2018 08:43:51 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
7seg писал(а):
Дефайны и листинг под спойлером
от увиденного я в своей оценке вашего кода возведу слово "трэш" в квадрат.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
СообщениеДобавлено: Пт май 25, 2018 08:48:02 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4510
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Деление на 10 с остатком в цикле - всё преобразование.

Добавлено after 1 minute 25 seconds:
Re: Как оптимизировать разбитие 16бит-числа на составляющие ?
Цитата:
от увиденного я в своей оценке вашего кода возведу слово "трэш" в квадрат.
ARV, да нормально там всё в коде. Что так сильно Вам не понравилось ?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
СообщениеДобавлено: Пт май 25, 2018 08:50:14 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
ну, если нормально, значит у меня болевой порог слишком низкий - у меня кровь из глаз едва не пошла.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
СообщениеДобавлено: Пт май 25, 2018 08:55:16 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4510
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
:)))
Ну просто в куче всё, по этому так и смотрится. Если разбить всё по модулям - будет намного лучше :)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
СообщениеДобавлено: Пт май 25, 2018 09:10:37 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
да, если написать все, как следует - будет лучше.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
СообщениеДобавлено: Пт май 25, 2018 11:06:17 
Потрогал лапой паяльник
Аватар пользователя

Карма: 3
Рейтинг сообщений: 3
Зарегистрирован: Ср май 03, 2017 03:22:26
Сообщений: 303
Рейтинг сообщения: 0
Если я понял вас правильно , то оптимальней будет завести массив
uint8_t data[5];

и заполнять его через цикл:

uint8_t TempResult =0;
for (int i = 0; i < 5; i++)
{
TempResult = NeberChar % 10;
NeberChar = NeberChar / 10;
data[i]=TempResult;
}

где NeberChar значение в диапазоне 0..65534 , а data[0]..data[4] и есть искомые значения.

_________________
andrei23061996@gmail.com
.................................................................................................................


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
СообщениеДобавлено: Пт май 25, 2018 11:29:41 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
и завести массив "символов", куда поместить все ваши ужасные (0<<SEGA)|(0<<SEGB)|(0<<SEGC)|(0<<SEGD)|(0<<SEGE)|(0<<SEGF)|(1<<SEGG)|(1<<SEGH), чтобы внезапно оказалось, что в вашем массиве data индексы для массива символов...

Добавлено after 2 minutes 26 seconds:
Re: Как оптимизировать разбитие 16бит-числа на составляющие ?
TempResult, кстати, лишняя сущность.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
СообщениеДобавлено: Пт май 25, 2018 11:49:41 
Потрогал лапой паяльник
Аватар пользователя

Карма: 3
Рейтинг сообщений: 3
Зарегистрирован: Ср май 03, 2017 03:22:26
Сообщений: 303
Рейтинг сообщения: 0
Тогда наверно будет удобней выводить индикацию в таком формате
void PrintNumber(uint16_t NeberChar,uint8_t NumberTimers)
{
uint8_t TempResult =0;
for (int i = 0; i < 5; i++)
{
TempResult = NeberChar % 10;
NeberChar = NeberChar / 10;
data[i]=TempResult;
AnodCount=i;
OneOUT.ByteRegister &=~(1<<i);
PrintChar(data[i]);
}
}

_________________
andrei23061996@gmail.com
.................................................................................................................


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

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


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

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


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

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


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