|
本帖最后由 joyrus 于 2012-7-9 12:04 编辑
C/C++ code
//==============================================//
// Filename: C8051f320_SMC1602A_Display.c //
// //
// Prozessor: C8051f320 //
// Compiler: Keil C51 7.06 //
// //
// Author: Paul.Jia //
// QQ: 79974439 //
// Copyright: MKL PSC TSD //
//==============================================//
//================================================
//1. SYSCLK is unlimited here
//2. Display by SMC1602A
//
//Use 3 ports for control
//Use 8 ports for data communications
//And initialize them right in the Main
//
//Need ms delay function from the Main
// extern void delay_ms(unsigned short ms);
//
//Need initialize before use the diaplay function
// void LCMInit(void);
//
//Export these 2 function
// void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
// void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData);
//================================================
//----------------------------
// Include Files
//----------------------------
#include <c8051f320.h>
#include <intrins.h>
//----------------------------
// Global Constants
//----------------------------
// Define control ports and data ports
// P0.5 - digital push-pull (1602)RS
// P0.6 - digital push-pull (1602)RW
// P0.7 - digital push-pull (1602)E
// P1.x - digital push-pull (1602)DATA
// Have to initalize these ports in the Main
//
sbit RS1602 = P0 ^ 5; // Register select signal port
sbit RW1602 = P0 ^ 6; // Data read/write port
sbit E1602 = P0 ^ 7; // Enable signal port
#define DATA1602 P1 // Data port
// Define macro definition basic the selected ports
//
#define W_D_IN P1MDOUT &= 0x00 // Change Data port to open-drain
#define W_D_OUT P1MDOUT |= 0xFF // Change Data port to push-pull
// Define device busy flag
//
#define Busy 0x80
//----------------------------
// Function Prototypes
//----------------------------
// Write data to SMC1602A
//
void WriteDataLCM(unsigned char WDLCM);
// Write command to SMC1602A
//
void WriteCommandLCM(unsigned char WCLCM, unsigned char BusyC);
// Read data from SMC1602A
//
unsigned char ReadDataLCM(void);
// Read command from SMC602A
//
unsigned char ReadStatusLCM(void);
// Initalize SMC1602A
//
void LCMInit(void);
// Display a char at the specified position
//
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
// Display a string at the specified position
//
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData);
// Call a extern ms delay function
//
extern void delay_ms(unsigned short ms);
//----------------------------
// Subroutines
//----------------------------
//-----------------Write Data---------------------
void WriteDataLCM(unsigned char WDLCM)
//------------------------------------------------
{
ReadStatusLCM(); // Detect Busy
W_D_OUT; // Change Data port to push-pull
DATA1602 = WDLCM; // Write data
RS1602 = 1; // LCM_RS = 1;
RW1602 = 0; // LCM_RW = 0;
E1602 = 0; // LCM_E = 0; If SYSCLK is high, add a small delay into here
delay_ms(4);
E1602 = 1; // LCM_E = 1;
}
//----------------Write Command-------------------
void WriteCommandLCM(unsigned char WCLCM, unsigned char BusyC)
//------------------------------------------------
{
if(BusyC) // Decide if detect Busy from parameter
{
ReadStatusLCM(); // Detect Busy
}
W_D_OUT; // Change Data port to push-pull
DATA1602 = WCLCM; // Write command
RS1602 = 0; // LCM_RS = 0;
RW1602 = 0; // LCM_RW = 0;
E1602 = 0; // LCM_E = 0; If SYSCLK is high, add a small delay into here
delay_ms(4);
E1602 = 1; // LCM_E = 1;
}
/*
//------------------Read Data---------------------
unsigned char ReadDataLCM(void)
//------------------------------------------------
{
RS1602 = 1; // LCM_RS = 1;
RW1602 = 1; // LCM_RW = 1;
E1602 = 0; // LCM_E = 0; If SYSCLK is high, add a small delay into here
delay_ms(4);
E1602 = 1; // LCM_E = 1;
W_D_IN; // Change Data port to open-drain
return DATA1602; // Return data
}
*/
//-----------------Read Command-------------------
unsigned char ReadStatusLCM(void)
//------------------------------------------------
{
W_D_IN; // Change Data port to open-drain
RS1602 = 0; // LCM_RS = 0;
RW1602 = 1; // LCM_RW = 1;
E1602 = 0; // LCM_E = 0; If SYSCLK is high, add a small delay into here
delay_ms(4);
E1602 = 1; // LCM_E = 1;
while(DATA1602 & Busy); // Detect Busy
return DATA1602; // Return data
}
//------------------Initalize---------------------
void LCMInit(void)
//------------------------------------------------
{
DATA1602 = 0;
WriteCommandLCM(0x38, 0); // Set display mode 3 times, no detect Busy
delay_ms(5);
WriteCommandLCM(0x38, 0);
delay_ms(5);
WriteCommandLCM(0x38, 0);
delay_ms(5);
// Keep above code
WriteCommandLCM(0x38, 1); // Set display mode(8 bits, 2 rows, 5x7), begin detect Busy everytime
WriteCommandLCM(0x08, 1); // Close display
WriteCommandLCM(0x01, 1); // Clear screen
WriteCommandLCM(0x06, 1); // Show the position of cursor move
WriteCommandLCM(0x0C, 1); // Show boot-strap cursor setting
WriteCommandLCM(0x80, 1); // The first position is row 1 line 1
}
//----------------Display one char----------------
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
//------------------------------------------------
{
Y &= 0x1;
X &= 0xF; // Revise X<=15 Y<=1
if(Y) // Add 0x40 to address for display row 2
{
X |= 0x40;
}
X |= 0x80; // Count the address
WriteCommandLCM(X, 0); // Send the address to SMC1602A
WriteDataLCM(DData); // Write the char to SMC1602A
}
//----------------Display list char---------------
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData)
//------------------------------------------------
{
unsigned char ListLength = 0;
Y &= 0x1;
X &= 0xF; // Revise X<=15 Y<=1
while(DData[ListLength] >= 0x20) // If the string end, quit
{
if(X <= 0xF)
{
DisplayOneChar(X, Y, DData[ListLength]); // Display one char
ListLength++;
X++;
}
}
} |
|