Форум РадиоКот • Просмотр темы - Как оптимизировать разбитие 16бит-числа на составляющие ?
Сообщения без ответов | Активные темы
Страница 1 из 1
[ Сообщений: 14 ]
Автор
Сообщение
7seg
Заголовок сообщения: Как оптимизировать разбитие 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Вернуться наверх
Реклама
Z_h_e
Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
Добавлено: Пт май 25, 2018 06:26:51
Собутыльник Кота
Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04Сообщений: 2694Откуда: г. Чайковский
Рейтинг сообщения: 0
Медали: 1
Возможно будет иметь смысл применить двоично десятичный формат числа. Тогда для динамической индикации ничего преобразовывать не надо будет.
_________________Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Вернуться наверх
Реклама
7seg
Заголовок сообщения: 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 раз.
Вернуться наверх
Реклама
Engineer_Keen
Заголовок сообщения: 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% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Подробнее>>
ARV
Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
Добавлено: Пт май 25, 2018 07:42:02
Ум, честь и совесть. И скромность.
Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56Сообщений: 18030Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
ваш код, 7seg , - лютый трэш. вы хоть почитайте о том, как организуется преобразование чисел в символьное представление, как организуется динамическая (и не динамическая) индикация на 7-сегментниках... как вообще пишутся программы - про циклы, например, дефайны и т.п. вопрос у вас настолько примитивный, что просто удивительно, как вы его еще задать смогли - я даже про гугление не говорю, здесь, на радиокоте статей и сообщений на форуме - просто жри не лопни! ну как же вы так-то, а?
_________________если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...Мой уютный бложик ... заходите!
Вернуться наверх
Реклама
Реклама
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Подробнее>>
7seg
Заголовок сообщения: 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Вернуться наверх
Реклама
ARV
Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
Добавлено: Пт май 25, 2018 08:43:51
Ум, честь и совесть. И скромность.
Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56Сообщений: 18030Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
7seg писал(а):
Дефайны и листинг под спойлером
от увиденного я в своей оценке вашего кода возведу слово "трэш" в квадрат.
_________________если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...Мой уютный бложик ... заходите!
Вернуться наверх
Реклама
Аlex
Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
Добавлено: Пт май 25, 2018 08:48:02
Модератор
Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57Сообщений: 4510Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Деление на 10 с остатком в цикле - всё преобразование.
Добавлено after 1 minute 25 seconds: Re: Как оптимизировать разбитие 16бит-числа на составляющие ? Цитата:
от увиденного я в своей оценке вашего кода возведу слово "трэш" в квадрат.
ARV, да нормально там всё в коде. Что так сильно Вам не понравилось ?
Вернуться наверх
Реклама
ARV
Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
Добавлено: Пт май 25, 2018 08:50:14
Ум, честь и совесть. И скромность.
Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56Сообщений: 18030Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
ну, если нормально, значит у меня болевой порог слишком низкий - у меня кровь из глаз едва не пошла.
_________________если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...Мой уютный бложик ... заходите!
Вернуться наверх
Реклама
ARV
Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
Добавлено: Пт май 25, 2018 09:10:37
Ум, честь и совесть. И скромность.
Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56Сообщений: 18030Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
да, если написать все, как следует - будет лучше.
_________________если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...Мой уютный бложик ... заходите!
Вернуться наверх
7seg
Заголовок сообщения: 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Вернуться наверх
ARV
Заголовок сообщения: Re: Как оптимизировать разбитие 16бит-числа на составляющие
Добавлено: Пт май 25, 2018 11:29:41
Ум, честь и совесть. И скромность.
Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56Сообщений: 18030Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
и завести массив "символов", куда поместить все ваши ужасные (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, кстати, лишняя сущность.
_________________если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...Мой уютный бложик ... заходите!
Вернуться наверх
7seg
Заголовок сообщения: 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Вернуться наверх
Страница 1 из 1
[ Сообщений: 14 ]
Кто сейчас на форуме
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 53
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения