The LCD screen is JM12864 or FYD12864 (with font library). I have used both models without issues. 4 rows * 8 columns of Chinese characters = 32 serial communication interfaces P1.5–P1.7, which can be modified according to your circuit.
#include
#define uchar unsigned char
void LCD_ini();
void ascii_change(void);
void delay();
void wri_add(uchar com);
void wri_dat(uchar com1);
void shan(void);
void disp();
void tkey(void);
sbit cs = P1^7;
sbit sid = P1^6;
sbit sclk = P1^5;
bit flag = 1;
uchar dat, count, f = 1; // f tests which unit is currently blinking
uchar data clock[3] = {23, 45, 12};
uchar code clockname[10] = {“Beijing Time:”};
uchar data num[6];
/******* Main Program *************/
void main() {
lcd_ini();
count = 10; // Machine cycle is 1us, each timer is 50ms, this variable is used to control the loop count, assigned to 20 below, for a total of 1 second
TMOD = 0x01;
TL0 = 0xB0;
TH0 = 0x3C;
EA = 1;
ET0 = 1;
IT0 = 1;
EX0 = 1;
TR0 = 1;
while (1) {
back: ascii_change();
disp();
delay();
if (flag == 1)
goto back;
tkey();
shan();
delay();
}
}
/**** LCD Initialization *******/
void lcd_ini() {
wri_add(0x30);
delay();
wri_add(0x0c);
delay();
wri_add(0x01);
delay();
wri_add(0x06);
delay();
}
/******** Timer Program *************/
void timer1() interrupt 1 using 2 {
TL0 = 0xB0;
TH0 = 0x3C;
count–;
if (count == 0) {
count = 10;
clock[2]++; // seconds //
}
else
goto out;
if (clock[2] == 60) {
clock[2] = 0;
clock[1]++; // minutes //
}
if (clock[1] == 60)
{
clock[1] = 0;
clock[0]++;
}
if (clock[0] == 24) // hours //
clock[0] = 0;
out: _nop_();
}
/******* Convert Tens and Units to ASCII Code ************/
void ascii_change(void) {
num[5] = clock[2] – (clock[2] / 10) * 10 + 0x30;
num[4] = clock[2] / 10 + 0x30;
num[3] = clock[1] – (clock[1] / 10) * 10 + 0x30;
num[2] = clock[1] / 10 + 0x30;
num[1] = clock[0] – (clock[0] / 10) * 10 + 0x30;
num[0] = clock[0] / 10 + 0x30;
}
/******** Delay Program *************/
void delay() {
uchar i, j;
for (i = 250; i > 0; i–)
for (j = 250; j > 0; j–);
}
/***** Write Address *********/
void wri_add(uchar com) {
uchar i, j, k;
cs = 0;
cs = 1;
dat = 0xf8;
for (i = 1; i <= 8; i++) {
sid = (bit)(dat & 0x80);
sclk = 0;
sclk = 1;
sclk = 0;
dat = dat << 1;
}
dat = com;
dat = dat & 0xf0;
for (j = 1; j <= 8; j++) {
sid = (bit)(dat & 0x80);
sclk = 0;
sclk = 1;
sclk = 0;
dat = dat << 1;
}
dat = com;
dat = _cror_(dat, 4); // This is for swapping high and low four bits
dat = dat & 0xf0;
for (k = 1; k <= 8; k++) {
sid = (bit)(dat & 0x80);
sclk = 0;
sclk = 1;
sclk = 0;
dat = dat << 1;
}
}
/********* Write Data *************/
void wri_dat(uchar com1) {
uchar i, j, k;
cs = 0;
cs = 1;
dat = 0xfa;
for (i = 1; i <= 8; i++) {
sid = (bit)(dat & 0x80);
sclk = 0;
sclk = 1;
sclk = 0;
dat = dat << 1;
}
dat = com1;
dat = dat & 0xf0;
for (j = 1; j <= 8; j++) {
sid = (bit)(dat & 0x80);
sclk = 0;
sclk = 1;
sclk = 0;
dat = dat << 1;
}
dat = com1;
dat = _cror_(dat, 4); // This is for swapping high and low four bits
dat = dat & 0xf0;
for (k = 1; k <= 8; k++) {
sid = (bit)(dat & 0x80);
sclk = 0;
sclk = 1;
sclk = 0;
dat = dat << 1;
}
}
/****** Display Program ***********/
void disp() {
uchar i, k = 0;
wri_add(0x80);
for (i = 1; i <= 9; i++)
wri_dat(clockname[i – 1]);
wri_add(0x90);
for (i = 1; i <= 6; i++) {
k++;
if (k == 3 || k == 5)
wri_dat(clockname[8]); // Colon between time.
wri_dat(num[i – 1]);
}
}
/******* Blinking Program *************************/
void shan(void) {
uchar i, k = 0;
wri_add(0x90);
if (f == 1) {
num[0] = ‘ ‘;
num[1] = ‘ ‘;
}
else
goto next;
for (i = 1; i <= 6; i++) {
k++;
if (k == 3 || k == 5)
wri_dat(clockname[8]); // Colon between time.
wri_dat(num[i – 1]);
}
goto return1;
next: if (f == 2) {
num[2] = ‘ ‘;
num[3] = ‘ ‘;
}
else
goto next1;
for (i = 1; i <= 6; i++) {
k++;
if (k == 3 || k == 5)
wri_dat(clockname[8]); // Colon between time.
wri_dat(num[i – 1]);
}
goto return1;
next1: if (f == 3) {
num[4] = ‘ ‘;
num[5] = ‘ ‘;
}
else
goto return1;
for (i = 1; i <= 6; i++) {
k++;
if (k == 3 || k == 5)
wri_dat(clockname[8]); // Colon between time.
wri_dat(num[i – 1]);
}
return1: _nop_();
}
/******* External Interrupt ***********/
void intr0() interrupt 0 using 2 {
flag = ~flag; // Check if the blink bit //
TR0 = ~TR0; // Blink timer, otherwise start timing
f = 1;
}
/********** Key Program ************/
void tkey(void) {
uchar judcekey;
judcekey = P1 & 0x0f;
if (judcekey == 0x0f)
goto return2;
/******* Shift Key *********/
if (judcekey == 0x0e)
f++;
if (f == 4)
f = 1;
/********** Add One Key *********/
if (judcekey == 0x0d) { clock[f – 1]++; }
if (f == 1) { if (clock[f – 1] == 24) { clock[f – 1] = 0; }}
} else { if (clock[f – 1] == 60) clock[f – 1] = 0; }
/****** Subtract One Key ***********/
if (judcekey == 0x0b) { clock[f – 1]–; }
if (f == 1) { if (clock[f – 1] == 0xff) { clock[f – 1] = 23; }}
} else { if (clock[f – 1] == 0xff) clock[f – 1] = 59; }
return2: _nop_();
}
To facilitate everyone’s better learning, Changxue Electronics Network has specifically added a public account for microcontrollers and EDA, pushing relevant knowledge daily, hoping to help your studies!