První kód je napsán v assembleru ve vývojovém prostředí MPLAB pro jednočipový mikrořadič PIC16F84. Druhý program pro ovládání LCD displaye s řadičem HD44780 je taktéž napsán ve stejném vývojovém prostředí ale je použit jazyk C. Jednočipový mikrořadič je použit PIC16F877A. Jako kompilátor céčka je použit HI-TECH PICC, který se dá jako demo stáhnout z: www.htsoft.com demo je u některých PICu omezena jen na 2KB kódu.
Kód v assembleru...
Kód v Céčku...
PIC16 code
//DEVICE PIC16F877A
//hacesoft
//www
.prochazka
.zde
.cz
//6
.11
.2005
//Ovládaní LCD DISPLAYe ve vývojové desce PIC + XILINX
//Která se nachází na www
.prochazka
.zde
.cz
//Fyzické zapojeni LCD k PICu 16F877A
//RE0
...RS -> vyber reg
.
//RE1
...RW -> read/write
//RB3
...EN1 -> ENABLE LCD
//RB1
...DB4
//RB2
...DB5
//RB4
...DB6
//RB5
...DB7
#include
"pic.h"
#include
"pic168xa.h"
#include
"LCD_vyvojova_deska.h"
#define XTAL_FREQ 20MHZ
#include
"delay.c"
#include
"stdio.h"
#include
"ctype.h"
#include
"string.h"
__CONFIG
(HS & WDTDIS & BORDIS & LVPDIS
); //Konfiguracni slovo
__IDLOC
(1); //verze SW
#define BF_FLAG
(false
); //FALSE=Cekaci smyska. TRUE=Cekani na prinzak BF z displye.
static bit EN @
((unsigned
)&PORTE*
8+
2);
static bit LCD_RW @
((unsigned
)&PORTE*
8+
1);
static bit LCD_RS @
((unsigned
)&PORTE*
8+
0);
static bit LCD_EN @
((unsigned
)&PORTB*
8+
3);
static bit LCD_BF @
((unsigned
)&PORTB*
8+
5);
static bit DB4 @
((unsigned
)&PORTB*
8+
1);
static bit DB5 @
((unsigned
)&PORTB*
8+
2);
static bit DB6 @
((unsigned
)&PORTB*
8+
4);
static bit DB7 @
((unsigned
)&PORTB*
8+
5);
unsigned char lcd_data
= 0;
//----------------------------------------------------------------
void lcd_busy
(void
){
#if _BF_FLAG
==true //Nektere displaye neposilaji informaci o dokonceni
TRISB1
= 1; //Nastavani RB1 na vstupni PIN
TRISB2
= 1; //Nastavani RB2 na vstupni PIN
TRISB4
= 1; //Nastavani RB4 na vstupni PIN
TRISB5
= 1; //Nastavani RB5 na vstupni PIN
asm
("xxx: nop");
//for
(;;) {
LCD_RS
= 0;
LCD_RW
= 1;
LCD_EN
= 1;
asm
("movf _PORTB,w");
LCD_EN
= 0;
LCD_EN
= 1;
LCD_EN
= 0;
asm
("andlw _LCD_BF"); //Test na BF příznak.
asm
("btfsc _STATUS,2"); //TEST na ZERO
asm
("goto xxx"); //TEST na ZERO
//
}
LCD_RW
= 0;
TRISB1
= 0; //Nastavani RB1 na vystupní PIN
TRISB2
= 0; //Nastavani RB2 na vystupní PIN
TRISB4
= 0; //Nastavani RB4 na vystupní PIN
TRISB5
= 0; //Nastavani RB5 na vystupní PIN
#else
DelayMs
(9);
#endif
}
//----------------------------------------------------------------
void send_prikaz
(unsigned char bCommand
){
lcd_data
= bCommand
;
lcd_busy
();
LCD_RW
= 0;
LCD_RS
= 0;
LCD_EN
= 1;
zapis_w
();
LCD_EN
= 0;
}
//----------------------------------------------------------------
void lcd_init
(void
){
//Pro jistotu se provede několikrát inicializace
DelayMs
(255);
lcd_init1
();
DelayMs
(255);
lcd_init1
();
DelayMs
(255);
lcd_init1
();
DelayMs
(255);
lcd_init1
();
DelayMs
(255);
lcd_init1
();
}
void lcd_init1
(void
){
//inicializace LCD displye
//unsigned trisb
;
TRISB
= (0b11000001 & TRISB
) | 0b00000000
;
//nastaveni portu B bity
3 až
7 na výstupní
//ostatní nechá nezměněny
.
TRISE0
= 0; //RS -> data ven
TRISE1
= 0; //RW -> data ven
ADCON1
= 12;
//PortA je nastaven jako vstup analog a
//RE0 až
2 jsou nastaveny datové piny
.
DelayMs
(100);
//***************** Nastaveni
8-bitové komunikace ***************************
//
8-bit-interface
send_prikaz
(0x03);
DelayMs
(100);
//*************** Nastaveni
4-bitové komunikace *****************************
//
4-bit-interface
send_prikaz
(0x02);
DelayMs
(100);
//***************************************************************************
//
4-bit-interface
, 2-lines
lcd_put_cmd
(0x28);
//lcd_put_cmd
(0b00100000
);
//disp
.off
, curs
.off
, no-blink
lcd_put_cmd
(0x08);
//lcd smazat
lcd_put_cmd
(0x01);
//disp
.on
, curs
.off
lcd_put_cmd
(0x0c);
//Inkrementace
, normalni mod
.
lcd_put_cmd
(0x06);
}
//----------------------------------------------------------------
void zapis_w
(void
){
//zkopirovat
4 az
7 bity z registru lcd_data na porty B
.
//RB1
...DB4
... bit4 registru lcd_data
//RB2
...DB5
... bit5 registru lcd_data
//RB4
...DB6
... bit6 registru lcd_data
//RB5
...DB7
... bit7 registru lcd_data
#asm
bcf _PORTB
,1
bcf _PORTB
,2
bcf _PORTB
,4
bcf _PORTB
,5
btfsc _lcd_data
,4
bsf _PORTB
,1
btfsc _lcd_data
,5
bsf _PORTB
,2
btfsc _lcd_data
,6
bsf _PORTB
,4
btfsc _lcd_data
,7
bsf _PORTB
,5
#endasm
}
//----------------------------------------------------------------
void lcd_put_char
(unsigned char sString
)
{
//Pošle znak na Display
.
lcd_data
= sString
;
lcd_busy
();
LCD_RW
= 0;
LCD_RS
= 1;
LCD_EN
= 1;
zapis_w
();
LCD_EN
= 0;
LCD_EN
= 1;
asm
("swapf _lcd_data , f");
zapis_w
();
LCD_EN
= 0;
}
//----------------------------------------------------------------
void lcd_scroll
(char Direction
)
//Pohybuje celým displayem
. Toto je funkce LCD
(HW
)
{
if
(Direction
==SCROLL_LEFT
)
{
lcd_put_cmd
(0b00011000
); //Scroll LEFT
}
else
{
lcd_put_cmd
(0b00011100
); //Scroll RIGHT
}
}
//----------------------------------------------------------------
void ScrollMessage
(unsigned char pozice
, unsigned char radek
,const char Message
[])
//Pohybuje textem na zvoleném řádku od zadané pozice
.
{
char TempS
[20];
unsigned int MHead
=0,Done
=0,count
;
while
(Done
==0)
{
for
(count
=0;count<20;count++)
{
TempS
[count
]=Message
[MHead+count
];
if
(Message
[MHead+count+
1]==0) Done
=1;
}
MHead++
;
lcd_goto
(pozice
, radek
);
lcd_string
(TempS
);
DelayMs
(250);
}
}
//----------------------------------------------------------------
void lcd_goto
(unsigned char pozice
, unsigned char radek
)
{
if
(radek >
1) radek
=1;
lcd_put_cmd
(((radek *
40) +
0x80)+ pozice
);
}
//----------------------------------------------------------------
void lcd_string
(const char * s
)
{
while
(*s
)
lcd_put_char
(*s++
);
}
//----------------------------------------------------------------
void lcd_put_cmd
(unsigned char bCommand
)
{
//Posle prikaz na Display
.
//asm
("movwf _lcd_data");
send_prikaz
(bCommand
);
LCD_EN
= 1;
asm
("swapf _lcd_data , f");
zapis_w
();
LCD_EN
= 0;
}
//----------------------------------------------------------------
main
(void
){
unsigned char loop
;
lcd_init
();
for
(;;) {
ScrollMessage
(0,0," Vita Vas Vyvojova deska PIC+XILINX ");
lcd_cls
;
lcd_goto
(0,1);
lcd_string
("Verze SW: 1.0.4.");
ScrollMessage
(0,0," Ze dne: 6. listopadu, 2005. ");
ScrollMessage
(0,0," Veskera dokumentace teto demonstracni desky se da stahnout z: ");
for
(loop
= 0; loop < 10; loop++){
lcd_goto
(0,1);
lcd_string
("prochazka.zde.cz");
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
lcd_goto
(0,1);
lcd_string
(" ");
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
}
lcd_goto
(0,0);
lcd_string
("prochazka.zde.cz");
lcd_goto
(0,1);
lcd_string
(" ----ahoj---- ");
for
(loop
= 0; loop < 5; loop++){
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
lcd_scroll
(SCROLL_LEFT
);
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
}
for
(loop
= 0; loop < 5; loop++){
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
lcd_scroll
(SCROLL_RIGHT
);
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
}
lcd_cursor_home
;
lcd_string
("prochazka.zde.cz");
ScrollMessage
(0,1," Uvitaci program vyvojoveho kitu PIC16F887A + XILINX XC9572XL. Zelenim tlacitkem se zvysuje hodnota na LED display a Modrim se hodnota Na LED display zmensuje. Zluta tlacitka ovladaji LED diody. Prepinace zapinaji a vypinaji blikani LED diod. Pokud je zapnuto blikani a stisknuto zlute tlacitko, tak LED dioda nesviti ale blika!!! ");
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
DelayMs
(250);
lcd_cls
;
}
}