ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Суббота
23 ноября
269434
mazur (30.08.2011 15:25 - 27.09.2011 20:35, просмотров: 50638)
Поправил. Может кому интересно будет. Мне нужно было, чтобы дисплей быстро обновлялся. Чего я и добился. Обновление VFD можно спокойно сделать следующим образом: Каруселька. В карусельку вставить вызов подпрограммы обновления дисплея. В данный момент выложил для VFD. Для LCD потом как-нибудь поправлю. Но принцип и так ясен. ;========================================================================= #define CHAR_LCD_8_BITS 0 #define CHAR_LCD_4_BITS 1 ;------------------------------------------------------------------------- .def LCD_DATA = r17 .equ DATA_PORT = PORTC ; LCD Data Port .equ DATA_PIN = PINC .equ DATA_DDR = DDRC .equ CMD_PORT = PORTC ; LCD Control Port .equ CMD_PIN = PINC .equ CMD_DDR = DDRC .equ Ena = 1 .equ RS = 2 .equ MAX_CHARS = 20 ; Количество символов в строке. .equ MAX_LINES = 4 ; Количество строк дисплея. .equ LINE_0 = 0x80 ; Адрес первой строки. .equ LINE_1 = 0xC0 ; Адрес второй строки. .equ LINE_2 = 0x94 ; Адрес третьей строки. .equ LINE_3 = 0xD4 ; Адрес четвертой строки. .dseg ;========================================================================= Def_Num_Error _EEROR_READ_BUF_VALUE_BRIGHT ; Ошибка чтения значения яркости. BRIGHT_BUF: ; Значение яркости VFD. .byte 1 ; 3 - 25% ; 2 - 75% ; 1 - 50% ; 0 - 100% ;========================================================================= DRV_LCD_FLAGS: ; Флаги обрабтчика .byte 1 .equ DRV_LCD_RUN_FLG = 0 ; Флаг запуска обработчика дисплея. .equ SEND_CHAR_FLG = 1 ; Флаг отправки символа. CNT_LCD_LINES: ; Счетчик количества строк. .byte 1 CNT_LCD_CHARS: ; Счетчик количества символов. .byte 1 ; Смещения на переменные обработчика дисплея. .equ DISP_DRV_LCD_FLAGS = 0 .equ DISP_CNT_LCD_LINES = 1 .equ DISP_CNT_LCD_CHARS = 2 NUL_BUFFER: ; Для отладки программы. Чтобы в AVR-Studio показывало как на дисплее. .byte 3 DSP_BUF: ; Буфер дисплея. .equ DSP_BUF_SIZE = MAX_CHARS*MAX_LINES .byte DSP_BUF_SIZE #define LINE_BUF_1 DSP_BUF #define LINE_BUF_2 DSP_BUF+MAX_CHARS #define LINE_BUF_3 DSP_BUF+(MAX_CHARS*2) #define LINE_BUF_4 DSP_BUF+(MAX_CHARS*3) .cseg Init_Display: ; Инициализация дисплея. #if (TYPE_DISPLAY==VFD_4_BITS) ldi LCD_DATA,0x30 rcall Send_Com_Init ldi LCD_DATA,0x30 rcall Send_Com_Init ldi LCD_DATA,0x30 rcall Send_Com_Init ldi LCD_Data,$20 rcall Send_Com_Init lds LCD_Data,BRIGHT_BUF ; Считывание значения яркости. cpi LCD_DATA,4 brsh Error_Read_Buf_Value_Bright ori LCD_DATA,0x28 rcall Send_Com ldi LCD_Data,$01 rcall Send_Com ldi LCD_Data,$06 rcall Send_Com ldi LCD_Data,$0C Send_Com: cbi CMD_PORT,RS rjmp Send_Byte Data_Port_Out: in r16,Data_DDR ori r16,0xF0 out Data_DDR,r16 ret Send_Data: sbi CMD_PORT,RS rjmp Send_Byte ret Send_Com_Init: cbi CMD_PORT,RS Send_Nibble: rcall Data_Port_Out in r16,DATA_PORT andi r16,0x0F rjmp Send_Nibble_1 Send_Byte: rcall Data_Port_Out ; Порт данных-выход. in r16,DATA_PORT andi r16,0x0F eor r16,LCD_DATA andi LCD_DATA,0x0F eor r16,LCD_DATA out DATA_PORT,r16 sbi CMD_PORT,Ena rcall Empty_Action cbi CMD_PORT,Ena andi r16,0x0F swap LCD_DATA Send_Nibble_1: andi LCD_DATA,0xF0 or r16,LCD_DATA out DATA_PORT,r16 sbi CMD_PORT,Ena rcall Empty_Action cbi CMD_PORT,Ena Data_Port_In: in r16,Data_DDR andi r16,0x0F out Data_DDR,r16 in r16,Data_Port andi r16,0x0F out Data_Port,r16 ret #endif Error_Read_Buf_Value_Bright: Write_Errors_Code _EEROR_READ_BUF_VALUE_BRIGHT rjmp Process_Errors DRV_LCD: ldiy DRV_LCD_FLAGS ; Указатель на переменные обработчика дисплея. ldd FLAGS,Y+DISP_DRV_LCD_FLAGS ; Считывание флагов обработчика дисплея. sbrc FLAGS,DRV_LCD_RUN_FLG ; Если установлен флаг запуска обработчика rjmp DRV_LCD_Run ; то переход. sbr FLAGS,1<<DRV_LCD_RUN_FLG ; Установка флага запуска обработчика. rcall Clear_DSP_BUF ; Очистка буфера дисплея (символ пробела). rcall Init_Display ; Инициализация дисплея. rcall Def_Users_Chars ; Считывание пользовательских символов. ; ret DRV_LCD_Run: ldd r18,Y+DISP_CNT_LCD_LINES ; Считывание счетчика строк. ldd r19,Y+DISP_CNT_LCD_CHARS ; Считывание счетчика символов. sbrs FLAGS,SEND_CHAR_FLG ; Если сброшен флаг отправки символа, rcall DRV_LCD_Send_Addr ; то переход на отправку адреса строки. DRV_LCD_Send_Char: ; Отправка символа. ldix DSP_BUF ; Указатель на буфер дисплея. ldi r16,MAX_CHARS ; Количество символов в строке. mul r16,r18 addw X,r0,r1 ; Смещение на нужную строку addw X,r19,RCLR ; Смещение на нужный символ. ld LCD_DATA,X ; Считывание символа. rcall Send_Data inc r19 ; Инкремент счетчика символов. cpi r19,MAX_CHARS ; Проверка на переполнение количества символов. brlo Save_Cnt_Send_Char ; Если меньше, то переход на сохранение счетчика символов. Clr_Cnt_Send_Char: clr r19 ; Сброс счетчика символов. cbr FLAGS,1<<SEND_CHAR_FLG ; Сброс флага отправки символов. inc r18 ; Инкремент счетчика строк. cpi r18,MAX_LINES ; Проверка на переполнение количества строк. brlo Save_Cnt_Send_Addr ; Если меньше, то переход на сохранение счетчика строк. Clr_Cnt_Send_Addr: clr r18 ; Сброс счетчика строк. Save_Cnt_Send_Addr: std Y+DISP_CNT_LCD_LINES,r18 ; Сохранение счетчика строк. Save_Cnt_Send_Char: std Y+DISP_CNT_LCD_CHARS,r19 ; Сохранение счетчика символов. Send_Char_End: std Y+DISP_DRV_LCD_FLAGS,FLAGS ; Сохранение флагов обработчика дисплея. ret DRV_LCD_Send_Addr: ; Отправка адреса строки. В r18 номер строки. ldiz Table_LCD_Line_Addr*2 ; Указатель на таблицу адресов строк. addw Z,r18,RCLR ; Смещение на номер строки. lpm LCD_DATA,Z ; Считывание номера строки. rcall Send_Com sbr FLAGS,1<<SEND_CHAR_FLG ; Установка флага вывода символов. ret Def_Users_Chars: ; Функция определения пользовательских символов. ldi LCD_DATA,1<<6 ; CGRAM rcall Send_Com ldiz TABLE_USERS_CHARS*2 ; Указатель на начало таблицы пользовательских символов. ldi r19,3 ; Количество пользовательских символов. Def_Users_Chars_Cycle: ldi r18,8 Def_Users_Chars_Cycle_0: lpm LCD_DATA,Z+ rcall Send_Data dec r18 brne Def_Users_Chars_Cycle_0 dec r19 brne Def_Users_Chars_Cycle ret Table_LCD_Line_Addr: ; Адреса строк. .db LINE_0, LINE_1 .db LINE_2, LINE_3 Table_Char_RUS: ; Таблица кириллицы. VFD поддерживает только ; заглавные русские буквы. И не все. Ф и Ь в таблице пользовательских символов. ;АБВГДЕЖЗ .db 0x41, 0x80, 0x42, 0x92, 0x81, 0x45, 0x82, 0x83 ;ИЙКЛМНОП .db 0x84, 0x85, 0x4B, 0x86, 0x4D, 0x48, 0x4F, 0x87 ;РСТУФХЦЧ .db 0x50, 0x43, 0x54, 0x88, 0x00, 0x58, 0x89, 0x8A ;ШЩЪЫЬЭЮЯ .db 0x8B, 0x8C, 0x8D, 0x8E, 0x01, 0x8F, 0xAC, 0xAD TABLE_USERS_CHARS: ; Таблица пользовательских символов. .db 0x00, 0x04, 0x0E, 0x15, 0x15, 0x0E, 0x04, 0x04 ; Ф .db 0x00, 0x10, 0x10, 0x10, 0x1E, 0x11, 0x11, 0x1E ; Ь .db 0x00, 0x04, 0x0E, 0x1F, 0x00, 0x1F, 0x0E, 0x04 ; Main: wdr rcall Service_Timers rcall DRV_LCD rcall KBD_DRV lds r16,_KEYS_CODE cpse r16,RSER rcall Process_Codes_Keys rcall Tasks_Service rjmp Main