Ср авг 31, 2022 04:57:23
А, может быть, дойдут? Как-то кажется, что, хотя бы частоту, энкодером менять проще..forregister84 писал(а):До энкодера руки не дошли.
Ср авг 31, 2022 19:05:25
Чт сен 01, 2022 09:11:00
Вс сен 04, 2022 20:41:24
Пн сен 12, 2022 11:29:04
Пн сен 12, 2022 22:16:19
Пн сен 12, 2022 22:43:49
Вт сен 13, 2022 06:15:48
Дребезг значительно уменьшается при уменьшении номиналов R3...R9 до 1...3кОм чтобы привести в соответствие с типовыми характеристиками на контактные энсодеры.forregister84 писал(а):...1 энкодер нормальный, второй с очень сильным дребезгом. Подтяжка 10 кОм + фильтр 10 кОм + 47 нФ...
Вт сен 13, 2022 17:36:34
Ср сен 14, 2022 16:17:11
Ср сен 14, 2022 16:52:20
Пт сен 16, 2022 17:22:18
Вс сен 18, 2022 22:22:56
Чт сен 22, 2022 21:55:42
Вс сен 25, 2022 12:22:58
Вс окт 02, 2022 12:12:34
Пн окт 03, 2022 16:15:00
Вт окт 25, 2022 16:03:52
Ср окт 26, 2022 18:33:02
#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;
}
//==================
Ср окт 26, 2022 19:01:13
весь цикл занимает 84 мс.