Nyt on tullut suoraan + sarjaliikekentellä toimivat LCD näytöt, vihdoinkin.
On myös I2C suoraan toimivia LCD näyttöjä, ei paljon muita enään olekaan
Tässä on sarjaliikenteellä toimiva LCD
// TÄMÄ on rinnakkaisLCD:n Testausohjelma
// PEKKA Ritamäki
// 13.6.2022
#include <16F18857.h> // valitse oikea PIC piiri
#FUSES NOWDT // Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES IESO Internal External Switch Over mode enabled
#FUSES NOBROWNOUT //No reset when brownout detected
#FUSES NOPUT //No power Up Timer
#FUSES NOCPD //No EE protection
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOFCMEN //Fail-safe clock monitor enabled
#FUSES NOIESO Internal External switch over mode disabled
#FUSES NOMCLR //Master Clear pin not enabled
#FUSES BORV21 //tämä pitää olla 3.3V:lla BORV21 (=2.1V) muuten ei toimi.
// Muuten Brown Out Reset on BORV40(= 4.0V)!!! 4.5V paristo menee menee alle 4V:n!
#device ADC=10 *=16 // valitaan tarkin ADC-muunnin
#use delay(internal=32MHz,restart_wdt)
#pin_select U1TX = PIN_C6 // ota käyttöön normaalit TX sarjaliikenteelle
#pin_select U1RX = PIN_C7 // ota käyttöön normaalit RX sarjaliikenteelle
#pin_select SCL1OUT=PIN_C3
#pin_select SDA1OUT=PIN_C4
#use FIXED_IO( A_outputs=PIN_A0 )
#use FIXED_IO(B_outputs=PIN_B0, PIN_B1,PIN_B2,PIN_B3, PIN_B4, PIN_B5,PIN_B6,PIN_B7)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8 ,errors )
// portin IO-nastosjen osoitteet
#BYTE PORTB = 6
#BYTE PORTA = 5
#BYTE PORTC= 7
#BYTE TRISA =0x85
#BYTE TRISB =0x86
#byte TXTA = 0x98
#BYTE RCSTA = 0x18
#BIT SPEN = RCSTA.7
#BYTE OPTION_REG = 0x81
#BIT PULLUPSBIT = OPTION_REG.7
#include "lcd1.c"
// vilauta lediä 100 ms
void led()
{
output_a(0x1);
delay_ms(100);
output_a(0 );
}
// pääohjelma alkaa
void main()
{
setup_adc_ports(NO_ANALOGS);
set_tris_a(0); // leiä varten suuntärekisteri =0 eli antonasta
output_a(0xF); // laitan neljä alintä bittiä päälle
printf("\rProbyte 3 LCD test %s",DATE);
led() ;
printf( "\rProbyte LCD test %s",DATE);
delay_ms(1000);
lcd_init();
while(1) // jatkuva syöttö
{
led() ; // vilautaä lEDiä A.0
lcd_gotoxy(ROW1);
printf(lcd_putc,"Rivi1" );
lcd_gotoxy(ROW2);
printf(lcd_putc,"Rivi2" );
lcd_gotoxy(ROW3);
printf(lcd_putc,"Rivi3" );
lcd_gotoxy(ROW4);
printf(lcd_putc,"Rivi4" );
delay_ms(1000);
}
}
// Tässä on LCD1.c
lcd1.c
// RinnakkaisLCD:n driveri esim. L2034 4*20 merkkiä varten
// LCD on kytketään 4 bitin moodiim
// B.4 -B.7 on data D0 -D3
// enable = B.3
// r/W =B.2= 0V
// RS = B.1
// alauksi LCD_init, sitten esim printf(lcd_putc,"Rivi4" );
// Pekka Ritamäki
#BIT DB3 = PORTB.7
#BIT DB2 = PORTB.6
#BIT DB1 = PORTB.5
#BIT DB0 = PORTB.4
#BIT RS = PORTB.1
#BIT R_W = PORTB.2
#BIT ENABLE = PORTB.3 // LCD enable
#define CMD 0 // komento moodi
#define DAT 1 // data moodi
#define LCD4MODE 3 // tämä laittaa 4-bittiseen moodiin
#define LCD_16_1 1 // 1*16 LCD mode 1 rivinen LCD
#define LCD_CLEAR 1
#define LCD_HOME 2
#define LCD_ENTRY_MODE 6
#define LCD_BACK 0x10
#define ROW1 0x80 // gotoxy (1, 1)*/
#define ROW2 0xC0 // 2*16 40 +80 */
#define ROW3 0x94 // gotoxy (1, 3)
#define ROW4 0xd4 // gotoxy (1, 4)
#define CURSOROFF 0x0C // Display on, cursor off 2, blink off send_bytes(CMD, CURSOROFF );
#define CURSORON 0x0D // Display on, cursor ON , blink off send_bytes(CMD, CURSORON );
#define LCD_CURSOR_ON 0xF // LCD kursoria päälle, käytä komentomodea esim send_bytes(CMD, LCD_CURSOR_ON);
#define LCD_CURSOR_OFF 0xD // LCD kursoria poispäältä, käytä komentomodea esim send_bytes(CMD, LCD_CURSOR_OFF);
#define LCD_CURSOR_RIGHT 0x14 // LCD siirrä kursoria oikealle, käytä komentomodea esim send_bytes(CMD, LCD_CURSOR_OFF);
#define CursorBack 16
// siirrä LCD kursoria taaksepäin, käytä komentomodea esim send_bytes(CMD, CursorBack);
#define CursorFwd 20 // liikutä kursoriä eteenäpäin send_bytes(CMD, CursorFwd );
void lcd_send_byte( byte address, byte n ) ;
int blink_cursor;
// tämän funktio käyttää esim enable lcd.enable =1
struct lcd_pin_map { // Tämä structuuri on B-portille
int data : 4; // 4 bittiä ylinnä B5..B7
int enable; // ENABLE on RB.3
int RW; // RW= B2
int RS; // RS=B.1
int spare; // ei käytössä
} lcd;
#byte lcd = 6 // LCD on mapattu ositteeseen 6 eli B-porttiin
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 riviä
#define lcd_line_two 0x40 // LCD RAM:in osoite toiselle riville vain eräillä LCD:llä
byte CONST LCD_INIT_STRING[4] = {0x20 | (lcd_type « 2), 0xc, 1, 6};
// Nämä bytet pitää lähettää käynnistyksessä LCD
// Seuraavia käytetän IO-portin suunnissa
// asettamaan I/O portin suuntarekisteriä
STRUCT lcd_pin_map const LCD_WRITE = {0,0,0,0,0};
Kirjoita tilassa ( LCD), kaikki io-nastat asetetaan Outputeiksi
//STRUCT lcd_pin_map const LCD_READ = {15,0,0,0,0};
void lcd_send_nibble(int8 nibble)
{
if ( nibble &1)
output_high(PIN_B4);
else
output_low(PIN_B4);
if ( nibble &2)
output_high(PIN_B5);
else
output_low(PIN_B5);
if ( nibble &4)
output_high(PIN_B6);
else
output_low(PIN_B6);
if ( nibble &8)
output_high(PIN_B7);
else
output_low(PIN_B7);
delay_us(1);
// enable=1;
output_high(PIN_B3); // Enable=1
delay_us(10);
printf("\rNibb =%x", nibble);
output_LOW( PIN_b3);// Enable=0
delay_us(10);
}
/*
void lcd_send_nibble( byte n ) {
lcd.data = n;
delay_cycles(1);
ENABLE= 1;
delay_us(6);
ENABLE= 0;
}
*/
void lcd_send_byte( byte address, byte n ) {
RS = 0;
delay_ms(1); // pieni viive koska lcd:tä ei lueta takaisin
if (address)
output_high(PIN_B1); // komentomode =1
else
output_low(PIN_B1); // komentomode =0 eli datamode
printf("\rRS =%x", address);
delay_cycles(1);
delay_cycles(1);
output_low(PIN_B3); // ENABLE=0;
printf("\rBYte =%x", n);
lcd_send_nibble(n » 4); // siirrä data4 bittiä oikealle
lcd_send_nibble(n & 0xf); // ota vain 4 alinta bittiä
}
// alusta lcd 4-bittiseen modeen
void lcd_init(void) {
set_tris_b(0);
byte i;
R_W= 0; // R_W on koko ajan nollissa
RS = 0; // aluksi komemtomoodi päälle
ENABLE=0;
output_low(PIN_B3); // enamble pois
delay_ms(15); pieni viive
for(i=1;i<=3;++i) {
lcd_send_nibble(LCD4MODE); // 4-bit mode =3
delay_ms(5);
}
lcd_send_nibble(2); // alusta LCD
for(i=0;i<=3;++i)
lcd_send_byte(CMD,LCD_INIT_STRING[i]);
blink_cursor = LCD_CURSOR_ON;
lcd_send_byte(CMD, blink_cursor); /* kursori päälle ja eteenpäin */
}
// Ei tarvitse tätä käyttää
void lcd_gotoxyl( byte x, byte y) { // laita LCD paikkaan c ja riville y
byte address;
if(y!=1)
address=lcd_line_two; #define lcd_line_two 0x40
else
address=0;
address+=x-1;
lcd_send_byte(0,0x80|address);
}
#define ROW1 0x80 /* gotoxy (1, 1)*/
#define ROW2 0xC0 /* 2*16 40 +80 */
#define ROW3 0x94 /* gotoxy (1, 3) */
#define ROW4 0xd4 /* gotoxy (1, 4) */
mene riville 1,2,3 tai 4
void lcd_gotoxy( byte x) { // goto ROW1, ROW2,ROW3 tai ROW4
lcd_send_byte(CMD,x);
}
/*
KIRJOITA yksi merkki LCD:lle
***/
char lcd_putc( char c) {
switch (c) {
// case '\f' : lcd_send_byte(0,1);
case '\n' : lcd_gotoxy(2); break; // contrl/ J = enter riville 2
case '\b' : lcd_send_byte(0,0x10); break; //mode =0 komento 10 0backstep
default : lcd_send_byte(1,c); break; // mode=1, data
}
return c;
}
Pekka





