Este experimento executa escrita diversas no LCD no modo 4 Bits, portanto utilizando apenas 1 port do 8051
- CPU-8051-USB
- PR-LCD-1602
- Grave o programa do experimento na CPU-8051-USB.
- Conecte o CN1 do módulo PR-LCD-1602 no port P0 da CPU-8051-USB
- Pressione e solte o botão reset.
//################################################################################################
//# EMPRESA: ========== CONTROL CHIP ENGENHARIA ======== #
//# SITE: http://www.controlchip.com.br #
//#==============================================================================================#
//# PROGRAMADOR: Israel Cortez #
//# DATA DO SOFTWARE: 20/05/2009 #
//# VERSÃO ATUAL: VR3.2 #
//#==============================================================================================#
//# Hardware Necessário: CPU-8051-USB / PR-LCD-1602 #
//#==============================================================================================#
//------------------------------
//========== INCLUDES ==========
//------------------------------
#include "8051.H" //Flags do 8051
//---------- ----------
#include //TRATAMENTO DE STRINGS
//--------------------------------
//========== PROTITIPOS ==========
//--------------------------------
void INICIALIZA_LCD(void);
void LCD_CLEAR(void);
void LCD_POSIC_LINHA1(char);
void LCD_POSIC_LINHA2(char);
void LCD_WRITE(char[16]);
void LCD_WAIT(unsigned char);
void LCD_WAIT_RAPIDO(void);
void BITS4(unsigned char);
void TIMER(unsigned char);
void QUEBRA_NUMEROS(unsigned char);
void WRITE_NUMERO(unsigned char);
void WRITE_CARAC(unsigned char);
//--------------------------------------------
//========== VARIAVEIS DE USO GERAL ==========
//--------------------------------------------
unsigned char ESCRITA_LENTA=0; // 1= Escrita LCD lenta | 0= Escrita LCD rápida
//===== BYTE AUXILIAR P/ ACESSO BIT A BIT =====
data unsigned char at 0x2F BYTE_BIT_BIT=0;
//===== BITS =====
bit at 0x78 BYTE_BIT_BIT_0=0; //BIT 0 2F.0
bit at 0x79 BYTE_BIT_BIT_1=0; //BIT 1 2F.1
bit at 0x7A BYTE_BIT_BIT_2=0; //BIT 2 2F.2
bit at 0x7B BYTE_BIT_BIT_3=0; //BIT 3 2F.3
bit at 0x7C BYTE_BIT_BIT_4=0; //BIT 4 2F.4
bit at 0x7D BYTE_BIT_BIT_5=0; //BIT 5 2F.5
bit at 0x7E BYTE_BIT_BIT_6=0; //BIT 6 2F.6
bit at 0x7F BYTE_BIT_BIT_7=0; //BIT 7 2F.7
//--- Quebra numeros ---
unsigned char DIGITO1;
unsigned char DG1_AUX;
unsigned char CENTENA;
unsigned char DG2_AUX;
unsigned char DIGITO2;
unsigned char DG3_AUX;
unsigned char DIGITO3;
//-----------------------------------------------------------
//======== DECLARAÇÃO DAS VIAS ENTRE uC E Lcd (I/Os) ========
//-----------------------------------------------------------
#define RS P0_0
#define RW P0_1
#define EN P0_2
#define DB4 P0_4
#define DB5 P0_5
#define DB6 P0_6
#define DB7 P0_7
//#############################################################
//-------------------------------------------------------------
//=========================== MAIN ============================
//-------------------------------------------------------------
//#############################################################
void main (void)
{
TIMER(2);
INICIALIZA_LCD(); //Inicializa o modo do display
ESCRITA_LENTA=1;
//----- Loop infinito -----
while (1)
{
//--- Mensagem 1 ---
LCD_CLEAR(); //Limpa display e posiciona o cursor na linha 0 posic 0
LCD_POSIC_LINHA1(0);
LCD_WRITE("PROGRAMA EXEMPLO");
LCD_POSIC_LINHA2(0);
LCD_WRITE("MOD PR-LCD-1602");
TIMER(100);
//--- Mensagem 2 ---
LCD_CLEAR();
LCD_WRITE(" CONTROL CHIP ");
LCD_POSIC_LINHA2(0);
LCD_WRITE(" ENGENHARIA ");
TIMER(100);
//--- Mensagem 3 ---
LCD_CLEAR();
LCD_WRITE(" Hello Word ");
LCD_POSIC_LINHA2(0);
LCD_WRITE(" Hello Word ");
TIMER(100);
//--- Alterna entre escrita Rápida e lenta ---
if(ESCRITA_LENTA==0)
{
ESCRITA_LENTA=1;
}
else
{
ESCRITA_LENTA=0;
}
}
}
//#############################################################
//-------------------------------------------------------------
//======================= SUB ROTINAS =========================
//-------------------------------------------------------------
//#############################################################
//======================================================================
//================== EXECUTA INICIALIZAÇÃO DO LCD ======================
//======================================================================
void INICIALIZA_LCD(void)
{
RS=0;
RW=0;
EN=0;
EN=1;
DB4=0;
DB5=1;
DB6=0;
DB7=0;
EN=0;
LCD_WAIT(100);
//Prepara o LCD para trabalhar com 4 bits e 2 linhas
RS=0;
BITS4(0x28);
//----- Envia segundo Byte -----
BITS4(0x0C);
//----- Envia terceiro Byte -----
BITS4(0x06);
//----- Limpa display -----
LCD_CLEAR();
//----- Posiciona cursor -----
LCD_POSIC_LINHA1(0);
}
//------------------------------------------------
//----- QUEBRA NUMERO (Desmembra os digitos) -----
//------------------------------------------------
void QUEBRA_NUMEROS(unsigned char NUMERO)
{
DG1_AUX=(NUMERO/100);
//----- Pega segundo digito -----
CENTENA=DG1_AUX*100;
DG2_AUX=NUMERO-CENTENA;
DG2_AUX=(DG2_AUX/10);
//----- Pega terceiro digito -----
DG3_AUX=CENTENA+DG2_AUX*10;
DG3_AUX=(NUMERO-DG3_AUX);
//--- Converte os numeros em ASCLL ---
DIGITO1=DG1_AUX+48;
DIGITO2=DG2_AUX+48;
DIGITO3=DG3_AUX+48;
}
//======================================================================
//================== ESCREVE NUMEROS DE 3 DIGITOS ======================
//======================================================================
void WRITE_NUMERO(unsigned char NUMEROS)
{
QUEBRA_NUMEROS(NUMEROS);
WRITE_CARAC(DIGITO1);
WRITE_CARAC(DIGITO2);
WRITE_CARAC(DIGITO3);
}
//============================================================
//================== ESCREVE CARACTERES ======================
//============================================================
void WRITE_CARAC(unsigned char CARACTER)
{
EN=1;
RS=1;
BITS4(CARACTER);
EN=0;
}
//======================================================================
//============================ WAIT LCD ================================
//======================================================================
void LCD_WAIT(unsigned char tempo)
{
unsigned char conta1=0;
unsigned char conta2=0;
unsigned char conta3=0;
while(conta1<=tempo)
{
conta1++;
conta2=0;
while(conta2<=5)
{
conta2++;
conta3=0;
while(conta3<=25)
{
conta3++;
}
}
}
}
//======================================================================
//========================= WAIT LCD RAPIDO ============================
//======================================================================
void LCD_WAIT_RAPIDO(void)
{
unsigned char conta2=0;
unsigned char conta3=0;
conta2=0;
while(conta2<=2)
{
conta2++;
conta3=0;
while(conta3<=2)
{
conta3++;
}
}
}
//======================================================================
//========================== ENVIA NIBBLE ==============================
//======================================================================
void BITS4(unsigned char DADO)
{
EN=1;
BYTE_BIT_BIT=DADO;
DB4=BYTE_BIT_BIT_4;
DB5=BYTE_BIT_BIT_5;
DB6=BYTE_BIT_BIT_6;
DB7=BYTE_BIT_BIT_7;
EN=0;
EN=1;
BYTE_BIT_BIT=DADO;
DB4=BYTE_BIT_BIT_0;
DB5=BYTE_BIT_BIT_1;
DB6=BYTE_BIT_BIT_2;
DB7=BYTE_BIT_BIT_3;
EN=0;
LCD_WAIT_RAPIDO();
}
//======================================================================
//============================ CLEAR LCD ===============================
//======================================================================
void LCD_CLEAR(void)
{
EN=1;
RS=0;
BITS4(1);
EN=0;
LCD_WAIT(6);
}
//======================================================================
//============================ POSIC LCD ===============================
//======================================================================
void LCD_POSIC_LINHA1(char POSIC)
{
RW=0;
EN=1;
RS=0;
BITS4(POSIC + 0x80);
EN=0;
LCD_WAIT(6);
}
void LCD_POSIC_LINHA2(char POSIC)
{
RW=0;
EN=1;
RS=0;
BITS4(POSIC + 0xC0);
EN=0;
LCD_WAIT(6);
}
//======================================================================
//=========================== WRITE TEXT ===============================
//======================================================================
void LCD_WRITE(char TEXTO[16])
{
int SIZE_LCD;
int PTR_LCD=0;
SIZE_LCD=strlen(TEXTO);
while(SIZE_LCD>=1)
{
SIZE_LCD--;
WRITE_CARAC(TEXTO[PTR_LCD]);
PTR_LCD++;
if(ESCRITA_LENTA==1)
{
LCD_WAIT(80);
}
}
}
//----------------------------------------------------------------
//========================= TEMPORIZADOR =========================
//----------------------------------------------------------------
void TIMER(unsigned char TEMPO)
{
unsigned char CONTA1=0;
unsigned char CONTA2=0;
unsigned char CONTA3=0;
while(CONTA1<=TEMPO)
{
CONTA1++;
CONTA2=0;
while(CONTA2<=10)
{
CONTA2++;
CONTA3=0;
while(CONTA3<=250)
{
CONTA3++;
}
}
}
}
;################################################################################################
;# EMPRESA: ========== CONTROL CHIP ENGENHARIA ======== #
;# SITE: http://www.controlchip.com.br #
;# E-Mail: suporte@controlchip.com.br #
;#==============================================================================================#
;# PROGRAMADOR: Israel Cortez #
;# DATA DO SOFTWARE: 20/05/2009 #
;# VERSÃO ATUAL: VR3.2 #
;#==============================================================================================#
;# Hardware Necessário: CPU-8051-USB / PR-LCD-1602 #
;#==============================================================================================#
;# Descrição: Este programa exibe mensagens diversas no LCD utilizando soment 1 port #
;# do microcontrolador (LCD no modo 4 Bits) #
;################################################################################################
;=========================== CONSTANTES ==========================
DADO_LCD EQU 0030H
LENTO EQU 31H
;=========================== TELAS LCD ===========================
MENSAGEM1 EQU 1000
MENSAGEM2 EQU 1020
MENSAGEM3 EQU 1040
MENSAGEM4 EQU 1060
MENSAGEM5 EQU 1080
;---------------------------
;------- PINAGEM LCD -------
;---------------------------
RS EQU P0.0
RW EQU P0.1
EN EQU P0.2
PIN4 EQU P0.4
PIN5 EQU P0.5
PIN6 EQU P0.6
PIN7 EQU P0.7
;######################################################################################################
;------------------------------------------------------------------------------------------------------
;====================================== PROGRAMA PRINCIPAL ============================================
;------------------------------------------------------------------------------------------------------
;######################################################################################################
ORG 0000H
INICIO:
MOV LENTO,#1
;===============================================
;================= INICIALIZA LCD ==============
;===============================================
CALL INICIALIZ_LCD
CALL CLEAR_LCD
MOV A,#10D
CALL TIMER_6ms
;===============================================
;=============== ESCREVE TELAS =================
;===============================================
TELAS:
;------------------
;===== TELA 1 =====
;------------------
CALL CLEAR_LCD
;--- Linha 1 ---
MOV A,#0
LCALL POS_LIN1
MOV DPTR,#MENSAGEM1
LCALL WRITESTRING
;--- Linha 2 ---
MOV A,#0
LCALL POS_LIN2
MOV DPTR,#MENSAGEM2
LCALL WRITESTRING
MOV A,#150
CALL TIMER_6ms
;------------------
;===== TELA 2 =====
;------------------
CALL CLEAR_LCD
;--- Linha 1 ---
MOV A,#0
LCALL POS_LIN1
MOV DPTR,#MENSAGEM3
LCALL WRITESTRING
;--- Linha 2 ---
MOV A,#0
LCALL POS_LIN2
MOV DPTR,#MENSAGEM4
LCALL WRITESTRING
MOV A,#150
CALL TIMER_6ms
;------------------
;===== TELA 3 =====
;------------------
CALL CLEAR_LCD
;--- Linha 1 ---
MOV A,#0
LCALL POS_LIN1
MOV DPTR,#MENSAGEM5
LCALL WRITESTRING
;--- Linha 2 ---
MOV A,#0
LCALL POS_LIN2
MOV DPTR,#MENSAGEM5
LCALL WRITESTRING
MOV A,#150
CALL TIMER_6ms
;--- INVERTE ESTADO ESCRITA Rapida/Lenta ---
MOV A,LENTO
CJNE A,#0,VAI_LENTO
MOV LENTO,#1
LJMP TELAS
VAI_LENTO:
MOV LENTO,#0
LJMP TELAS
;#####################################################################################################
;-----------------------------------------------------------------------------------------------------
;============================================ SUB ROTINAS ============================================
;-----------------------------------------------------------------------------------------------------
;#####################################################################################################
;=================================================================
;======================== TEMPORIZADOR 1 =========================
;=================================================================
;timer ajustado para aproximadamente 6 mili segundos
TIMER_6ms: MOV R0,A
CJNE R0,#0,INICIO_TIMER_6ms
MOV R0,#1D
INICIO_TIMER_6ms: MOV R1,#200D
MOV R2,#6D
REPETE_TEMPO: NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R1,REPETE_TEMPO
MOV R1,#200D
DJNZ R2,REPETE_TEMPO
DJNZ R0,INICIO_TIMER_6ms
RET
;=================================================================
;======================== INICIALIZ LCD ==========================
;=================================================================
INICIALIZ_LCD: CLR RS
CLR RW
CLR EN
SETB EN
CLR PIN4
SETB PIN5
CLR PIN6
CLR PIN7
CLR EN
MOV A,#8D
CALL TIMER_6ms
;Prepara o LCD para trabalhar com 4 bits e 2 linhas
CLR RS
MOV DADO_LCD,#28h
CALL ENVIA_NIBBLE
MOV A,#1D
CALL TIMER_6ms
;----- Envia segundo Byte -----
CLR RS
MOV DADO_LCD,#0Ch ;Cursor Desabilitado
; MOV DADO_LCD,#0Ch ;Cursor Habilitado
CALL ENVIA_NIBBLE
MOV A,#1D
CALL TIMER_6ms
;----- Envia terceiro Byte -----
CLR RS
MOV DADO_LCD,#06h
CALL ENVIA_NIBBLE
MOV A,#1D
CALL TIMER_6ms
RET
;=================================================================
;=============== ENVIA NIBBLE (LCD EM MODO 4 BITS) ===============
;=================================================================
;---- ENVIA 1 NIBBLE ----
ENVIA_NIBBLE: SETB EN
CLR PIN4
CLR PIN5
CLR PIN6
CLR PIN7
MOV ACC,DADO_LCD
JNB ACC.4,PIN5_1
SETB PIN4
PIN5_1: JNB ACC.5,PIN6_1
SETB PIN5
PIN6_1: JNB ACC.6,PIN7_1
SETB PIN6
PIN7_1: JNB ACC.7,FIM_NIBLE
SETB PIN7
FIM_NIBLE: CLR EN
;--------- ENVIA 2 NIBBLE ---------
SETB EN
CLR PIN4
CLR PIN5
CLR PIN6
CLR PIN7
MOV ACC,DADO_LCD
JNB ACC.0,PIN5_2
SETB PIN4
PIN5_2: JNB ACC.1,PIN6_2
SETB PIN5
PIN6_2: JNB ACC.2,PIN7_2
SETB PIN6
PIN7_2: JNB ACC.3,FIM_NIBLE2
SETB PIN7
FIM_NIBLE2: CLR EN
CALL WAIT_LCD
RET
;=================================================================
;========================= WAIT LCD =============================
;=================================================================
;ajustado para aproximadamente mili segundo
WAIT_LCD: MOV R7,#50D
MOV R6,#4D
LOOP: NOP
DJNZ R7,LOOP
MOV R7,#50D
DJNZ R6,LOOP
RET
;=================================================================
;=========================== CLEAR LCD ===========================
;=================================================================
CLEAR_LCD: CLR RS
MOV DADO_LCD,#01h
CALL ENVIA_NIBBLE
CALL WAIT_LCD
RET
;=================================================================
;========================= WRITE CARAC ===========================
;=================================================================
WRITE_CARAC: SETB RS
MOV DADO_LCD,A
LCALL ENVIA_NIBBLE
CLR RS
RET
;=================================================================
;========================== WRITE TEXT ===========================
;=================================================================
WRITESTRING: MOV A,#0D
MOVC A,@A+DPTR
CJNE A,#'$',WRITE_NEXT
SJMP FINIS_STRING
WRITE_NEXT: SETB RS
MOV DADO_LCD,A
LCALL ENVIA_NIBBLE
CLR RS
INC DPTR
;--- Verifica se escrita deve ser lenta ---
MOV A,LENTO
CJNE A,#1,PULA_TEMPO
MOV A,#5
CALL TIMER_6ms
PULA_TEMPO:
SJMP WRITESTRING
FINIS_STRING: CLR RS
RET
;=================================================================
;=========================== POSIC LCD============================
;=================================================================
POS_LIN1: CLR RW
CLR RS
ADD A,#80H
MOV DADO_LCD,A
CALL ENVIA_NIBBLE
RET
;=================================================================
;========================= POSIC LCD 2 ===========================
;=================================================================
POS_LIN2: CLR RW
CLR RS
ADD A,#192
MOV DADO_LCD,A
CALL ENVIA_NIBBLE
RET
;=================================================================
;========================= WRITE TEXT 2 ==========================
;=================================================================
ENVIA_NIBBLE2: SETB EN
SETB PIN4
SETB PIN5
CLR PIN6
CLR PIN7
CLR EN
;--------- ENVIA 2 NIBBLE ---------
SETB EN
CLR PIN4
CLR PIN5
CLR PIN6
CLR PIN7
MOV ACC,DADO_LCD
JNB ACC.0,PIN5_22
SETB PIN4
PIN5_22: JNB ACC.1,PIN6_22
SETB PIN5
PIN6_22: JNB ACC.2,PIN7_22
SETB PIN6
PIN7_22: JNB ACC.3,FIM_NIBLE22
SETB PIN7
FIM_NIBLE22: CLR EN
CALL WAIT_LCD
RET
;==========================================================
;============ TEXTOS A SEREM ESCRITOS NO LCD ==============
;==========================================================
org MENSAGEM1
DB 'PROGRAMA EXEMPLO$'
org MENSAGEM2
DB 'MOD PR-LCD-1602$'
org MENSAGEM3
DB ' CONTROL CHIP $'
org MENSAGEM4
DB ' ENGENHARIA $'
org MENSAGEM5
DB ' Hello Word $'
END