Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.96/24: Рейтинг темы: голосов - 24, средняя оценка - 4.96
jomis77
0 / 0 / 0
Регистрация: 26.03.2013
Сообщений: 58
1

Мигающий текст на LCD HD44780

01.05.2015, 03:35. Просмотров 4412. Ответов 5
Метки нет (Все метки)

Всем привет! А как проще всего сделать часть текста выводимого на LCD типа HD44780 мигающим? Именно часть текста, а не курсор. Сейчас использую для LCD библиотеку отсюда http://chipenable.ru/index.php/progr...i-hd44780.html. Я предполагаю два возможных решения (не факт, что они верные):
1. По таймеру выводить и затирать нужный кусок текста
2. Организовывать что-то типа видеобуфера с дополнительными свойствами-флагами для каждого знакоместа и уже потом регулярно по таймеру обновлять все содержимое дисплея с учетом свойств-флагов.
Может есть более оригинальные, простые и правильные решения?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.05.2015, 03:35
Ответы с готовыми решениями:

Инициализация lcd на HD44780
Здравствуйте! Пытаюсь освоить lcd на HD44780. Понимаю, что есть много уже...

О выводе на дисплей LCD HD44780
Пишу программу на Atmego32A. Столкнулся с проблемкой при выводе на дисплей....

Библиотерка LCD на контроллере HD44780
Для работы на си с данным дисплеем в winAVR есть библиотека "lcd_lib". Возьмем...

Вывод на LCD HD44780 HEX кода
Доброго времени суток, господа. Прошу Вашей помощи в решение одной проблемы....

Работа с LCD дисплеем HD44780 из МК Atmega16 (GCC)
Здравствуйте, пытаюсь подключить LCD дисплей к микроконтроллеру, скачал...

5
BykTiho
0 / 0 / 0
Регистрация: 12.04.2010
Сообщений: 3,260
01.05.2015, 07:25 2
Оба решения простые и правильные. Но мне кажется, что более "правильно" будет первое, т.к. намного упрощается алгоритм. Зато второе - универсальное, любой текст в любом месте можно сделать мигающим без исправления исходного кода.
Если заранее не знать что куда будет выводиться, я бы пожертвовал размером кода и реализовал второй вариант.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
01.05.2015, 09:52 3
Код
extern void _Print_Buf (u08 x, char __flash *data);
#define Print_Buf(y, x, data) _Print_Buf(((y)-1)*POSITION_MAX_X+((x)-1), (data))

//------------------------------------------------------------------------
void _Print_Buf (u08 x, char __flash *data)
{
u08 i = 0;

while (data [i])
{
dsp_buf [x++] = data [i++];
}

init_dsp_buf ();
}
//========================================================================

//------------------------------------------------------------------------
void change_t_heat_init (void)
{
Print_Buf (3, 1, "ФОРМ");
Print_Buf (4, 11, "ПАР");

tui_service_blink_string = 1;

_tui_service_slave = TUI_SERVICE_CHANGE_T_HEAT;
}
//------------------------------------------------------------------------
void blink_heat (void)
{
switch (tui_service_blink_string)
{
case 0:
briok;

case 1:
clr_str (2, 1, 4);
//             Print_Buf (2, 1, "    "); // Или так.
set_timer (ST_TUI_SERVICE_2, NO_RERUN_TIMER, 500);
tui_service_blink_string = 2;
briok;

case 2:
if (woyt (ST_TUI_SERVICE_2))
{
Print_Buf (2, 1, "НАГР");

set_timer (ST_TUI_SERVICE_2, NO_RERUN_TIMER, 500);
tui_service_blink_string = 3;
}
briok;

case 3:
if (woyt (ST_TUI_SERVICE_2))
{
tui_service_blink_string = 1;
}
briok;

default:
briok;
}
}
//------------------------------------------------------------------------
Видео.

Вывод информации на дисплей реализован следующим образом. Есть буфер. 20 символов x 4 строки = 80 байт. Вывод на дисплей посимвольно, каждые 1 мс. Полное обновление дисплея происходит за кол-во символов * кол-во строк + адреса строк. Итого 84 мс.
0
jomis77
0 / 0 / 0
Регистрация: 26.03.2013
Сообщений: 58
02.05.2015, 15:00 4
Я тоже больше склоняюсь к второму варианту, люблю универсальные решения.
В связи с этим у меня к уважаемому dymyurk1978 несколько вопросов (опыта и знаний у меня пока маловато, поэтому заранее извиняюсь за возможно "нубские" вопросы):
1. Я так понимаю используется какой-то программный таймер (set_timer (ST_TUI_SERVICE_2, NO_RERUN_TIMER, 500)). Можно посмотреть реализацию?
2. Судя из определения (extern void _Print_Buf (u08 x, char __flash *data);) буфер используется только для отображения интерфейса (имеется ввиду заранее известного и не меняющегося в программе текста)? А для отображения числовых значений параметров используется отдельная функция вывода?
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
02.05.2015, 18:33 5
sys_timer.h
Код
#ifndef SYS_TIMER_H

#define SYS_TIMER_H

#include "sys_timer.h"

#include <ioavr.h>

#include "avrlibtypes.h"

//========================================================================
#define ST_TCNT         TCNT0
#define ST_TIMSK        TIMSK
#define ST_OCIE         OCIE0
#define ST_OCR          OCR0
#define ST_TCCR         TCCR0
#define CS0             CS00
#define CS1             CS01
#define CS2             CS02
//========================================================================

//========================================================================
#define SYS_TICK_TIME   1 // Период системного таймера 1 мс
//========================================================================

//========================================================================
#define ST_SIZE         2
//========================================================================

//========================================================================
//--------------------- Флаги системных таймеров -------------------------
#define SYS_TICK_FLG    0
//------------------------------------------------------------------------

//------------------------------------------------------------------------
#define NO_RERUN_TIMER  0

#define TMR_UNLOCK      0 // Флаг активности таймера.
#define RERUN_TIMER     1
#define TIME_OUT        2 // Время вышло.

#define TMR_UNLOCK_FLG  1<<TMR_UNLOCK // Флаг активности таймера.
#define RERUN_TIMER_FLG 1<<RERUN_TIMER
#define TIME_OUT_FLG    1<<TIME_OUT // Время вышло.
//========================================================================

//========================================================================
extern u08 sys_tick;
//========================================================================

#define TMRS_QUANTITY   25

// typedef struct tmrs_queue {u08 st_flags; u16 st_cnt} tmrs_queue;
typedef struct tmrs_queue
{
u08 tmr_flags;
u16 tmr_cnt;
u16 tmr_period;
} tmrs_queue;

extern struct tmrs_queue Timers_Queue [];

enum
{
ST_KBD_1 = 0,
ST_KBD_2,

ST_DRV_CHAR_DSP,

ST_TUI_SERVICE_COLON,
ST_TUI_SERVICE_2,
};

void init_sys_timer (void);

void service_timers (void);

u08 woyt (u08 num_tmr);

void set_timer (u08 num_tmr, u08 flags, u16 time);

#endif
sys_timer.c
Код
//========================================================================
#include "sys_timer.h"
//========================================================================

//========================================================================
u08 sys_tick;
//========================================================================

//========================================================================
#pragma vector = TIMER0_COMP_vect
__interrupt void Timer0Comp(void)
{
ST_OCR += 250;
sys_tick |= 1<<SYS_TICK_FLG;
}
//========================================================================

//========================================================================
void init_sys_timer (void)
{
sys_tick = 0;
ST_TCNT = 0;
ST_TIMSK |= 1<<ST_OCIE;
ST_OCR = 250;
ST_TCCR |= (1<<CS0) | (1<<CS1);
}
//------------------------------------------------------------------------

//------------------------------------------------------------------------
struct tmrs_queue Timers_Queue [TMRS_QUANTITY];

void service_timers(void)
{
if (sys_tick & (1<<SYS_TICK_FLG))
{
sys_tick &= ~ (1<<SYS_TICK_FLG);

struct tmrs_queue *p_tmrs_queue = Timers_Queue;

for (p_tmrs_queue = Timers_Queue; p_tmrs_queue < Timers_Queue + TMRS_QUANTITY; p_tmrs_queue++)
{
if (p_tmrs_queue -> tmr_flags & (1<<TMR_UNLOCK_FLG))
{
p_tmrs_queue -> tmr_cnt--;

if (p_tmrs_queue -> tmr_cnt == 0)
p_tmrs_queue -> tmr_flags |= (1<<TIME_OUT_FLG);
}
}
}
}

//------------------------------------------------------------------------

//------------------------------------------------------------------------
void set_timer(u08 num_tmr, u08 flags, u16 time)
{
struct tmrs_queue *p_tmrs_queue = Timers_Queue+num_tmr;
p_tmrs_queue -> tmr_flags = flags | (1<<TMR_UNLOCK_FLG);
p_tmrs_queue -> tmr_cnt = time;
}
//------------------------------------------------------------------------

//------------------------------------------------------------------------
u08 woyt(u08 num_tmr)

{
struct tmrs_queue *p_tmrs_queue = Timers_Queue+num_tmr;
if(p_tmrs_queue -> tmr_flags & (1<<TIME_OUT_FLG))
{
p_tmrs_queue -> tmr_flags &= ~ (1<<TIME_OUT_FLG);
return 1;
}
else
return 0;
}
//========================================================================
Пример использования вы видели выше.

Буфер это буфер. Что положишь в него, то и будет выводиться на дисплей. extern void _Print_Buf (u08 x, char __flash *data); В данном случае в буфер выводится текст, который расположен в flash памяти.

char_dysplay.h
Код
#ifndef CHAR_DISPLAY_H

#define CHAR_DISPLAY_H

#include "char_dysplay.h"

#include <ioavr.h>

#include "avrlibtypes.h"
#include "macros.h"
#include "main_def_func.h"

//========================================================================
#define LCD             0
#define VFD             1

#define TYPE_DISPLAY    VFD // LCD //
//========================================================================

//========================================================================
// LCD Data Port
#define DATA_PORT       PORTA
#define DATA_PIN        PINA
#define DATA_DDR        DDRA

#define CMD_PORT        PORTA // LCD Control Port
#define CMD_PIN         PINA
#define CMD_DDR         DDRA

// Строб.
#define EN_PORT         PORTA
#define EM_DDR          DDRA

#define EN              2

// Команда\данные.
#define RS_PORT         PORTA
#define RS_DDR          DDRA

#define RS              3
//========================================================================

//========================================================================
#define Line1           0x80 // Адрес первой строки.
#define Line2           0xC0 // Адрес второй строки.
#define Line3           0x94 // Адрес третьей строки.
#define Line4           0xD4 // Адрес четвертой строки.
//========================================================================

//========================================================================
#define DRV_LCD_TIME    1
//========================================================================

//========================================================================
#if (TYPE_DISPLAY==VFD)
extern u08 brykht; // Значение яркости VFD.
// 3 - 25%
// 2 - 75%
// 1 - 50%
// 0 - 100%

#define QUANT_USERS_CHARS 4

#define ARROW_RIGHT 2
#define ARROW_LEFT 3

extern u08 __flash table_usirs_chars [];

extern u08 __flash table_rus_chars [];
#endif
//========================================================================

//========================================================================
void lcd_io_in (void);
void lcd_send_mybbti (u08 lcd_data);
void lcd_send_byte (u08 lcd_data);
void lcd_send_som_mybbti (u08 lcd_data);
void lcd_send_som (u08 lcd_data);
void lcd_send_data (u08 lcd_data);
//========================================================================

//========================================================================
void char_dsp_init (void);
//========================================================================

//========================================================================
void def_usirs_chars (u08 __flash *ptr);
//========================================================================

//========================================================================
extern u08 _drv_char_dsp;
//------------------------------------------------------------------------
enum
{
DRV_CHAR_DSP_INIT_1 = 0,
DRV_CHAR_DSP_INIT_2,
DRV_CHAR_DSP_SIT_NEXT_STATE,
DRV_CHAR_DSP_SEND_ADDR,
DRV_CHAR_DSP_SEND_CHAR,
};
//------------------------------------------------------------------------
extern u08 position_x;
extern u08 position_y;
//------------------------------------------------------------------------
void drv_char_dsp (void);
//========================================================================

//========================================================================
#define POSITION_MAX_X    20   // Количество символов в строке.
#define POSITION_MAX_Y    4    // Количество строк дисплея.

extern u08 dsp_buf [];

#define LineBuf1          dsp_buf
#define LineBuf2          dsp_buf+POSITION_MAX_X
#define LineBuf3          dsp_buf+(POSITION_MAX_X*2)
#define LineBuf4          dsp_buf+(POSITION_MAX_X*3)
//========================================================================

//========================================================================
extern void clr_dsp_buf (void);

extern void init_dsp_buf (void);

#define clr_str(y, x, n) clr_string(((y)-1)*POSITION_MAX_X+((x)-1), (n))
void clr_string (u08 x, u08 n);
//========================================================================

//========================================================================
extern void _PrintChar (u08 x, u08 a);
#define PrintChar(y, x, a) _PrintChar(((y)-1)*POSITION_MAX_X+((x)-1), (a))
//========================================================================

#endif
char_dysplay.c
Код
//========================================================================
#include "char_dysplay.h"
//========================================================================

//========================================================================
void lcd_io_in (void)
{
DATA_DDR = DATA_DDR & 0x0F;
DATA_PORT = DATA_PORT & 0x0F;
}
//------------------------------------------------------------------------

//------------------------------------------------------------------------
void lcd_send_mybbti (u08 lcd_data)
{
set_bit (CMD_PORT, EN);
DATA_PORT = (DATA_PORT & 0x0F) | (lcd_data & 0xF0);
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
clr_bit (CMD_PORT, EN);
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
//------------------------------------------------------------------------

//------------------------------------------------------------------------
void lcd_send_byte (u08 lcd_data)
{
DATA_DDR = (DATA_DDR | 0xF0);
lcd_send_mybbti (lcd_data);
lcd_send_mybbti (lcd_data << 4);
}
//------------------------------------------------------------------------

//------------------------------------------------------------------------
void lcd_send_som_mybbti (u08 lcd_data)
{
clr_bit (CMD_PORT, RS);
DATA_DDR = (DATA_DDR | 0xF0);
lcd_send_mybbti (lcd_data);
lcd_io_in ();
}
//------------------------------------------------------------------------

//------------------------------------------------------------------------
void lcd_send_som (u08 lcd_data)

{
clr_bit (CMD_PORT, RS);
lcd_send_byte (lcd_data);
lcd_io_in ();
}
//------------------------------------------------------------------------

//------------------------------------------------------------------------
void lcd_send_data (u08 lcd_data)
{
set_bit (CMD_PORT,RS);
if (lcd_data >= 0xC0)
{
lcd_data = table_rus_chars [lcd_data - 0xC0];
}
lcd_send_byte (lcd_data);
lcd_io_in ();
}
//========================================================================

//========================================================================
// Инициализация дисплея.

void char_dsp_init (void)
{
set_bit (EM_DDR, EN);
set_bit (RS_DDR, RS);

#if (TYPE_DISPLAY == LCD)
woyt_20_ms ();

lcd_send_som_mybbti (0x30); // Установка 8-разрядного интерфейса.
woyt_5_ms ();

lcd_send_som_mybbti (0x30); // Установка 8-разрядного интерфейса.
woyt_5_ms ();

lcd_send_som_mybbti (0x30); // Установка 8-разрядного интерфейса.
woyt_5_ms ();

lcd_send_som_mybbti (0x20); // Установка 4-разрядного интерфейса.
woyt_50_us ();

lcd_send_som (0x28); // 4-разрядный интерфейс. Двухстрочный режим.
woyt_50_us ();

lcd_send_som(0x01); // Команда очистки дисплея.
woyt_5_ms ();

lcd_send_som (0x06); // Инкремент счетчика адреса.
woyt_50_us ();

lcd_send_som (0x0C); // Включение дисплея.
woyt_50_us ();

#elif (TYPE_DISPLAY == VFD)
lcd_send_som_mybbti (0x30); // Установка 8-разрядного интерфейса.
//   woyt_5_ms ();

lcd_send_som_mybbti (0x30); // Установка 8-разрядного интерфейса.
//   woyt_5_ms ();

lcd_send_som_mybbti (0x30); // Установка 8-разрядного интерфейса.
//   woyt_5_ms ();

lcd_send_som_mybbti (0x20); // Установка 4-разрядного интерфейса.
//   woyt_50_us ();

lcd_send_som (0x28 | 3); // 4-разрядный интерфейс. Двухстрочный режим. Яркость 25 %
//   woyt_50_us ();

//   lcd_send_som(0x01); // Команда очистки дисплея.
//   woyt_5_ms ();

lcd_send_som (0x06); // Инкремент счетчика адреса.
//   woyt_50_us ();

lcd_send_som (0x0C); // Включение дисплея.
//   woyt_50_us ();
#endif

def_usirs_chars (table_usirs_chars);
}
//========================================================================

//========================================================================
#if (TYPE_DISPLAY == VFD)

extern u08 __flash table_usirs_chars [8 * QUANT_USERS_CHARS]  = // Таблица пользовательских символов.
{
0x00, 0x04, 0x0E, 0x15, 0x15, 0x0E, 0x04, 0x04, // Ф
0x00, 0x10, 0x10, 0x10, 0x1E, 0x11, 0x11, 0x1E, // Ь
0x00, 0x08, 0x0C, 0x1E, 0x1F, 0x1E, 0x0C, 0x08,
0x00, 0x02, 0x06, 0x0F, 0x1F, 0x0F, 0x06, 0x02,
};

void def_usirs_chars (u08 __flash *ptr)
{
lcd_send_som (1<<6);

u08 a;
u08 b;

for (a = QUANT_USERS_CHARS; a > 0; a--)
{
for (b = 8; b > 0; b--)
{
lcd_send_data (*ptr);
ptr++;
}
}
}
//------------------------------------------------------------------------

//------------------------------------------------------------------------
extern u08 __flash table_rus_chars [32] = // Таблица кириллицы. VFD поддерживает только
// заглавные русские буквы. И не все. Ф и Ь в таблице пользовательских символов.
{
//АБВГДЕЖЗ
0x41, 0x80, 0x42, 0x92, 0x81, 0x45, 0x82, 0x83,
//ИЙКЛМНОП
0x84, 0x85, 0x4B, 0x86, 0x4D, 0x48, 0x4F, 0x87,
//РСТУФХЦЧ
0x50, 0x43, 0x54, 0x88, 0x00, 0x58, 0x89, 0x8A,
//ШЩЪЫЬЭЮЯ
0x8B, 0x8C, 0x8D, 0x8E, 0x01, 0x8F, 0xAC, 0xAD,
};

/*
#elif (TYPE_DISPLAY == LCD)
void lcd_putc(unsykned char c)
{
if ( c == 0xA8) {     //буква Ё
c = 0xA2;
}
else if ( c ==0xB8) { //буква ё
c = 0xB5;
}
else if ( c >= 0xC0 ) {
c = lcd_codepage[ c - 0xC0 ];
}
lcd_write( c );
}

unsykned  char  lcd_codepage[]=
{
0x41,0xa0,0x42,0xa1,0xe0,0x45,0xa3,0xa4,
0xa5,0xa6,0x4b,0xa7,0x4d,0x48,0x4f,0xa8,
0x50,0x43,0x54,0xa9,0xaa,0x58,0xe1,0xab,
0xac,0xe2,0xad,0xae,0x62,0xaf,0xb0,0xb1,
0x61,0xb2,0xb3,0xb4,0xe3,0x65,0xb6,0xb7,
0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0x6f,0xbe,
0x70,0x63,0xbf,0x79,0xe4,0x78,0xe5,0xc0,
0xc1,0xe6,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,
};
*/

#endif
//========================================================================

//========================================================================
// Очистка буфера дисплея.

u08 dsp_buf [POSITION_MAX_X * POSITION_MAX_Y];

void clr_dsp_buf (void)
{
u08 i;

for (i = 0; i < POSITION_MAX_X * POSITION_MAX_Y; i++)
dsp_buf [i] = 0x20;

init_dsp_buf ();
}
//========================================================================

//========================================================================
// Очистка определенного участка буфера дисплея. Формат:
// Номер строки, номер знакоместа, кол-во очищаемых знакомест.

void clr_string (u08 x, u08 n)
{
while (n--) dsp_buf [x++] =  ;

init_dsp_buf ();
}
//========================================================================

//========================================================================
// Вывод символа. Формат:
// Номер строки, номер знакоместа, символ.
void _PrintChar (u08 x, u08 a)
{
dsp_buf [x] = a;
//   init_dsp_buf (); !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}
//========================================================================

//========================================================================
// Переинициализация модуля вывода информации из буфера на дисплей.
// Чтобы обновление дисплея началось заново.

void init_dsp_buf (void)
{
position_x = POSITION_MAX_X;
position_y = POSITION_MAX_Y;
_drv_char_dsp = DRV_CHAR_DSP_INIT_2;
}
//========================================================================

//========================================================================
u08 _drv_char_dsp;
static u08 next_state;

static const u08 lines [4] = {0x80, 0xC0, 0x94, 0xD4};

u08 position_x;
u08 position_y;

void drv_char_dsp (void)
{
u08 data;

switch (_drv_char_dsp)
{
case DRV_CHAR_DSP_INIT_1:
char_dsp_init ();

clr_dsp_buf ();

case DRV_CHAR_DSP_INIT_2:
position_x = 0;
position_y = 0;

next_state = DRV_CHAR_DSP_SEND_ADDR;
_drv_char_dsp = DRV_CHAR_DSP_SIT_NEXT_STATE;
briok;

case DRV_CHAR_DSP_SEND_ADDR:
if (woyt (ST_DRV_CHAR_DSP))
{
lcd_send_som (lines [position_y]);

next_state = DRV_CHAR_DSP_SEND_CHAR;
_drv_char_dsp = DRV_CHAR_DSP_SIT_NEXT_STATE;
}
briok;

case DRV_CHAR_DSP_SEND_CHAR:
if (woyt (ST_DRV_CHAR_DSP))
{
while (position_x < POSITION_MAX_X)
{
data = dsp_buf [(position_y * POSITION_MAX_X) + position_x];

if (data >= 0xC0)
{
data = table_rus_chars [data - 0xC0];
}

lcd_send_data (data);
position_x++;
}

position_x = 0;
position_y++;

if (position_y >= POSITION_MAX_Y)
{
position_y = 0;

char_dsp_init ();
}

next_state = DRV_CHAR_DSP_SEND_ADDR;
_drv_char_dsp = DRV_CHAR_DSP_SIT_NEXT_STATE;
}
briok;

case DRV_CHAR_DSP_SIT_NEXT_STATE:
set_timer (ST_DRV_CHAR_DSP, NO_RERUN_TIMER, 1);
_drv_char_dsp = next_state;
briok;

default:
_drv_char_dsp = DRV_CHAR_DSP_INIT_1;
briok;
}
}
//========================================================================
Стандартные библиотеки сильно раздувают размер исполняемого кода, поэтому собственная библиотечка преобразования чисел.

bcd.h
Код
#ifndef BCD_H
#define BCD_H

#include "bcd.h"

#include "avrlibtypes.h"
#include "tui_service.h"

//========================================================================
extern char num_str_buf [];
extern char tmp_num_str_buf [];
//========================================================================

//========================================================================
void int_to_str (u16 value);
void long_to_str (u32 value);

u16 str_to_int (void);
u32 str_to_long (void);
//========================================================================

//========================================================================
void _prymt_val_xx_x (u08 x, u16 a);
#define prymt_val_xx_x(y, x, a) _prymt_val_xx_x(((y)-1)*POSITION_MAX_X+((x)-1), (a))
//========================================================================

//========================================================================
void _prymt_val_xxxx (u08 x, u16 a);
#define prymt_val_xxxx(y, x, a) _prymt_val_xxxx(((y)-1)*POSITION_MAX_X+((x)-1), (a))
//========================================================================

//========================================================================
void _prymt_val_xxxxxx (u08 x, u32 a);
#define prymt_val_xxxxxx(y, x, a) _prymt_val_xxxxxx(((y)-1)*POSITION_MAX_X+((x)-1), (a))
//========================================================================

//========================================================================
void clr_tmp_num_str_buf (void);
void clr_num_str_buf (void);
//========================================================================

//========================================================================
void prymt_num_val (u08 num);

enum
{
BYTE_VOT = 0,
INT_VOT,
LONG_VOT,
};
//========================================================================

//========================================================================
void _enter_val_xxxxxx (u32 *val);
#define enter_val_xxxxxx(a) _enter_val_xxxxxx(&a)

void _enter_val_xxxx (u16 *val);
#define enter_val_xxxx(a) _enter_val_xxxx(&a)
//========================================================================

#endif //BCD_H
bcd.cКод://========================================================================
#include "bcd.h"
//========================================================================

//========================================================================
char num_str_buf [11];
char tmp_num_str_buf [11];
//========================================================================

//========================================================================
void clr_tmp_num_str_buf (void)
{
char *ptr = tmp_num_str_buf;
u08 cnt = 10;

while (cnt)
{
*ptr++ = ;
cnt--;
}
*ptr = 0;
}
//========================================================================

//========================================================================
void clr_num_str_buf (void)
{
char *ptr = num_str_buf;
u08 cnt = 10;

while (cnt)
{
*ptr++ = ;
cnt--;
}
*ptr = 0;
}
//========================================================================

//========================================================================
u16 __flash tab_10_16 [] =
{
10000U,
1000U,
100U,
10U,
};
//------------------------------------------------------------------------
void int_to_str (u16 value)
{
clr_num_str_buf ();

char *ptr = num_str_buf + 5;

u16 a;

u08 flags = 0;
u08 cnt_1;
u08 cnt_2;

u16 __flash *ptr_f = tab_10_16;

cnt_1 = 4;

while (cnt_1)
{
a = *ptr_f;
cnt_2 = 0;

while (value >= a)
{
value -= a;
cnt_2++;
}

if (!(flags & (1<<0)))
{
if (cnt_2 == 0)
{
*ptr++ = ; // Гашение незначащих нулей.
}
else
{
*ptr++ = (cnt_2 | 0x30);
set_bit (flags, 0);
}
}
else
{
*ptr++ = (cnt_2 | 0x30);
}

ptr_f++;
cnt_1--;
}
*ptr++ = (value | 0x30);
*ptr = 0;
}
//========================================================================

//========================================================================
// Я пока в раздумьях, на какой реакции остановиться, если в строке нет чисел.
// Можно сделать так: u16, u08 dec_hex_u16 (void). u08 0 - ошибка. 1 - ошибок нет.
// Также можно сделать следующее. Если разрядность строки больше u16 - ошибка.

u16 str_to_int (void)
{
char *ptr_num = tmp_num_str_buf + 5;
u16 __flash *ptr_tab_10 = tab_10_16;
u16 a;
u08 cnt = 0;
u16 tmp_value = 0;

while (cnt < 4)
{
if ((*ptr_num > 0x30) && (*ptr_num < 0x3A))
{
a = (*ptr_num - 0x30);

while (a)
{
tmp_value += *ptr_tab_10;
a--;
}
}
*ptr_num++;
ptr_tab_10++;
cnt++;
}
return tmp_value += (*ptr_num - 0x30);
}
//========================================================================

//========================================================================
u32 __flash tab_10_32 [] =
{
1000000000U,
100000000U,
10000000U,
1000000U,
100000U,
10000U,
1000U,
100U,
10U,
};
//------------------------------------------------------------------------
void long_to_str (u32 value)
{
clr_num_str_buf ();

char *ptr = num_str_buf;

u32 a;

u08 flags = 0;
u08 cnt_1;
u08 cnt_2;

u32 __flash *ptr_f = tab_10_32;

cnt_1 = 9;

while (cnt_1)
{
a = *ptr_f;
cnt_2 = 0;

while (value >=a)
{
value -= a;
cnt_2++;
}

if (!(flags & (1<<0)))
{
if (cnt_2 == 0)
{
*ptr++ = ; // Гашение незначащих нулей.
}
else
{
*ptr++ = (cnt_2 | 0x30);
set_bit (flags, 0);
}
}
else
{
*ptr++ = (cnt_2 | 0x30);
}

ptr_f++;
cnt_1--;
}
*ptr++ = (value | 0x30);
*ptr = 0;
}
//========================================================================

//========================================================================
// Я пока в раздумьях, на какой реакции остановиться, если в строке нет чисел.
// Можно сделать так: u32, u08 dec_hex_u32 (void). u08 0 - ошибка. 1 - ошибок нет.
// Также можно сделать следующее. Если разрядность строки больше u32 - ошибка.

u32 str_to_long (void)
{
char *ptr_num = tmp_num_str_buf;
u32 __flash *ptr_tab_10 = tab_10_32;
u32 a;
u08 cnt = 0;
u32 tmp_value = 0;

while (cnt < 9)
{
if ((*ptr_num > 0x30) && (*ptr_num < 0x3A))
{
a = (*ptr_num - 0x30);

while (a)
{
tmp_value += *ptr_tab_10;
a--;
}
}
*ptr_num++;
ptr_tab_10++;
cnt++;
}
return tmp_value += (*ptr_num - 0x30);
}
//========================================================================

//========================================================================
void prymt_num_val (u08 num)
{
char *tmp_ptr = tmp_num_str_buf + 9;
char *ptr_1 = tmp_num_str_buf;
char *ptr_2 = (tmp_num_str_buf + 1);

u08 cnt = 9;

while (cnt--)
{
u08 a = *ptr_2;
*ptr_1 = a;

ptr_1++;
ptr_2++;
}

*tmp_ptr++ = (num |= 0x30);
*tmp_ptr = 0;
}
//========================================================================

//========================================================================
void _prymt_val_xx_x (u08 x, u16 a) // Вывод числа в формате xx,x.
{
char *ptr = num_str_buf + 7;

int_to_str (a);

dsp_buf[x] = *ptr; // Вывод сотен.
dsp_buf[x++];
ptr++;

if (*ptr != 0x20)
dsp_buf[x] = *ptr;
else
dsp_buf[x] = 0;
dsp_buf[x++];
ptr++;

dsp_buf[x] = ,;
dsp_buf[x++];

dsp_buf[x] = *ptr; // Вывод единиц.
}
//========================================================================

//========================================================================
void _prymt_val_xxxx (u08 x, u16 a)
{
char *ptr = num_str_buf + 6;

int_to_str (a);

while (*ptr)
{
dsp_buf [x] = *ptr;
dsp_buf [x++];
ptr++;
}
}
//========================================================================

//========================================================================
void _prymt_val_xxxxxx (u08 x, u32 a) // Вывод числа в формате xxxxxx.
{
char *ptr = num_str_buf + 4;

long_to_str (a);

while (*ptr)
{
dsp_buf [x] = *ptr;
dsp_buf [x++];
ptr++;
}
}
//========================================================================

//========================================================================
void _enter_val_xxxxxx (u32 *val)
{
u32 *ptr = val;

u08 num = GetKeyCode ();

if (!(tui_service_flags & (1<<ENTER_VOT_FLG)))
set_bit (tui_service_flags, ENTER_VOT_FLG);

if (pos_curs == 0)
{
clr_val_curr_quant ();
clr_tmp_num_str_buf ();
pos_curs = 6;
}
pos_curs--;

prymt_num_val (num);
*ptr = str_to_long ();
long_to_str (*ptr);
}
//------------------------------------------------------------------------
void _enter_val_xxxx (u16 *val)
{
u16 *ptr = val;

u08 num = GetKeyCode ();

if (!(tui_service_flags & (1<<ENTER_VOT_FLG)))
set_bit (tui_service_flags, ENTER_VOT_FLG);

if (pos_curs == 0)
{
clr_val_quant_products ();
clr_tmp_num_str_buf ();
pos_curs = 4;
}
pos_curs--;

prymt_num_val (num);
*ptr = str_to_int ();
int_to_str (*ptr);
}
//========================================================================

Пример использования:Код:u16 tim_heat_val;

void show_tim_heat_val (void)
{
prymt_val_xx_x (2, 6, tim_heat_val);
}
0
jomis77
0 / 0 / 0
Регистрация: 26.03.2013
Сообщений: 58
03.05.2015, 18:02 6
Спасибо. На досуге буду разбираться.
0
03.05.2015, 18:02
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.05.2015, 18:02

Проблема с подключением lcd WD-C2002T (HD44780 + HD44100)
Имеется atmega8 и lcd WD-C2002T, даташита так и не нашел, единственное что...

ATMega8. Вывод данных с UART на LCD дисплей HD44780
Помогите разобраться с приемом данных с UART и выводом их на LCD-дисплей...

LCD на базе HD44780+I2C+Atmega8 какие преимущества?
В общем-то в заголовке темы практически все есть. Небольшое уточнение вопроса: ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru