目录

前言:本代码涉及的主要知识:proteus模拟实验板:代码(实验板实现代码):代码(时间 + 日期):代码(时间显示 + 日期显示 + 按键控制):代码(温度显示):代码汇总(时间显示 + 日期显示 + 按键控制 + 温度显示)[有bug]:代码汇总 正解(时间显示 + 日期显示 + 按键控制 + 温度显示):总结:

前言:

设计本代码的主要目的是为了完成期末作业,即在液晶显示屏上显示、时间、日期、温度,以及用按键控制时间、温度的显示。总的来说就是对前面学习计数的糅合,本代码实现的是显示时间,并能在实验板上成功显示。

本代码涉及的主要知识:

1.液晶显示屏模块应用

主要是学会如何在液晶显示屏上显示内容

2.T1中断函数的使用

主要通过T1中断函数记录时间,即通过每次的溢出参产生中断来记录秒的变化。

3.通过数组记录时、分、秒,再通过%、/来取值显示

4.行列键盘

5.温度显示

proteus模拟实验板:

上述模拟板是某个大哥按照实验板模拟的,主要以它代替真实实验板。

代码(实验板实现代码):

#include

unsigned char code table[]="0123456789:-";

sbit RS=P2^6;

sbit RW=P2^5;

sbit EN=P2^7;

unsigned char count = 0;

unsigned char time[] = {23, 58, 50};//初始时间

void delay(unsigned int x){//延时函数

unsigned int i;

for (i=x; i>0;i--);

}

void write_com (unsigned char com){//写指令函数

P0= com;

RS=0;RW=0;EN=1;

delay(200);

EN=0;

}

void write_date(unsigned char dat) {//写数据函数

P0 = dat;

RS=1;RW=0;EN=1;

delay (200);

EN=0;

}

void init(){//初始化

write_com(0x01);

write_com(0x38);

write_com(0x0f);

write_com(0x06);

}

timer1() interrupt 3{//T1中断函数

TH1 = 0x3C;

TL1 = 0xB0;

count = count + 1;

if(count == 20){

count = 0;

time[2] = time[2] + 1;

if(time[2] >= 60){

time[2] = 0;

time[1] = time[1] + 1;

if(time[1] >= 60){

time[1] = 0;

time[0] = time[0] + 1;

if(time[0] >= 24){

time[0] = 0;

}

}

}

}

}

void dispaly(){//显示时间函数

init();

write_com(0x80);

write_date(table[time[0] / 10]);

delay(3000);

write_date(table[time[0] % 10]);

delay(3000);

write_date(table[10]);

delay(3000);

write_date(table[time[1] / 10]);

delay(3000);

write_date(table[time[1] % 10]);

delay(3000);

write_date(table[10]);

delay(3000);

write_date(table[time[2] / 10]);

delay(3000);

write_date(table[time[2] % 10]);

delay(3000);

write_com(0x02);

}

void intpt_begin(){//开中断

TMOD = 0x10;

TH1 = 0x3C;

TL1 = 0xB0;

EA = 1;

ET1 = 1;

TR1 = 1;

}

void main()

{

intpt_begin();

while(1){

dispaly();

}

}

后续的显示日期和显示时间的原理大致相同,添加按键也无非多用几个引脚,难点主要是温度显示,后续有时间学习一下。

代码(时间 + 日期):

#include

unsigned char code table[]="0123456789:/";

sbit RS=P2^6;

sbit RW=P2^5;

sbit EN=P2^7;

unsigned char count = 0;

unsigned char time[] = {23, 58, 50};

unsigned int date[] = {2023, 5, 20};

unsigned char year[] = {0, 0, 0, 0};

unsigned int years = 0;

unsigned int i;

void delay(unsigned int x){//延时函数

for (i=x; i>0;i--);

}

void write_com (unsigned char com){//写指令函数

P0 = com;

RS = 0;RW = 0;EN = 1;

delay(200);

EN = 0;

}

void write_date(unsigned char dat) {//写数据函数

P0 = dat;

RS = 1;RW = 0;EN = 1;

delay (200);

EN = 0;

}

void init(){//初始化

write_com(0x01);

write_com(0x38);

write_com(0x0f);

write_com(0x06);

}

timer1() interrupt 3{//T1中断函数

TH1 = 0x3C;

TL1 = 0xB0;

count = count + 1;

if(count == 20){

count = 0;

time[2] = time[2] + 1;

if(time[2] >= 60){

time[2] = 0;

time[1] = time[1] + 1;

if(time[1] >= 60){

time[1] = 0;

time[0] = time[0] + 1;

if(time[0] >= 24){

time[0] = 0;

}

}

}

}

}

void dispaly_1(){//显示时间函数,显示第一层

write_com(0x80);//起点为第一行第一个字符

write_date(table[time[0] / 10]);

delay(3000);

write_date(table[time[0] % 10]);

delay(3000);

write_date(table[10]);

delay(3000);

write_date(table[time[1] / 10]);

delay(3000);

write_date(table[time[1] % 10]);

delay(3000);

write_date(table[10]);

delay(3000);

write_date(table[time[2] / 10]);

delay(3000);

write_date(table[time[2] % 10]);

delay(3000);

write_com(0x02);

}

void dispaly_2(){

write_com(0xc0); //起点为第二行第一个字符

years = date[0];

for(i = 0; i < 4; i ++){

year[i] = years % 10;

years = years / 10;

}

// for(i = 3; i >= 0; i --) {

// write_date(table[year[i]]);

// delay(3000);

// }

write_date(table[year[3]]);

delay(3000);

write_date(table[year[2]]);

delay(3000);

write_date(table[year[1]]);

delay(3000);

write_date(table[year[0]]);

delay(3000);

write_date(table[11]);

delay(3000);

write_date(table[date[1] / 10]);

delay(3000);

write_date(table[date[1] % 10]);

delay(3000);

write_date(table[11]);

delay(3000);

write_date(table[date[2] / 10]);

delay(3000);

write_date(table[date[2] % 10]);

delay(3000);

}

void intpt_begin(){//开中断

TMOD = 0x10;

TH1 = 0x3C;

TL1 = 0xB0;

EA = 1;

ET1 = 1;

TR1 = 1;

}

void main()

{

intpt_begin();//开中断

while(1){

init();

dispaly_1();

dispaly_2();

}

}

代码(时间显示 + 日期显示 + 按键控制):

1、按键控制主要基于单片机的行列键盘的原理,即通过扫描找到键位。 由于实验板的按键排布与书本上的案件排布不同,所以要对书上的代码进行一定的修改。

2.本代码设立了七个按键(从左至右,从上至下),分别能对时间的时、分、秒和日期的年、月、日进行控制。

3.本代码时间的变化会影响日期的变化,年份(平闰)会影响二月份(28、29)天数的变化。

#include

unsigned char code table[]="0123456789:/";

sbit RS=P2^6;

sbit RW=P2^5;

sbit EN=P2^7;

unsigned char count = 0;

unsigned char time[] = {23, 59, 30};

unsigned int date[] = {2023, 12, 31};

unsigned char year[] = {0, 0, 0, 0};

unsigned int years = 0;

unsigned int i,j;

unsigned char net = 0;//按键

char key_buf[]={0x77, 0x7b, 0x7d, 0x7e, 0xb7, 0xbb, 0xbd, 0xbe, 0xd7, 0xdb, 0xdd, 0xde, 0xe7, 0xeb, 0xed, 0xee};//0-15

char month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

char key = 0;

void delay(unsigned int x){//延时函数

for (i=x; i>0;i--);

}

void month_change(){//判别闰平年

if(date[0] % 4 == 0 && date[0] % 100 != 0 || date[0] % 400 == 0) month[2] = 29;

else month[2] = 28;

}

void write_com (unsigned char com){//写指令函数

P0 = com;

RS = 0;RW = 0;EN = 1;

delay(200);

EN = 0;

}

void write_date(unsigned char dat) {//写数据函数

P0 = dat;

RS = 1;RW = 0;EN = 1;

delay (200);

EN = 0;

}

void init(){//初始化

write_com(0x01);

write_com(0x38);

write_com(0x0f);

write_com(0x06);

}

timer1() interrupt 3{//T1中断函数

TH1 = 0x3C;

TL1 = 0xB0;

count = count + 1;

if(count == 20){

count = 0;

time[2] = time[2] + 1;

if(time[2] >= 60){

time[2] = 0;

time[1] = time[1] + 1;

if(time[1] >= 60){

time[1] = 0;

time[0] = time[0] + 1;

if(time[0] >= 24){

time[0] = 0;

date[2] = date[2] + 1;

if(date[2] >= month[date[1]] + 1){

date[2] = 1;

date[1] = date[1] + 1;

if(date[1] >= 13){

date[1] = 1;

date[0] = date[0] + 1;

if(date[0] >= 9999){

date[0] = 2023;

}

}

}

}

}

}

}

}

void dispaly_1(){//显示时间函数,显示第一层

write_com(0x80);//起点为第一行第一个字符

write_date(table[time[0] / 10]);

delay(6000);

write_date(table[time[0] % 10]);

delay(6000);

write_date(table[10]);

delay(6000);

write_date(table[time[1] / 10]);

delay(6000);

write_date(table[time[1] % 10]);

delay(6000);

write_date(table[10]);

delay(6000);

write_date(table[time[2] / 10]);

delay(6000);

write_date(table[time[2] % 10]);

delay(6000);

write_com(0x02);

}

void dispaly_2(){

write_com(0xc0); //起点为第二行第一个字符

years = date[0];

for(i = 0; i < 4; i ++){

year[i] = years % 10;

years = years / 10;

}

write_date(table[year[3]]);

delay(6000);

write_date(table[year[2]]);

delay(6000);

write_date(table[year[1]]);

delay(6000);

write_date(table[year[0]]);

delay(6000);

write_date(table[11]);

delay(6000);

write_date(table[date[1] / 10]);

delay(6000);

write_date(table[date[1] % 10]);

delay(6000);

write_date(table[11]);

delay(6000);

write_date(table[date[2] / 10]);

delay(6000);

write_date(table[date[2] % 10]);

delay(6000);

}

void intpt_begin(){//开中断

TMOD = 0x10;

TH1 = 0x3C;

TL1 = 0xB0;

EA = 1;

ET1 = 1;

TR1 = 1;

}

char getKey(void)

{

char key_scan[]={0xef,0xdf,0xbf,0x7f};

for(i = 0;i < 4; i++)

{

P1 = key_scan[i];

if((P1 & 0x0f) != 0x0f)

{

for(j = 0; j < 16; j++)

{

if(key_buf[j] == P1)

return j;

}

}

}

return -1;

}

void key_control(){

if(key == 0){

time[0] = time[0] + 1;

if(time[0] >= 24){

time[0] = 0;

}

}

if(key == 1){

time[1] = time[1] + 1;

if(time[1] >= 60){

time[1] = 0;

}

}

if(key == 2){

time[2] = 0;

}

if(key == 3){

date[0] = date[0] + 1;

if(date[0] >= 9999){

date[0] = 2023;

}

}

if(key == 4){

date[0] = date[0] - 1;

if(date[0] <= 1000){

date[0] = 2023;

}

}

if(key == 5){

date[1] = date[1] + 1;

if(date[1] >= 13){

date[1] = 1;

}

}

if(key == 6){

date[2] = date[2] + 1;

if(date[2] >= month[date[1]] + 1){

date[2] = 1;

}

}

}

void main()

{

intpt_begin();//开中断

while(1){

init();

month_change();

dispaly_1();

dispaly_2();

key = getKey();

if(key != -1) key_control();

}

}

—— 2023.5.21

代码(温度显示):

主要通过对温度传感器的控制让其读取温度,再将读取的温度转化,并在显示屏上显示

#include

#define uchar unsigned char

#define uint unsigned int

typedef unsigned char uint8;

typedef unsigned int uint16;

sbit DQ=P3^7; //定义数据线

int j = 0;

uint8 temp[]= "wd:00";

sbit RS=P2^6;

sbit RW=P2^5;

sbit EN=P2^7;

long tmp = 0; //存储温度值

void delay(uint16 time)

{

while(time--);

}

uint8 DS18B20_init()

{

uint8 ans;

DQ = 1;

delay(1);

DQ = 0;

delay(100);

DQ = 1;

delay(6);

ans = DQ;

delay(100);

if(!ans)

return 1;

else

return 0;

}

void DS18B20_write(uint8 date)

{

uint8 i;

DQ = 1;

delay(1);

for(i=0;i<8;i++) //根据时序将数据从低到高一位一位发送出来

{

DQ = 0;

if(date&0x01) //从低到高取出数据的每位

DQ = 1;

else

DQ = 0;

delay(10);

DQ = 1;

date >>= 1;

delay(1);

}

}

uint8 DS18B20_read()

{

uint8 i,date = 0;

DQ = 1; //释放总线

delay(1);

for(i=0;i<8;i++) //根据时序将数据从低到高一位一位接收

{

DQ = 0;

date >>= 1;

DQ = 1;

if(DQ)

date |= 0x80; //将data的一位置1

delay(8);

DQ = 1;

delay(1);

}

return date; //返回读出的数

}

void DS18B20_check()

{

uint8 date1,date2;

float ta;

if(DS18B20_init())

{

DS18B20_write(0xcc); //跳过序列号

DS18B20_write(0x44); //启动温度转换

DS18B20_init(); //复位

DS18B20_write(0xcc); //跳过序列号

DS18B20_write(0xbe); //启动读取温度

date1 = DS18B20_read(); //读取两个温度字节

date2 = DS18B20_read();

tmp = date2;

tmp <<= 8;

tmp = tmp|date1;

ta = tmp*0.0625;

tmp = ta*1000;

}

}

void write_com (unsigned char com){//写指令函数

P0 = com;

RS = 0;RW = 0;EN = 1;

delay(200);

EN = 0;

}

void write_date(unsigned char dat) {//写数据函数

P0 = dat;

RS = 1;RW = 0;EN = 1;

delay (200);

EN = 0;

}

void init(){//初始化

write_com(0x01);

write_com(0x38);

write_com(0x0f);

write_com(0x06);

}

void dispaly_3(){//显示时间函数,显示第一层

temp[3] = 0x30 + tmp / 10000;

temp[4] = 0x30 + tmp / 1000 % 10;

write_com(0x80);//起点为第一行第一个字符

for(j = 0; j < 5; j ++){

write_date(temp[j]);

delay(3000);

}

write_com(0x02);

}

void main()

{

DS18B20_init(); //DS18B20初始化

DS18B20_write(0xcc); //跳过序列号

DS18B20_write(0x44); //启动温度转换

while(1){

init();

DS18B20_check(); //从DS18B20中读取温度

dispaly_3();

}

}

———— 2023.5.21

本代码参考:基于51单片机的温控系统

代码汇总(时间显示 + 日期显示 + 按键控制 + 温度显示)[有bug]:

温度显示需要在上述代码的基础上往后移动11位 此代码秒不能动,还未发现问题所在,正在寻找

#include

#define uchar unsigned char

#define uint unsigned int

typedef unsigned char uint8;

typedef unsigned int uint16;

sbit DQ=P3^7; //定义数据线

int j = 0;

int k = 0;

uint8 temp[]= "wd:00";

sbit RS=P2^6;

sbit RW=P2^5;

sbit EN=P2^7;

long tmp = 0; //存储温度值

unsigned int years = 0;

unsigned char code table[]="0123456789:/";

unsigned char count = 0;

unsigned char time[] = {23, 59, 30};

unsigned int date[] = {2023, 12, 31};

unsigned char year[] = {0, 0, 0, 0};

char key_buf[]={0x77, 0x7b, 0x7d, 0x7e, 0xb7, 0xbb, 0xbd, 0xbe, 0xd7, 0xdb, 0xdd, 0xde, 0xe7, 0xeb, 0xed, 0xee};//0-15

char month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

char key = 0;

void delay(unsigned int time)

{

while(time--);

}

uint8 DS18B20_init()

{

uint8 ans;

DQ = 1;

delay(1);

DQ = 0;

delay(100);

DQ = 1;

delay(6);

ans = DQ;

delay(100);

if(!ans)

return 1;

else

return 0;

}

void DS18B20_write(uint8 date)

{

uint8 i;

DQ = 1;

delay(1);

for(i=0;i<8;i++) //根据时序将数据从低到高一位一位发送出来

{

DQ = 0;

if(date&0x01) //从低到高取出数据的每位

DQ = 1;

else

DQ = 0;

delay(10);

DQ = 1;

date >>= 1;

delay(1);

}

}

uint8 DS18B20_read()

{

uint8 i,date = 0;

DQ = 1; //释放总线

delay(1);

for(i=0;i<8;i++) //根据时序将数据从低到高一位一位接收

{

DQ = 0;

date >>= 1;

DQ = 1;

if(DQ)

date |= 0x80; //将data的一位置1

delay(8);

DQ = 1;

delay(1);

}

return date; //返回读出的数

}

void DS18B20_check()

{

uint8 date1,date2;

float ta;

if(DS18B20_init())

{

DS18B20_write(0xcc); //跳过序列号

DS18B20_write(0x44); //启动温度转换

DS18B20_init(); //复位

DS18B20_write(0xcc); //跳过序列号

DS18B20_write(0xbe); //启动读取温度

date1 = DS18B20_read(); //读取两个温度字节

date2 = DS18B20_read();

tmp = date2;

tmp <<= 8;

tmp = tmp|date1;

ta = tmp*0.0625;

tmp = ta*1000;

}

}

void write_com (unsigned char com){//写指令函数

P0 = com;

RS = 0;RW = 0;EN = 1;

delay(200);

EN = 0;

}

void write_date(unsigned char dat) {//写数据函数

P0 = dat;

RS = 1;RW = 0;EN = 1;

delay (200);

EN = 0;

}

void init(){//初始化

write_com(0x01);

write_com(0x38);

write_com(0x0f);

write_com(0x06);

}

void dispaly_3(){//显示时间函数,显示第一层

temp[3] = 0x30 + tmp / 10000;

temp[4] = 0x30 + tmp / 1000 % 10;

write_com(0x8b);//起点为第一行第一个字符

for(j = 0; j < 5; j ++){

write_date(temp[j]);

delay(3000);

}

write_com(0x02);

}

void month_change(){//判别闰平年

if(date[0] % 4 == 0 && date[0] % 100 != 0 || date[0] % 400 == 0) month[2] = 29;

else month[0] = 28;

}

timer1() interrupt 3{//T1中断函数

TH1 = 0x3C;

TL1 = 0xB0;

count = count + 1;

if(count == 20){

count = 0;

time[2] = time[2] + 1;

if(time[2] >= 60){

time[2] = 0;

time[1] = time[1] + 1;

if(time[1] >= 60){

time[1] = 0;

time[0] = time[0] + 1;

if(time[0] >= 24){

time[0] = 0;

date[2] = date[2] + 1;

if(date[2] >= month[date[1]] + 1){

date[2] = 1;

date[1] = date[1] + 1;

if(date[1] >= 13){

date[1] = 1;

date[0] = date[0] + 1;

if(date[0] >= 9999){

date[0] = 2023;

}

}

}

}

}

}

}

}

void dispaly_1(){//显示时间函数,显示第一层

write_com(0x80);//起点为第一行第一个字符

write_date(table[time[0] / 10]);

delay(6000);

write_date(table[time[0] % 10]);

delay(6000);

write_date(table[10]);

delay(6000);

write_date(table[time[1] / 10]);

delay(6000);

write_date(table[time[1] % 10]);

delay(6000);

write_date(table[10]);

delay(6000);

write_date(table[time[2] / 10]);

delay(6000);

write_date(table[time[2] % 10]);

delay(6000);

write_com(0x02);

}

void dispaly_2(){

write_com(0xc0); //起点为第二行第一个字符

years = date[0];

for(j = 0; j < 4; j ++){

year[j] = years % 10;

years = years / 10;

}

write_date(table[year[3]]);

delay(6000);

write_date(table[year[2]]);

delay(6000);

write_date(table[year[1]]);

delay(6000);

write_date(table[year[0]]);

delay(6000);

write_date(table[11]);

delay(6000);

write_date(table[date[1] / 10]);

delay(6000);

write_date(table[date[1] % 10]);

delay(6000);

write_date(table[11]);

delay(6000);

write_date(table[date[2] / 10]);

delay(6000);

write_date(table[date[2] % 10]);

delay(6000);

}

void intpt_begin(){//开中断

TMOD = 0x10;

TH1 = 0x3C;

TL1 = 0xB0;

EA = 1;

ET1 = 1;

TR1 = 1;

}

char getKey(void)

{

char key_scan[]={0xef,0xdf,0xbf,0x7f};

for(k = 0;k < 4; k++)

{

P1 = key_scan[k];

if((P1 & 0x0f) != 0x0f)

{

for(j = 0; j < 16; j++)

{

if(key_buf[j] == P1)

return j;

}

}

}

return -1;

}

void key_control(){

if(key == 0){

time[0] = time[0] + 1;

if(time[0] >= 24){

time[0] = 0;

}

}

if(key == 1){

time[1] = time[1] + 1;

if(time[1] >= 60){

time[1] = 0;

}

}

if(key == 2){

time[2] = 0;

}

if(key == 3){

date[0] = date[0] + 1;

if(date[0] >= 9999){

date[0] = 2023;

}

}

if(key == 4){

date[0] = date[0] - 1;

if(date[0] <= 1000){

date[0] = 2023;

}

}

if(key == 5){

date[1] = date[1] + 1;

if(date[1] >= 13){

date[1] = 1;

}

}

if(key == 6){

date[2] = date[2] + 1;

if(date[2] >= month[date[1]] + 1){

date[2] = 1;

}

}

}

void main()

{

DS18B20_init(); //DS18B20初始化

DS18B20_write(0xcc); //跳过序列号

DS18B20_write(0x44); //启动温度转换

while(1){

init();

month_change();

dispaly_1();

DS18B20_check(); //从DS18B20中读取温度

dispaly_3();

dispaly_2();

key = getKey();

if(key != -1) key_control();

}

}

—— 2023.5.21

代码汇总 正解(时间显示 + 日期显示 + 按键控制 + 温度显示):

解决了显示问题,让整个显示过程更加连贯 处理方法:把中断函数开启函数放到了while循环的外部。

#include

unsigned char code table[]="0123456789:/";

sbit RS=P2^6;

sbit RW=P2^5;

sbit EN=P2^7;

unsigned char count = 0;

unsigned char time[] = {23, 59, 30};

unsigned int date[] = {2023, 12, 31};

unsigned char year[] = {0, 0, 0, 0};

unsigned int years = 0;

unsigned int i,j;

unsigned char net = 0;//按键

char key_buf[]={0x77, 0x7b, 0x7d, 0x7e, 0xb7, 0xbb, 0xbd, 0xbe, 0xd7, 0xdb, 0xdd, 0xde, 0xe7, 0xeb, 0xed, 0xee};//0-15

char month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

char key = 0;

#define uchar unsigned char

#define uint unsigned int

typedef unsigned char uint8;

typedef unsigned int uint16;

sbit DQ=P3^7; //定义数据线

char k = 0;

uint8 temp[]= "wd:00";

long tmp = 0; //存储温度值

void delay(unsigned int x){//延时函数

for (i=x; i>0;i--);

}

void month_change(){//判别闰平年

if(date[0] % 4 == 0 && date[0] % 100 != 0 || date[0] % 400 == 0) month[2] = 29;

else month[2] = 28;

}

void write_com (unsigned char com){//写指令函数

P0 = com;

RS = 0;RW = 0;EN = 1;

delay(200);

EN = 0;

}

void write_date(unsigned char dat) {//写数据函数

P0 = dat;

RS = 1;RW = 0;EN = 1;

delay (200);

EN = 0;

}

void init(){//初始化

write_com(0x01);

write_com(0x38);

write_com(0x0f);

write_com(0x06);

}

timer1() interrupt 3{//T1中断函数

TH1 = 0x3C;

TL1 = 0xB0;

count = count + 1;

if(count == 20){

count = 0;

time[2] = time[2] + 1;

if(time[2] >= 60){

time[2] = 0;

time[1] = time[1] + 1;

if(time[1] >= 60){

time[1] = 0;

time[0] = time[0] + 1;

if(time[0] >= 24){

time[0] = 0;

date[2] = date[2] + 1;

if(date[2] >= month[date[1]] + 1){

date[2] = 1;

date[1] = date[1] + 1;

if(date[1] >= 13){

date[1] = 1;

date[0] = date[0] + 1;

if(date[0] >= 9999){

date[0] = 2023;

}

}

}

}

}

}

}

}

void dispaly_1(){//显示时间函数,显示第一层

write_com(0x80);//起点为第一行第一个字符

write_date(table[time[0] / 10]);

delay(6000);

write_date(table[time[0] % 10]);

delay(6000);

write_date(table[10]);

delay(6000);

write_date(table[time[1] / 10]);

delay(6000);

write_date(table[time[1] % 10]);

delay(6000);

write_date(table[10]);

delay(6000);

write_date(table[time[2] / 10]);

delay(6000);

write_date(table[time[2] % 10]);

delay(6000);

write_com(0x02);

}

void dispaly_2(){

write_com(0xc0); //起点为第二行第一个字符

years = date[0];

for(i = 0; i < 4; i ++){

year[i] = years % 10;

years = years / 10;

}

write_date(table[year[3]]);

delay(6000);

write_date(table[year[2]]);

delay(6000);

write_date(table[year[1]]);

delay(6000);

write_date(table[year[0]]);

delay(6000);

write_date(table[11]);

delay(6000);

write_date(table[date[1] / 10]);

delay(6000);

write_date(table[date[1] % 10]);

delay(6000);

write_date(table[11]);

delay(6000);

write_date(table[date[2] / 10]);

delay(6000);

write_date(table[date[2] % 10]);

delay(6000);

}

void intpt_begin(){//开中断

TMOD = 0x10;

TH1 = 0x3C;

TL1 = 0xB0;

EA = 1;

ET1 = 1;

TR1 = 1;

}

char getKey(void)

{

char key_scan[]={0xef,0xdf,0xbf,0x7f};

for(k = 0;k < 4; k++)

{

P1 = key_scan[k];

if((P1 & 0x0f) != 0x0f)

{

for(j = 0; j < 16; j++)

{

if(key_buf[j] == P1)

return j;

}

}

}

return -1;

}

void key_control(){

if(key == 0){

time[0] = time[0] + 1;

if(time[0] >= 24){

time[0] = 0;

}

}

if(key == 1){

time[1] = time[1] + 1;

if(time[1] >= 60){

time[1] = 0;

}

}

if(key == 2){

time[2] = 0;

}

if(key == 3){

date[0] = date[0] + 1;

if(date[0] >= 9999){

date[0] = 2023;

}

}

if(key == 4){

date[0] = date[0] - 1;

if(date[0] <= 1000){

date[0] = 2023;

}

}

if(key == 5){

date[1] = date[1] + 1;

if(date[1] >= 13){

date[1] = 1;

}

}

if(key == 6){

date[2] = date[2] + 1;

if(date[2] >= month[date[1]] + 1){

date[2] = 1;

}

}

}

uint8 DS18B20_init()

{

uint8 ans;

DQ = 1;

delay(1);

DQ = 0;

delay(100);

DQ = 1;

delay(6);

ans = DQ;

delay(100);

if(!ans)

return 1;

else

return 0;

}

void DS18B20_write(uint8 date)

{

uint8 i;

DQ = 1;

delay(1);

for(i=0;i<8;i++) //根据时序将数据从低到高一位一位发送出来

{

DQ = 0;

if(date&0x01) //从低到高取出数据的每位

DQ = 1;

else

DQ = 0;

delay(10);

DQ = 1;

date >>= 1;

delay(1);

}

}

uint8 DS18B20_read()

{

uint8 i,date = 0;

DQ = 1; //释放总线

delay(1);

for(i=0;i<8;i++) //根据时序将数据从低到高一位一位接收

{

DQ = 0;

date >>= 1;

DQ = 1;

if(DQ)

date |= 0x80; //将data的一位置1

delay(8);

DQ = 1;

delay(1);

}

return date; //返回读出的数

}

void DS18B20_check()

{

uint8 date1,date2;

float ta;

if(DS18B20_init())

{

DS18B20_write(0xcc); //跳过序列号

DS18B20_write(0x44); //启动温度转换

DS18B20_init(); //复位

DS18B20_write(0xcc); //跳过序列号

DS18B20_write(0xbe); //启动读取温度

date1 = DS18B20_read(); //读取两个温度字节

date2 = DS18B20_read();

tmp = date2;

tmp <<= 8;

tmp = tmp|date1;

ta = tmp*0.0625;

tmp = ta*1000;

}

}

void dispaly_3(){//显示温度

temp[3] = 0x30 + tmp / 10000;

temp[4] = 0x30 + tmp / 1000 % 10;

write_com(0x8b);//起点为第一行第十一个字符

for(j = 0; j < 5; j ++){

write_date(temp[j]);

delay(3000);

}

write_com(0x02);

}

void main()

{

DS18B20_init(); //DS18B20初始化

DS18B20_write(0xcc); //跳过序列号

DS18B20_write(0x44); //启动温度转换

intpt_begin();//开中断

init();

while(1){

month_change();

dispaly_1();

DS18B20_check(); //从DS18B20中读取温度

dispaly_3();

dispaly_2();

key = getKey();//扫描键盘

if(key != -1) key_control();

}

}

值得一提的是在模拟板上显示温度是0,实验板上温度完全没有问题,离谱的是实验板和模拟板都没有问题,离谱,还有就是本代码内部的一些语句若用for循环代替会乱码,也很离谱,反正最后能让板子显示就行了。

优化版代码:

优化了按键丝滑度、时间显示丝滑度、感谢给我提供帮助的大哥!

#include

unsigned char code table[]="0123456789:/";

sbit RS=P2^6;

sbit RW=P2^5;

sbit EN=P2^7;

unsigned int count = 0;

unsigned char time[] = {23, 59, 30};

unsigned int date[] = {2023, 12, 31};

unsigned char year[] = {0, 0, 0, 0};

unsigned int years = 0;

unsigned int i,j;

unsigned char net = 0;//按键

char key_buf[]={0x77, 0x7b, 0x7d, 0x7e, 0xb7, 0xbb, 0xbd, 0xbe, 0xd7, 0xdb, 0xdd, 0xde, 0xe7, 0xeb, 0xed, 0xee};//0-15

char month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

char key = 0;

#define uchar unsigned char

#define uint unsigned int

typedef unsigned char uint8;

typedef unsigned int uint16;

sbit DQ=P3^7; //定义数据线

char k = 0;

uint8 temp[]= "T:00";

long tmp = 0; //存储温度值

void delay(unsigned int x){//延时函数

for (i=x; i>0;i--);

}

void month_change(){//判别闰平年

if(date[0] % 4 == 0 && date[0] % 100 != 0 || date[0] % 400 == 0) month[2] = 29;

else month[0] = 28;

}

void write_com (unsigned char com){//写指令函数

P0 = com;

RS = 0;RW = 0;EN = 1;

delay(200);

EN = 0;

}

void write_date(unsigned char dat) {//写数据函数

P0 = dat;

RS = 1;RW = 0;EN = 1;

delay (200);

EN = 0;

}

void init(){//初始化

write_com(0x01);

write_com(0x38);

write_com(0x0c);

write_com(0x06);

}

timer1() interrupt 3{//T1中断函数

TH1 = 0x3C;

TL1 = 0xB0;

count = count + 1;

if(count == 20){

count = 0;

time[2] = time[2] + 1;

if(time[2] >= 60){

time[2] = 0;

time[1] = time[1] + 1;

if(time[1] >= 60){

time[1] = 0;

time[0] = time[0] + 1;

if(time[0] >= 24){

time[0] = 0;

date[2] = date[2] + 1;

if(date[2] >= month[date[1]] + 1){

date[2] = 1;

date[1] = date[1] + 1;

if(date[1] >= 13){

date[1] = 1;

date[0] = date[0] + 1;

if(date[0] >= 9999){

date[0] = 2023;

}

}

}

}

}

}

}

}

void dispaly_1(){//显示时间函数,显示第一层

write_com(0x80);//起点为第一行第一个字符

write_date(table[time[0] / 10]);

delay(1);

write_date(table[time[0] % 10]);

delay(1);

write_date(table[10]);

delay(1);

write_date(table[time[1] / 10]);

delay(1);

write_date(table[time[1] % 10]);

delay(1);

write_date(table[10]);

delay(1);

write_date(table[time[2] / 10]);

delay(1);

write_date(table[time[2] % 10]);

delay(1);

write_com(0x02);

}

void dispaly_2(){

write_com(0xc0); //起点为第二行第一个字符

years = date[0];

for(i = 0; i < 4; i ++){

year[i] = years % 10;

years = years / 10;

}

write_date(table[year[3]]);

delay(1);

write_date(table[year[2]]);

delay(1);

write_date(table[year[1]]);

delay(1);

write_date(table[year[0]]);

delay(1);

write_date(table[11]);

delay(1);

write_date(table[date[1] / 10]);

delay(1);

write_date(table[date[1] % 10]);

delay(1);

write_date(table[11]);

delay(1);

write_date(table[date[2] / 10]);

delay(1);

write_date(table[date[2] % 10]);

delay(1);

}

void intpt_begin(){//开中断

TMOD = 0x10;

TH1 = 0x3C;

TL1 = 0xB0;

EA = 1;

ET1 = 1;

TR1 = 1;

}

char getKey(void)

{

char key_scan[]={0xef,0xdf,0xbf,0x7f};

for(k = 0;k < 4; k++)

{

P1 = key_scan[k];

if((P1 & 0x0f) != 0x0f)

{

for(j = 0; j < 16; j++)

{

if(key_buf[j] == P1)

return j;

}

}

}

return -1;

}

void key_control(){

if(key == 0){

time[0] = time[0] + 1;

if(time[0] >= 24){

time[0] = 0;

}

}

if(key == 1){

time[1] = time[1] + 1;

if(time[1] >= 60){

time[1] = 0;

}

}

if(key == 2){

time[2] = 0;

}

if(key == 3){

date[0] = date[0] + 1;

if(date[0] >= 9999){

date[0] = 2023;

}

}

if(key == 4){

date[0] = date[0] - 1;

if(date[0] <= 1000){

date[0] = 2023;

}

}

if(key == 5){

date[1] = date[1] + 1;

if(date[1] >= 13){

date[1] = 1;

}

}

if(key == 6){

date[2] = date[2] + 1;

if(date[2] >= month[date[1]] + 1){

date[2] = 1;

}

}

delay(10000);

}

uint8 DS18B20_init()

{

uint8 ans;

DQ = 1;

delay(1);

DQ = 0;

delay(100);

DQ = 1;

delay(6);

ans = DQ;

delay(100);

if(!ans)

return 1;

else

return 0;

}

void DS18B20_write(uint8 date)

{

uint8 i;

DQ = 1;

delay(1);

for(i=0;i<8;i++) //根据时序将数据从低到高一位一位发送出来

{

DQ = 0;

if(date&0x01) //从低到高取出数据的每位

DQ = 1;

else

DQ = 0;

delay(10);

DQ = 1;

date >>= 1;

delay(1);

}

}

uint8 DS18B20_read()

{

uint8 i,date = 0;

DQ = 1; //释放总线

delay(1);

for(i=0;i<8;i++) //根据时序将数据从低到高一位一位接收

{

DQ = 0;

date >>= 1;

DQ = 1;

if(DQ)

date |= 0x80; //将data的一位置1

delay(8);

DQ = 1;

delay(1);

}

return date; //返回读出的数

}

void DS18B20_check()

{

uint8 date1,date2;

float ta;

if(DS18B20_init())

{

DS18B20_write(0xcc); //跳过序列号

DS18B20_write(0x44); //启动温度转换

DS18B20_init(); //复位

DS18B20_write(0xcc); //跳过序列号

DS18B20_write(0xbe); //启动读取温度

date1 = DS18B20_read(); //读取两个温度字节

date2 = DS18B20_read();

tmp = date2;

tmp <<= 8;

tmp = tmp|date1;

ta = tmp*0.0625;

tmp = ta*1000;

}

}

void dispaly_3(){//显示温度

temp[2] = 0x30 + tmp / 10000;

temp[3] = 0x30 + tmp / 1000 % 10;

write_com(0x8c);//起点为第一行第十一个字符

write_date(temp[0]);

delay(1);

write_date(temp[1]);

delay(1);

write_date(temp[2]);

delay(1);

write_date(temp[3]);

delay(1);

write_com(0x02);

}

void main()

{

DS18B20_init(); //DS18B20初始化

DS18B20_write(0xcc); //跳过序列号

DS18B20_write(0x44); //启动温度转换

intpt_begin();//开中断

init();

while(1){

month_change();

dispaly_1();

DS18B20_check(); //从DS18B20中读取温度

dispaly_3();

dispaly_2();

key = getKey();//扫描键盘

if(key != -1) key_control();

}

}

——— 2023.5.23

总结:

本代码不足之处还是有的,即采用中断函数测量一秒,不准确。更改方法就是用实验板自带芯片测时间会更准确。

—— 2023.5.23

好文推荐

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。