Как оптимизировать использование функций?

Обсуждаем контроллеры компании Atmel.
Ответить
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

[uquote="Morroc",url="/forum/viewtopic.php?p=4211356#p4211356"][uquote="Land",url="/forum/viewtopic.php?p=4211295#p4211295"]
на мой взгляд у вас в принципе подход не тот. если хотите оптимизировать - делайте одну универсальную функцию для ввода данных, другую универсальную для отрисовки экрана, конечный автомат для управления тем что вводим в данный момент и т.д.[/uquote]
Вот я как бы об этом и спрашиваю. Как написать универсальную функцию для ввода данных, если все, что описано в первом посте имеет место быть.

Добавлено after 1 minute 29 seconds:
[uquote="veso74",url="/forum/viewtopic.php?p=4211359#p4211359"]Morroc, он, вероятно, пытается это сделать, и у него, вероятно, возникают трудности с передачей string на универсальную функцию.[/uquote]
именно. Формат вывода данных меняется от функции к функции
Реклама
Друг Кота
Сообщения: 19495
Зарегистрирован: Чт фев 20, 2014 18:57:55

Сообщение Morroc »

/del
Последний раз редактировалось Morroc Пт апр 08, 2022 15:49:37, всего редактировалось 2 раза.
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Реклама
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

как-то так?

Код: Выделить всё

const char format1[] = "%i/%i/20%02i";
	const char format2[] = "%02i:%02i:%02i";
	const char format3[] = "%i";

char settinng_par (char *str, char min_x, char max_x, signed char x, signed char y, signed char z )
и потом settinng_par( format1, 1, 31, x, y, z);

Ззараза... ломается вывод ( кракозябры идут

Добавлено after 1 minute 23 seconds:
[uquote="Morroc",url="/forum/viewtopic.php?p=4211368#p4211368"]Я бы так не делал как он пытается, то передача строк дело тоже полезное )[/uquote]
ну и как бы вы делали? Зело любопытно, можно пример для первых двух функций в первом сообщении?
Друг Кота
Сообщения: 19495
Зарегистрирован: Чт фев 20, 2014 18:57:55

Сообщение Morroc »

Для этого стоит взглянуть на всю программу. Читали про конечные автоматы ? Допустим у вас не будет выделенной функции для ввода конкретных параметров, но будет конечный автомат, который обрабатывает нажатия кнопок в зависимости от текущего состояния системы. Преимущество такого построения программы - это что то вроде многозадачности, у вас автоматически не будет проблем принять какие то данные с порта или динамическую индикацию крутить на светодиодах и т.п. (ну разве что в моменты перерисовки lcd будет небольшая блокировка). Вы же сейчас залетаете в эти ваши функции и пока они не отработают ничего больше не выполняется, так ?
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Реклама
Эиком - электронные компоненты и радиодетали
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

Morroc, ну почему же ничего больше не выполняется? часики тикают, кнопки опрашиваются. И собственно все работает. Если бы не размер получающейся прошивки -- меня бы все устроило.
Реклама
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Это из темы микроменю? И какой размер прошивки?
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 362
Зарегистрирован: Вс апр 03, 2022 07:01:29

Сообщение НовыйДень »

Изучите и используйте указатели на функции и массивы этих указателей на функции. В зависимости от текущей отображаемой на дисплее информации меняются назначения функций кнопок с помощью указателей на функции.
Операции ввода чисел вообще не привязаны к функциям даты или времени или чего-то иного. Если ввод чисел реализован кнопками + и -, то функции этих кнопок просто инкрементируют или декрементируют значение, считываемое по указателю. Опять же, во всей этой байде активно используются указатели - на переменные, на функции.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Не стал все расписывать, но, как-то так
Спойлер

Код: Выделить всё

	typedef const struct Menu_Item {
		const struct Menu_Item *Next; 
		const struct Menu_Item *Previous; 
		const struct Menu_Item *Parent; 
		const struct Menu_Item *Child; 
		void (*SelectCallback)(void);
	} Menu_Item_t;

	#define MENU_ITEM(Name, Next, Previous, Parent, Child, SelectFunc) \
		extern Menu_Item_t const Next;     \
		extern Menu_Item_t const Previous; \
		extern Menu_Item_t const Parent;   \
		extern Menu_Item_t const Child;  \
                Menu_Item_t const Name = {&Next, &Previous, &Parent, &Child, SelectFunc}
				
Menu_Item_t NULL_MENU = {0};

static Menu_Item_t* CurrentMenuItem = &NULL_MENU;

Menu_Item_t* Menu_GetCurrentMenu(void)
{
	return CurrentMenuItem;
}

void Menu_Navigate(Menu_Item_t* const NewMenu)
{
	if ((NewMenu == &NULL_MENU) || (NewMenu == NULL))
		return;
	CurrentMenuItem = NewMenu;
}


// Menus	Name	| Next	| Prev	| Parent	| Child	| SelectFunction
MENU_ITEM(m_0, m_1, m_4, null_menu, null_menu, day_of_month_Select);		// day_of_month_Select
MENU_ITEM(m_1, m_2, m_0, null_menu, null_menu, month_Select);				// month_Select
MENU_ITEM(m_2, m_3, m_1, null_menu, null_menu, year_Select);				// year_Select
MENU_ITEM(m_3, m_4, m_2, null_menu, null_menu, day_Select);					// day_Select
MENU_ITEM(m_4, m_0, m_3, null_menu, null_menu, hours_Select);				// hours_Select

volatile Menu_Item_t* menu = &NULL_MENU;
void (*id)(void);

interrupt{
	currentMillis++;
   	if((currentMillis - previousMillis) > 500){
		previousMillis = currentMillis;
		blink = !blink;
	}
}

int main(void)
{

	Menu_Navigate(&m_0);

    while(1)
    {
	
		skan_key();				//читаем значение кнопок
	
		if (BUTTON == BUTTON_RIGHT) {
			lcd_clear();//очистка LCD и перевод курсора в 0.0
			Menu_Navigate(MENU_NEXT);
		}
	
		if (BUTTON == BUTTON_LEFT) {
			lcd_clear();
			Menu_Navigate(MENU_PREVIOUS);
		}	

		if (BUTTON == BUTTON_UP) {
			if(id == day_of_month_Select) 	{ if(++day > 31) day = 1; }
			if(id == month_Select) 			{ if(++month > 12) month = 1; }
			if(id == year_Select) 			{ ++year; }
			if(id == day_Select) 			{ if(++day_n > 7) day_n = 1; }
			if(id == hours_Select) 			{ if(++hours > 23) hours = 0; }
		}

		if (BUTTON == BUTTON_DOWN) {
			if(id == day_of_month_Select) 	{ if(--day < 1) day = 31; }
			if(id == month_Select) 			{ if(--month < 1) month = 12; }
			if(id == year_Select) 			{ if(--year < 22) year = 22; }
			if(id == day_Select) 			{ if(--day_n < 22) day_n = 22; }
			if(id == hours_Select) 			{ if(--hours < 0) hours = 23; }
		}
	
		menu = Menu_GetCurrentMenu();
		id = menu->SelectCallback;
	
		void(*SelectCallback)(void) = menu->SelectCallback;
		if (SelectCallback)	SelectCallback();
									
    }

}

/** выбор меню числа месяца */
static void day_of_month_Select(void)
{
	lcd_gotoxy (0,1);
	if (blink) 
	dsprintf(string, "%02i/%02i/20%02i", day, month, year);
	else
	dsprintf(string, "  /%02i/20%02i", month, year);
	lcd_str_out(string);
}

/** выбор меню месяца */
static void month_Select(void)
{
	lcd_gotoxy (0,1);
	if (blink) 
	dsprintf(string, "%02i/%02i/20%02i", day, month, year);
	else
	dsprintf(string, "%02i/  /20%02i", day, year);
	lcd_str_out(string);
}

/** выбор меню год */
static void year_Select(void)
{
	lcd_gotoxy (0,1);
	if (blink) 
	dsprintf(string, "%02i/%02i/20%02i", day, month, year);
	else
	dsprintf(string, "%02i/%02i/20  ", day, month);
	lcd_str_out(string);
}

/** выбор меню дня недели */
static void day_Select(void)
{
	lcd_gotoxy (0,1);
	if (blink) 
	dsprintf(string, "%02i", day_n);
	else
	dsprintf(string, "  ");
	lcd_str_out(string);   
}

/** выбор меню часа */
static void hours_Select(void)
{
   ds3231_read_time(time);
   // Вывести время
   	lcd_gotoxy (0,1);
	if (blink) 
	dsprintf(string, "%02i:%02i:%02i", hours, time[1], time[2]);
	else
	dsprintf(string, "  :%02i:%02i", time[1], time[2]);
	lcd_str_out(string); 
}

Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

Dimon456, спасибо большое, с кодом стало понятно. Плюсануть не могу по объективным причинам, уж извините )
Друг Кота
Аватара пользователя
Сообщения: 6321
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

[uquote="OKF",url="/forum/viewtopic.php?p=4211340#p4211340"]Ибо компиляторы сейчас продвинутые[/uquote]
С этим соглашусь.
результирующий код выдают не хуже вашего ассемблера
А вот тут позвольте усомниться. Для конкретной программы в конкретных условиях, полагаю, хороший программер сможет "утоптать" прогу процентов на 10.
Правда сейчас, когда МК по объёму памяти и быстродействию легко уделывают МиниЭВМ 30-летней давности - борьба за байты выглядит неактуальной. Но кто знает, что там за горизонтом...
Изображение
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 362
Зарегистрирован: Вс апр 03, 2022 07:01:29

Сообщение НовыйДень »

Тут вот один мой знакомый пытается на правоверном ассемблере прогать басурманские STM32H7. Месяца полтора уже бьется, а воз и ныне там, едва таймер научился запускать. А вы говорите - ассемблер, ассемблер...
Друг Кота
Аватара пользователя
Сообщения: 6321
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

Почти кстати:
У В.Маяковского на встрече с читателями один вьюноша ему говорит:
-Мы вот с товарищем читали Ваши стихи и ничего не поняли.
-Нужно было читать с умным товарищем - ответил В.В.
Я сам с STMовскими камнями дел не имел, поэтому мне трудно судить. И если представляется удобная среда программирования на ЯВУ - может, действительно, не стоит браться за асм ввиду гигантских ресурсов STM. Мы же в этой теме говорим о конкретной линии МК - Атмел.
СпойлерПомню, я на заре своей программерской биографии :) смотрел на знающих асм IBM-360 снизу вверх: надо же, они знают тайный смысл заклинания BALR - USING ! Хотя сам к тому времени свободно кодил на Алгол-60, Фортран и PL-I. Но однажды пришлось. Потыркался малость - и простыня листинга метра полтора - заработала. С той поры у меня в активе с полдюжины разных асмов.
Не боги горшки обжигают.
Изображение
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44

Сообщение Demiurg »

[uquote="veso74",url="/forum/viewtopic.php?p=4211244#p4211244"]3. На C выход из цикла через break не "самый красивый". Попробуйте написать по другому.[/uquote]
Аргументы, примеры. Лично я безо всяких душевных терзаний часто использую break.

Можно сделать так. Пусть у нас символьный дисплей. Создаем буфер в ОЗУ. Размер буфера зависит от кол-ва строк и символов в строке. Скажем, у нас дисплей 20х4. Значит размер буфера будет 80 байтов. Так как дисплей медленный, мы делаем следующее: отныне пишем в буфер дисплея. Создаем программный таймер настроенный на 1 мс. И каждую мс в зависимости от состояния обработчика дисплея отправляем либо адрес текущей строки, либо символ из буфера дисплея. Полное обновление дисплея происходит, в случае 20х4, за 84 мс, 80 символов, плюс 4 адреса строк.

char_display.h:
Спойлер

Код: Выделить всё

#ifndef CHAR_DISPLAY_H

#define CHAR_DISPLAY_H

#include "char_display.h"

#include "main_def_func.h"

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

// Тип дисплея. ЖКИ LCD или вакуумно-люминесцентный VFD.
#define TYPE_DISPLAY    VFD // LCD // 
//==================

//==================
// LCD Data Port
#define DATA_PORT       PORTC
#define DATA_PIN        PINC
#define DATA_DDR        DDRC

// LCD Control Port
#define CMD_PORT        PORTC
#define CMD_PIN         PINC
#define CMD_DDR         DDRC

// Строб.
#define EN_PORT         PORTC
#define EN_DDR          DDRC

#define EN              2

// Команда\данные.
#define RS_PORT         PORTC
#define RS_DDR          DDRC

#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 bright; // Значение яркости VFD.
// 3 - 25%
// 2 - 75%
// 1 - 50%
// 0 - 100%
#endif
//==================

//==================
#define QUANT_USERS_CHARS 4

#define ARROW_RIGHT 2
#define ARROW_LEFT 3
//==================

//==================
void lcd_io_in (void);
void lcd_send_nibble (u08 lcd_data);
void lcd_send_byte (u08 lcd_data);
void lcd_send_com_nibble (u08 lcd_data);
void lcd_send_com (u08 lcd_data);
void lcd_send_data (u08 lcd_data);
//==================

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

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

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

extern char 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)
//==================

//==================
#ifdef __PROJECT_MODE_WORK__
#define DSP_INIT_TIME 40
#endif

#ifdef __PROJECT_MODE_DEBUG__
#define DSP_INIT_TIME 4
#endif
//==================

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

extern void init_dsp_buf (void);
//==================

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

//==================
extern u08 __flash string_azbuka [];

void test_out_text (void);
//==================

//==================
enum
{
   DRV_CHAR_DSP_INIT_1 = 0,
   DRV_CHAR_DSP_INIT_2,
   DRV_CHAR_DSP_SEND_ADDR,
   DRV_CHAR_DSP_SEND_CHAR,
};
//------------------------------------------------------------------------
void drv_char_dsp (void);

void drv_char_dsp_init_1 (void);
void drv_char_dsp_init_2 (void);
void drv_char_dsp_send_addr (void);
void drv_char_dsp_send_char (void);
//------------------------------------------------------------------------
u08 get_char_dsp_state (void);
//==================

#endif
Спойлер

Код: Выделить всё

//==================
#include "char_display.h"
//==================

//==================
// Алгоритм работы модуля дисплея:
// Есть буфер дисплея. Размер буфера равен кол-во символов*кол-во строк.
// Обновление дисплея осуществляется посимвольно, раз в 1 мс. Полное
// обновление дисплея происходит за
// кол-во символов*кол-во строк + кол-во строк (адреса строк).
// Если дисплей 20х4, то полное обновление происходит за 20*4+4=84 мс.
//==================

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

static u08 position_x;
static u08 position_y;

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

   static soft_timer ST_DRV_CHAR_DSP;
//==================

//==================
#if (TYPE_DISPLAY == LCD)

u08 __flash table_rus_chars [64] =
{
  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,
};

u08 __flash string_azbuka [] = "абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";

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

#elif (TYPE_DISPLAY == VFD)

u08 __flash table_users_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,
};
//------------------------------------------------------------------------

//------------------------------------------------------------------------
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,
};

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

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

//------------------------------------------------------------------------
void lcd_send_nibble (u08 lcd_data)
{
   set_bit (CMD_PORT, EN);
   DATA_PORT = (DATA_PORT & 0x0F) | (lcd_data & 0xF0);
   asm("rjmp ($/2+1)*2"); // Такой своеобразный ассемблер в IAR/
   asm("rjmp ($/2+1)*2");
   asm("rjmp ($/2+1)*2");
   asm("rjmp ($/2+1)*2");
   asm("rjmp ($/2+1)*2");
   clr_bit (CMD_PORT, EN);
   asm("rjmp ($/2+1)*2");
   asm("rjmp ($/2+1)*2");
   asm("rjmp ($/2+1)*2");
   asm("rjmp ($/2+1)*2");
   asm("rjmp ($/2+1)*2");
}
//------------------------------------------------------------------------

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

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

//------------------------------------------------------------------------
void lcd_send_com (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 (TYPE_DISPLAY == LCD)
      if (lcd_data == 0xA8)
      {
         lcd_data = 0xA2; //буква 'Ё' 
      }
      else if (lcd_data ==0xB8)
      {
         lcd_data = 0xB5; //буква 'ё'
      }
#endif

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

   lcd_send_byte (lcd_data);
   lcd_io_in ();
}
//==================

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

bool char_dsp_init (void)
{
   static u08 _char_dsp_init;

#if (TYPE_DISPLAY == LCD)
   static u08 cnt;
#endif

   switch (_char_dsp_init)
   {
      case 0:
         set_soft_timer (ST_DRV_CHAR_DSP, DSP_INIT_TIME, 0); // Задержка. Повтора нет.
         _char_dsp_init = 1;
         return false;

      case 1:
         if (handle_soft_timer (ST_DRV_CHAR_DSP))
         {
            set_bit (EN_DDR, EN);
            set_bit (RS_DDR, RS);

#if (TYPE_DISPLAY == LCD)
            cnt = 0;

            set_soft_timer (ST_DRV_CHAR_DSP, 0, 5); // Немедленное исполнение, последующая задержка 5 мс.
            _char_dsp_init = 2;

#elif (TYPE_DISPLAY == VFD)

            // Так как VFD работает быстро, задержки не нужны.
            for (u08 i = 3; i > 0; i--)
            {
               lcd_send_com_nibble (0x30); // Установка 8-разрядного интерфейса.
            }

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

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

            lcd_send_com (0x06); // Инкремент счетчика адреса.
            lcd_send_com (0x0C); // Включение дисплея.

            def_users_chars (table_users_chars);

            return true;
#endif
         }
         return false;

#if (TYPE_DISPLAY == LCD)
      case 2:
         if (handle_soft_timer (ST_DRV_CHAR_DSP))
         {
            if (cnt < 3)
            {
               lcd_send_com_nibble (0x30); // Установка 8-разрядного интерфейса.
               cnt++;
               return false;
            }

            if (cnt == 3)
            {
               lcd_send_com_nibble (0x20); // Установка 4-разрядного интерфейса.
               delay_us (50);

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

               lcd_send_com(0x01); // Команда очистки дисплея.
               cnt++;
               return false;
            }

            if (cnt == 4)
            {
               lcd_send_com (0x06); // Инкремент счетчика адреса.
               delay_us (50);

               lcd_send_com (0x0C); // Включение дисплея.
               delay_us (50);
               return true;
            }
         }
         return false;
#endif
   }

   return false;
}
//==================

//==================
void def_users_chars (u08 __flash *ptr)
{
   lcd_send_com (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++;

#if (TYPE_DISPLAY == LCD)
         delay_us (50);
#endif

      }
   }
}
//==================

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

char 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 init_dsp_buf (void)
{
   _drv_char_dsp = DRV_CHAR_DSP_INIT_2;
}
//==================

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

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

   init_dsp_buf (); // Переинициализация модуля дисплея.
}
//==================

//==================
//void test_out_text (void)
//{
/*
// Тестовый вывод текста в буфер.
// Вариант 1 вывода текста.
u08 i = 0;
u08 j = 0;

while (string_azbuka [j])
{
   dsp_buf [i++] = string_azbuka [j++];
}

clr_dsp_buf ();
*/
//------------------------------------------------------------------------
// Вариант 2 вывода текста.
// Примечание: в параметрах функции Print_Buf количество символов не должно
// превышать кол-ва символов на строку. Но в данном случае точно известно,
// что позиция первого символа начинается с нулевого адреса буфера дисплея
// и кол-во символов не превышает 20*4.

//Print_Buf (1, 1, "абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ");

//      Print_Buf (1, 1, "абвгдеёжзийклмнопрст");
//      Print_Buf (1, 2, "уфхцчшщъыьэюяАБВГДЕЁ");
//      Print_Buf (1, 3, "ЖЗИЙКЛМНОПРСТУФХЦЧШЩ");
//      Print_Buf (1, 4, "ЪЫЬЭЮЯ");
//}
//==================

//==================
void drv_char_dsp (void)
{
   u08 data;

   switch (_drv_char_dsp)
   {
      case DRV_CHAR_DSP_INIT_1:
         if (char_dsp_init ())
         {
            clr_dsp_buf ();
            Set_Event (EV_ID_CHAR_DSP_RUN, USER_EVENT);
            _drv_char_dsp = DRV_CHAR_DSP_INIT_2;
         }
         break;

      case DRV_CHAR_DSP_INIT_2:
         position_x = 0;
         position_y = 0;

         set_soft_timer (ST_DRV_CHAR_DSP, 0, 1); // Немедленное исполнение. Повтор.

         _drv_char_dsp = DRV_CHAR_DSP_SEND_ADDR;
         break;

      case DRV_CHAR_DSP_SEND_ADDR:
         if (handle_soft_timer (ST_DRV_CHAR_DSP))
         {
            lcd_send_com (lines [position_y]);
            _drv_char_dsp = DRV_CHAR_DSP_SEND_CHAR;
         }
         break;

      case DRV_CHAR_DSP_SEND_CHAR:
         if (handle_soft_timer (ST_DRV_CHAR_DSP))
         {
         #if (TYPE_DISPLAY == LCD)
            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++;

            if (position_x >= POSITION_MAX_X)
            {
               position_x = 0;

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

               _drv_char_dsp = DRV_CHAR_DSP_SEND_ADDR;
            }

         #elif (TYPE_DISPLAY == VFD)
            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 (); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            }

            _drv_char_dsp = DRV_CHAR_DSP_SEND_ADDR;

         #endif
         }
         break;
   }
}
//==================

//==================
u08 get_char_dsp_state (void)
{
   return _drv_char_dsp;
}
//==================
Это сообщение буду пополнять.
Контактная информация:
nds
Друг Кота
Аватара пользователя
Сообщения: 4766
Зарегистрирован: Вс май 25, 2008 19:47:47
Откуда: РФ

Сообщение nds »

[uquote="Dimon456",url="/forum/viewtopic.php?p=4211567#p4211567"]Не стал все расписывать, но, как-то так[/uquote]
имхо полтора килобайта на этом не утопчешь
попробуй эксперимента ради оставить все функции пустыми и посмотреть результирующий размер.

Тут нужно смотреть весь код целиком включая библиотечные функции
2B OR NOT 2B = FF
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA

Сообщение GoldenAndy »

Рискну произнести крамолу, но я бы отказался от printf.
И сделал бы отдельной функцией преобразование байта в 2 ASCII символа. Значений же выше 99 там нет. И формировани е строки для отправки в дисплей - тоже ручками, с использованием этой функции. Без всяких форматных строк. Задача ж не универсальный вывод всего, а конкретные форматы.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Контактная информация:
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44

Сообщение Demiurg »

Плюсую. Именно этим в том числе я собирался дополнить свое сообщение. Отказаться от библиотечных print.
Контактная информация:
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

nds писал(а):попробуй эксперимента ради оставить все функции пустыми и посмотреть результирующий размер.

Код: Выделить всё

 431 bytes of CODE memory (+ 6 bytes shared)
  71 bytes of DATA memory
И в чем проблема?
Demiurg писал(а):Отказаться от библиотечных print.
print универсальный форматный вывод.
1,5-2 кило кода, вы столько же потратите на изобретение вашего кода, пусть даже и конкретные форматы. Код в студию.
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44

Сообщение Demiurg »

[uquote="Dimon456",url="/forum/viewtopic.php?p=4212440#p4212440"]print универсальный форматный вывод.
1,5-2 кило кода, вы столько же потратите на изобретение вашего кода, пусть даже и конкретные форматы. Код в студию.[/uquote]
У меня по конкретным проектам конкретные решения. Просто добавление print и даже единичное использование в проекте сразу добавляет места, пару-тройку килобайт.
Контактная информация:
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Код в студию.

Добавлено after 8 minutes 55 seconds:
Demiurg, на тебе вводную

Код: Выделить всё

	lcd_gotoxy (0,1);
	dsprintf(string, "%02i/%02i/20%02i", day, month, year);
	lcd_str_out(string);
раздербань его на составляющие.
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 362
Зарегистрирован: Вс апр 03, 2022 07:01:29

Сообщение НовыйДень »

Если не нужен универсальный форматированный вывод, можно смело заменить либо самописной реализацией, либо облегченной версией tiny_printf. Хотя в мощных МК библиотечный универсальный printf весьма неплох, особенно в расширенной версии - выравнивание чисел влево или вправо, лидирующие нули, десятичная запятая, отрицательные числа, экспоненциальный формат, хекс-форма чисел.
Ответить

Вернуться в «AVR»