-- ------------------------------------------------------ -- Title: Output library to LCD KTM-S1201 lcd_ktms1201.jal -- -- Author: Alexis Klyuev, RA1CAC, Copyright (c) 2014, all rights reserved. -- -- Adapted-by: -- -- Compiler: 2.4l -- -- Description: -- Библиотека вывода на дисплей LCD KTM-S1201 -- для Microchip PIC16f6xxa. -- -- Sources: -- -- Notes: -- File creation date/time: 18 May 2014 00:53:00 MSK. -- -- ------------------------------------------------------ -- -------------------------------------------------------------------------------- -- You may want to change the selected pin: -- LCD KTM-S1201 -- alias LCD_SCK is pin_B0 -- pin_B0_direction = output -- alias LCD_SI is pin_B1 -- pin_B1_direction = output -- alias LCD_CS is pin_B2 -- pin_B2_direction = output -- alias LCD_CD is pin_B3 -- pin_B3_direction = output -------------------------------------------------------------------------------- const byte lcd_CMD = 1 const byte lcd_DATA = 0 const byte lcd_BLINK_OFF = 0x18 const byte lcd_BLINK_ON_SLOW = 0x1a const byte lcd_BLINK_ON_FAST = 0x1b const byte lcd_SPACE = 0x0f const byte lcd_MINUS = 0x0a const byte lcd_DOT = 0x2e const dword c10_000_000 = 10_000_000 const dword c1_000_000 = 1_000_000 const dword c100_000 = 100_000 const dword c10_000 = 10_000 const dword c1_000 = 1_000 const dword c100 = 100 const word c10 = 10 const byte ini_buf[6] = { 0x40, -- mode set 0x30, -- use unsynchronized transfer 0x18, -- blink off 0x11, -- display on 0x15, -- segment decoder on 0x20 -- clear data memory } --var volatile byte freq_str[13] --= {1,2,3,lcd_DOT,4,5,6,7,8,9,lcd_SPACE,1,lcd_MINUS} var volatile byte decimal[4] = { 0x14, 0xe0, 0xb8, 0x15 } ;------------------------------------------------------------------- ; lcd_write(...) ; ; Note: /CS must be set before calling this function, and ; reset afterwards (because its the release of /CS that makes the ; LCD update its memory). ;------------------------------------------------------------------- procedure lcd_write(byte in buffer[], byte in cnt, byte in cmd) is var byte i var byte c if(cmd != 0x00) then LCD_CD = lcd_CMD else LCD_CD = lcd_DATA end if for cnt using i loop c = buffer[i] if (c != ".") then for 8 loop LCD_SCK = off if ((c & 0x80) != 0x00) then LCD_SI = on else LCD_SI = off end if LCD_SCK = on c = c << 1 _usec_delay(20) end loop end if end loop end procedure ;------------------------------------------------------------------- ; lcd_init() ; ; Initialize the KTM-S1201: segment decoder on, unsynchronized ; transfer mode. ;------------------------------------------------------------------- procedure lcd_init() is LCD_CS = low ; wait a few us for /BUSY to exit high impedance state _usec_delay(2000) lcd_write(ini_buf, 6, 1) LCD_CS = high end procedure ;-------------------------------------------------------------------------------- ; lcd_dword_to_str(dword in freq, sword in delta, byte in str[], bit in rit_on) ; freq - source value ; delta - RX delta +- ; str[] - output buffer ; rit_on - rx delta 1 = on, 0 = off ;-------------------------------------------------------------------------------- procedure lcd_dword_to_str(dword in freq, sword in delta, byte in str[], bit in rit_on) is var byte i,j,d var word udelta var dword divider = c10_000_000 for 12 using i loop str[i] = lcd_SPACE end loop j = 7 for 7 loop d = byte(freq / divider) if ((d != 0) | (str[j+1] != lcd_SPACE)) then str[j] = d end if freq = freq % divider divider = divider / 10 j = j - 1 end loop str[0] = byte(freq) if rit_on then if delta < 0 then str[11] = lcd_MINUS udelta = word(delta * -1) else udelta = word(delta) end if str[10] = byte(udelta / c100) udelta = word(udelta % c100) str[9] = byte(udelta / c10) udelta = word(udelta % c10) str[8] = byte(udelta) end if end procedure -------------------------------------------------------------------------------- ;------------------------------------------------------------------- ; lcd_puts(...) ; ; Send a string to the KTM-S1201. Allowed characters are ; 0x00 - 0x09 : numeric digits ; lcd_SPACE : blank ; lcd_DOT : decimal point ; lcd_MINUS : minus sign ; ; position = starting position relative to the left hand side, ; which is 0. ; ; Limitation: only one decimal point is supported in the input ; string. If you need more decimal points, use ; LCD_insert_decimal(). ;-------------------------------------------------------------------*/ procedure lcd_puts(byte in buffer[], sbyte in position ) is var byte ucDecoderOn[1] = {0x15} var byte ucClear[1] = {0x20} var byte ucBuffer[2] var byte i, n, pos, chars=0 LCD_CS = low ; wait a few us for /BUSY to exit high impedance state _usec_delay(2000) lcd_write( ucClear, 1, lcd_CMD ) ; clear memory lcd_write( ucDecoderOn, 1, lcd_CMD ) ; decoder on n = byte(count(buffer)) for n using i loop if (buffer[i] != "." ) then chars = chars + 1 end if end loop pos = 12 - ( position + chars ) if (( position + chars ) == 0) then pos = 11 elsif (( position + chars ) > 12) then pos = 0 end if ucBuffer[0] = 0xe0 | (2 * pos) lcd_write( ucBuffer, 1, lcd_CMD) lcd_write(buffer, 13, lcd_DATA) ; out data for 13 using i loop if ((buffer[i] == lcd_DOT) & (i >= position))then decimal[1] = 0xE0 + (2 * (i-position)) lcd_write(decimal, 4, lcd_CMD) end if end loop LCD_CS = high end procedure ;------------------------------------------------------------------- ; LCD_blink(...) ; ; Turn blinking on or off. Use BLINK_ defines for parameter. ; ; Observation: SLOW blinks on and off in approximately 1 second ; FAST blinks twice the speed as slow ; When blinking, some segments stay on all the time! ; why? (looks like crap). ;------------------------------------------------------------------- procedure lcd_blink (byte in blink) is var byte ucBuffer[1] LCD_CS = low ; wait a few us for /BUSY to exit high impedance state _usec_delay(2000) ucBuffer[0] = blink lcd_write( ucBuffer, 1, lcd_CMD); LCD_CS = high end procedure ;------------------------------------------------------------------- ; LCD_insert_decimal(...) ; ; Insert a decimal point at the position specified (relative ; to the left hand side). ;------------------------------------------------------------------- procedure lcd_insert_decimal( byte in position ) is ; static unsigned char ucDecimal[4] = { 0x14, 0xe0, 0xb8, 0x15 }; var byte pos; if ( position > 12 ) then position = 12 end if ; if ( position < 0 ) position = 0 LCD_CS = low ; wait a few us for /BUSY to exit high impedance state _usec_delay(2000) pos = 12 - position; if ( pos > 12 ) then pos = 12 end if ; if ( pos < 0 ) pos = 0; decimal[1] = 0xe0 | ( 2 * pos ); lcd_write(decimal, 4, lcd_CMD); LCD_CS = high end procedure ------------------------------------------- ;procedure lcd_display_number(dword in number, byte in pos) is ; lcd_write(freq_str, 12, 0) ;end procedure -------------------------------------------