Вс авг 14, 2022 20:35:05
result |= ((DDRB & (1<<Rbit)) >> Rbit) << Wbit;
result = (DDRB & (1 << Rbit)) ? result | (1 << Wbit) : result & ~(1 << Wbit);
Вс авг 14, 2022 20:49:21
Что, проще нет что ли? Давайте предоставим все это компилятору.MLX90640 писал(а):Тут сложность в понимании того, что используется так называемый тренарный оператор условия.
Вс авг 14, 2022 21:10:12
Вс авг 14, 2022 23:02:29
Вс авг 14, 2022 23:07:51
Ср авг 17, 2022 13:11:54
Ср авг 17, 2022 13:40:37
Ср авг 17, 2022 14:42:08
Второй из них заключается в том, чтобы при сдвиге цифр влево просто переносить байты цифр в буфере дисплея левее, начиная слева. Допустим, есть буфер
buf[4], в котором buf[0] - самый левый разряд, а buf[3] - самый правый. Так вот, каждый шаг анимации бегущей строки будет представлен шагами:
Первый же способ делается на указателях. В этом случае ничего не копируется, инкрементируется только указатель на начало отображения строки в дисплей, сдвигаясь по строке.
ISR(TIMER1_COMPA_vect) { //обработчик прерывания по совпадению А таймера 1, счетчик сбрасывается в 0
PORTD&=0b11110000; // потушить все (разряды - off)
PORTB=digits[digit_out[cur_dig]]&maska; // символ на экран
PORTD |= (1<<cur_dig); // засветить нужный разряд (бит знакоместа - on)
cur_dig++; if (cur_dig > 3) {
cur_dig = 0;
}
}
Ср авг 17, 2022 15:15:29
/* кодирование сегментов в байте */
#define SEG_A (1 << 0)
#define SEG_B (1 << 1)
#define SEG_C (1 << 2)
#define SEG_D (1 << 3)
#define SEG_E (1 << 4)
#define SEG_F (1 << 5)
#define SEG_G (1 << 6)
#define SEG_dp (1 << 7)
/* символы шрифта */
#define BLANK 0
#define CH_0 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F )
#define CH_1 ( SEG_B | SEG_C )
#define CH_2 (SEG_A | SEG_B | SEG_D | SEG_E | SEG_G)
#define CH_3 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_G)
#define CH_4 ( SEG_B | SEG_C | SEG_F | SEG_G)
#define CH_5 (SEG_A | SEG_C | SEG_D | SEG_F | SEG_G)
#define CH_6 (SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)
#define CH_7 (SEG_A | SEG_B | SEG_C )
#define CH_8 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)
#define CH_9 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G)
#define CH_DASH ( SEG_G)
#define CH_DNDASH ( SEG_D )
const uint8_t font[] =
{CH_0, CH_1, CH_2, CH_3, CH_4, CH_5, CH_6, CH_7, CH_8, CH_9};
#define NUM_DIG 4 // число разрядов в индикаторе
static uint8_t buf[NUM_DIG]; // буфер хранения данных о сегментах в разрядах
/** ----------
* @brief Преобразование текстовой строки в данные для сегментов
* индикатора.
* @param *str - входная текстовая строка в кодировке ANSI
* @param len - длина строки
*/
void DND_Print(char *str, uint8_t len)
{
uint8_t digit = 0;
uint8_t dotsign[NUM_DIG] = {0, 0, 0, 0};
/* преобразование текстовой строки */
while(len--)
{
switch(*str){
/* цифры */
case '0' ... '9':
buf[digit] = font[*str - '0'];
break;
/* тире */
case '-': buf[digit] = CH_DASH;
break;
case '_': buf[digit] = CH_DNDASH;
break;
/* десятичные точки*/
case '.':
case ',':
/* для индикатора с разделительным двоеточием */
if(digit == 2)
{
dotsign[3] = SEG_dp;
}
digit--;
break;
/* разделительные точки */
case ':':
/* для индикатора с разделительным двоеточием */
if(digit == 2)
{
dotsign[2] = SEG_dp;
dotsign[3] = SEG_dp;
}
digit--;
break;
default: buf[digit] = BLANK;
}
str++; // следующий символ в строке
digit++; // следующий разряд
if(digit > NUM_DIG) break;
}
/* добавление признака точек в разряды*/
for(digit = 0; digit < NUM_DIG; digit++)
{
buf[digit] |= dotsign[digit];
}
}
/** ----------
* @brief Поразрядное переключение шагов динамической индикации.
*/
#ifdef USE_SEGMENT_ANIMATION
#include "fx.h"
#endif
void DND_DynaScan(void)
{
static uint8_t digit = 0;
#ifdef USE_SEGMENT_ANIMATION
uint8_t mask;
mask = DND_SegAnimation_GetMask(digit);
DND_DigitOut(digit, buf[digit] & mask);
#else
DND_DigitOut(digit, buf[digit]); // для варианта без анимации сегментов
#endif
digit++;
if(digit >= NUM_DIG) digit = 0;
}
DND_Print("1259", 4); // фиксированная текстовая строка в формате ANSI
char str[10];
uint8_t len;
len = sprintf(str, "%02d:%02d", current_time.tm_hour, current_time.tm_min);
DND_Print(str, len);
/* кодирование сегментов для цифр такое же как выше */
const uint8_t font[] =
{CH_0, CH_1, CH_2, CH_3, CH_4, CH_5, CH_6, CH_7, CH_8, CH_9};
/* Преобразование чисел от 0 до 9 в сегменты индикатора */
void DND_Print(byte d0, byte d1, byte d2, byte d3)
{
buf[0] = font[d0];
buf[1] = font[d1];
buf[2] = font[d2];
buf[3] = font[d3];
}
Ср авг 17, 2022 15:16:54
Ср авг 17, 2022 15:18:55
Чт авг 18, 2022 03:43:58
Чт авг 18, 2022 09:52:52
Да... Если всё написанное выше слишком сложно для понимания, то можно существенно упростить функции, сделав их по-топорному,
Чт авг 18, 2022 13:08:33
Чт авг 18, 2022 13:57:45
#define SEG_A (1 << 5)
#define SEG_B (1 << 7)
#define SEG_C (1 << 0)
#define SEG_D (1 << 3)
#define SEG_E (1 << 1)
#define SEG_F (1 << 4)
#define SEG_G (1 << 6)
#define SEG_dp (1 << 2)
Чт авг 18, 2022 13:59:03
switch(*str){
/* цифры */
case '0' ... '9':
buf[digit] = font[*str - '0'];
break;
#ifdef USE_LETTERS
/* буквы */
case 'A' ... 'U':
buf[digit] = font[*str - 'A' + 10];
break;
case 'a' ... 'u':
buf[digit] = font[*str - 'a' + 10];
break;
#endif
/* тире */
case '-': buf[digit] = CH_DASH;
break;
case '_': buf[digit] = CH_DNDASH;
break;
/* десятичные точки*/
case '.':
case ',':
/* для индикатора с разделительным двоеточием */
if(digit == 2)
{
dotsign[3] = SEG_dp;
}
digit--;
break;
/* разделительные точки */
case ':':
/* для индикатора с разделительным двоеточием */
if(digit == 2)
{
dotsign[2] = SEG_dp;
dotsign[3] = SEG_dp;
}
digit--;
break;
default: buf[digit] = BLANK;
Чт авг 18, 2022 15:53:02
Функция void DND_Print(byte d0, byte d1, byte d2, byte d3) принимает числовые значения d0, d1, d2, d3
Чт авг 18, 2022 16:20:03
#define byte unsigned char
Чт авг 18, 2022 17:15:38
Чт авг 18, 2022 17:39:16