标题:
12864时钟(定时器)+18b20+按键调时单片机程序
[打印本页]
作者:
1367067553
时间:
2019-5-6 13:35
标题:
12864时钟(定时器)+18b20+按键调时单片机程序
本帖最后由 1367067553 于 2019-5-11 15:34 编辑
#include <reg51.h> //头文件
#include <intrins.h>
#define uint unsigned int //宏定义
#define uchar unsigned char
/*TS12864A-3 端口定义*/
#define LCD_data P0 //数据口
sbit LCD_RS = P3^5; //寄存器选择输入
sbit LCD_RW = P3^6; //液晶读/写控制
sbit LCD_EN = P3^4; //液晶使能控制
sbit LCD_PSB = P3^7; //串/并方式控制
/*键盘定义*/
sbit LIE1 = P2^4; //定义列
sbit LIE2 = P2^5;
sbit LIE3 = P2^6;
sbit LIE4 = P2^7;
sbit HANG1 = P2^0; //定义行
sbit HANG2 = P2^1;
sbit HANG3 = P2^2;
sbit HANG4 = P2^3;
sbit D1 = P1^3;
sbit DQ = P1^1; //定义DS18B20口
sbit beep =P1^2; //蜂鸣器
/*变量定义*/
uchar ucKeyNumber; //记录按键值
uchar ucMatrixStatus; //矩阵键盘状态
uint uiMatrixCount; //矩阵键盘计数
uint uiMatrixLieSelect; //矩阵键盘计数
uchar ucMatrixTemp; //按键端口
uchar ucStatus,flag=0,king; //定义标志位
uint uiCount,uiStatus;
uchar miao=48,fen=59,shi=23,nian=19,yue=5;ri=2;
uchar mun_char_table[]={"0123456789"};
/*函数调用*/
void My_T0(void); //定时器初始化
void delay(int ms); //LCD12864延时函数
void lcd_wcmd(uchar cmd); //写命令
void lcd_wdat(uchar dat); //写指令
void lcd_init(); //LCD12864初始化
void LCDWrituenumber(uchar x,uchar y,uchar ucDAT); //写字符
void lcd_pos(uchar X,uchar Y); //写字符串
void xianshi(void); //显示
void kaiji(void); //开机动画
void Matrix_keyboar(void); //按键扫描
void keyRun(void); //按键执行
/*********ds18b20模块*************/
void delay_us(uint i)
{
while(i--);
}
//********DS18B20初始化************//
void DS18B20_Init(void)
{
uchar x;
DQ = 1;
delay_us(100);
DQ = 0;
delay_us(1000);
DQ = 1;
delay_us(200);
x = DQ; //DQ管脚送出60-240us的0脉冲 以示初始化成功
delay_us(250);
}
//************写一个字节************//
void write_OneChar(uchar dat)
{
uchar i=0;
for(i = 8;i > 0;i--)
{
DQ = 0;
DQ = dat&0x01;
delay_us(60);
DQ = 1;
dat>>=1;
}
}
//************读一个字节***********//
uchar Read_OneChar(void)
{
uchar i=0;
uchar value = 0;
for(i = 8;i > 0;i--)
{
DQ = 0;
value>>=1;
DQ = 1;
if(DQ)value|=0x80;
delay_us(50);
}
return(value);
}
//**************读取温度**************//
uint ReadTemperature(void)
{
uchar a = 0;
uchar b = 0;
uint t = 0;
float tt = 0;
DS18B20_Init();
write_OneChar(0xcc);
write_OneChar(0x44);
DS18B20_Init();
write_OneChar(0xcc);
write_OneChar(0xbe);
a = Read_OneChar();
b = Read_OneChar();
t = b;
t <<= 8;
t = t|a;
tt = t*0.0625;
t = tt*10+0.5;
return(t);
}
/**************************************************
*函数类型:main.c
*函数名称:主函数
**************************************************/
void main(void)
{
lcd_init(); //12864初始化
DS18B20_Init(); //18B20初始化
while(1)
{
My_T0();
kaiji();
xianshi();
}
}
/**************************************************
* LCD12864模块
/**************************************************/
void delay(int ms) //LCD12864延时函数
{
while(ms--)
{
uchar i;
for(i=0;i<250;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
/*******************************************************************/
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
/*******************************************************************/
void lcd_wcmd(uchar cmd)
{
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delay(1);
LCD_EN = 1;
delay(1);
LCD_EN = 0;
}
/*******************************************************************/
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
/*******************************************************************/
void lcd_wdat(uchar dat)
{
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delay(1);
LCD_EN = 1;
delay(1);
LCD_EN = 0;
}
/*******************************************************************/
/* LCD初始化设定 */
/*******************************************************************/
void lcd_init()
{
LCD_PSB = 1; //并口方式
lcd_wcmd(0x34); //扩充指令操作
delay(5);
lcd_wcmd(0x30); //基本指令操作
delay(5);
lcd_wcmd(0x0C); //显示开,关光标
delay(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delay(5);
}
/*********************************************************
* 写字符 *
**********************************************************/
void LCDWritueString(uchar x,uchar y,uchar *str) //固定格式
{
uchar i;
lcd_pos(x,y);
i = 0;
while(str[i] != '\0')
{
lcd_wdat(str[i]); //显示字符
i++;
}
}
/*********************************************************
* 写字符串 *
*********************************************************/
void LCDWrituenumber(uchar x,uchar y,uchar ucDAT)
{
lcd_pos(x,y);
lcd_wdat((ucDAT / 10)+ 48);
lcd_wdat((ucDAT % 10) + 48);
}
/*************************************************
* 设定显示位置 *
*************************************************/
void lcd_pos(uchar X,uchar Y)
{
uchar pos;
if (X==0)
{X=0x80;}
else if (X==1)
{X=0x90;}
else if (X==2)
{X=0x88;}
else if (X==3)
{X=0x98;}
pos = X+Y ;
lcd_wcmd(pos); //显示地址
}
/**********************************************
* 定时器初始化 *
**********************************************/
void My_T0(void)
{
TMOD = 0x01;
TH0 = (65536-1000)/256;
TL0 = (65536-1000)%256;
EA = 1;
ET0 = 1;
TR0 = 1;
}
/***********************************************
* 定时器T0服务函数 *
***********************************************/
void Tim0() interrupt 1
{
TH0 = (65536-1000)/256;
TL0 = (65536-1000)%256;
Matrix_keyboar();
keyRun();
uiStatus++;
if(king == 0)
{
uiCount++;
}
if(uiCount >= 1000)
{
uiCount = 0;
miao++;
if(miao >=60)
{
miao = 0;
fen++;
}
if(fen >= 60)
{
fen = 0;
shi++;
}
if(shi >= 24)
{
shi = 0;
ri++;
}
if(ri >=31)
{
ri = 0;
yue++;
}
if(yue >= 12)
{
yue = 0;
nian++;
}
}
}
/***********************************************
* 显示函数 *
***********************************************/
void xianshi(void)
{
if(flag == 1)
{
uint temp;
lcd_pos(0,1);
lcd_wdat(mun_char_table[shi/10]);
lcd_wdat(mun_char_table[shi%10]);
LCDWritueString(0,2," -");
lcd_pos(0,3);
lcd_wdat(mun_char_table[fen/10]);
lcd_wdat(mun_char_table[fen%10]);
LCDWritueString(0,4," -");
lcd_pos(0,5);
lcd_wdat(mun_char_table[miao/10]);
lcd_wdat(mun_char_table[miao%10]);
lcd_pos(1,1);
lcd_wdat(mun_char_table[nian/10]);
lcd_wdat(mun_char_table[nian%10]);
LCDWritueString(1,2,"年");
lcd_pos(1,3);
lcd_wdat(mun_char_table[yue/10]);
lcd_wdat(mun_char_table[yue%10]);
LCDWritueString(1,4,"月");
lcd_pos(1,5);
lcd_wdat(mun_char_table[ri/10]);
lcd_wdat(mun_char_table[ri%10]);
LCDWritueString(1,6,"日");
LCDWrituenumber(1,0,20);
/* 显示温度 */
temp=ReadTemperature(); //把读到的温度赋值给temp
LCDWritueString(3,0,"当前温度:");
lcd_pos(3,5);
lcd_wdat(mun_char_table[temp/100]);
lcd_wdat(mun_char_table[temp%100/10]);
lcd_pos(3,6);
LCDWritueString(3,6,".");
lcd_wdat(mun_char_table[temp%10]);
LCDWritueString(3,7,"度");
if(temp >= 250)
{
beep = ~beep; //蜂鸣器滴滴
}
else
beep = 1;
}
}
/*******************************************
* 开机动画 *
*******************************************/
void kaiji(void)
{
switch(ucStatus)
{
case 0: LCDWritueString(0,0,"大学生单片机竞赛");
if(uiStatus >= 500)
{
uiStatus = 0;
ucStatus = 1;
}
break;
case 1: LCDWritueString(0,0," ");
if(uiStatus >= 500)
{
uiStatus = 0;
ucStatus = 2;
}
break;
case 2: LCDWritueString(1,2,"H001组");
if(uiStatus >= 500)
{
uiStatus = 0;
ucStatus = 3;
}
break;
case 3: LCDWritueString(1,2," ");
if(uiStatus >= 500)
{
uiStatus = 0;
ucStatus = 4;
}
break;
case 4: LCDWritueString(2,2,"只因追求");
if(uiStatus >= 500)
{
uiStatus = 0;
ucStatus = 5;
}
break;
case 5: LCDWritueString(2,2," ");
if(uiStatus >= 500)
{
uiStatus = 0;
ucStatus = 6;
}
break;
case 6: LCDWritueString(3,2,"源于热爱");
if(uiStatus >= 500)
{
uiStatus = 0;
ucStatus = 7;
}
break;
case 7: LCDWritueString(3,2," ");
if(uiStatus >= 500)
{
uiStatus = 0;
ucStatus = 8;
flag = 1;
}
break;
case 8: break;
}
}
///////////////////*******以下为按键模块********///////////////////
/***********************************************
* 矩阵键盘扫描
***********************************************/
void Matrix_keyboar(void)
{
switch(ucMatrixStatus)
{
case 0: if(uiMatrixLieSelect == 0)
{
LIE1 = 0;LIE2 = 1;LIE3 = 1;LIE4 = 1; //每一列 第一个
}
else if(uiMatrixLieSelect == 1)
{
LIE1 = 1;LIE2 = 0;LIE3 = 1;LIE4 = 1; //每一列 第二个
}
else if(uiMatrixLieSelect == 2)
{
LIE1 = 1;LIE2 = 1;LIE3 = 0;LIE4 = 1; //每一列 第三个
}
else if(uiMatrixLieSelect == 3)
{
LIE1 = 1;LIE2 = 1;LIE3 = 1;LIE4 = 0; //每一列 第四个
}
else
{
LIE1 = 1;LIE2 = 1;LIE3 = 1;LIE4 = 1; //没有列按下
}
ucMatrixStatus = 1;
break;
case 1: if((HANG1 == 1) && (HANG2 == 1)&& (HANG3 == 1)&& (HANG4 == 1) )//没有行按下
{
ucMatrixStatus = 0; //重新扫描
uiMatrixLieSelect++; //逐行扫描
if(uiMatrixLieSelect > 3)uiMatrixLieSelect = 0;
}
else
{
uiMatrixCount++; //计时
if(uiMatrixCount >= 10) //消抖
{
uiMatrixCount = 0; //清零
if((HANG1 == 1) && (HANG2 == 1)&& (HANG3 == 1)&& (HANG4 == 1))
{
ucMatrixStatus = 0; //回到第一步
}
else
{
ucMatrixTemp = P2;
ucMatrixStatus = 2;
}
}
}
break;
case 2: if((HANG1 == 1) && (HANG2 == 1)&& (HANG3 == 1)&& (HANG4 == 1))
{
switch(ucMatrixTemp)
{
case 0XEE: ucKeyNumber = 1;break; //S1
case 0XDE: ucKeyNumber = 2;break; //S2
case 0XBE: ucKeyNumber = 3;break; //S3
case 0X7E: ucKeyNumber = 4;break; //S4
case 0XED: ucKeyNumber = 5;break; //S5
case 0XDD: ucKeyNumber = 6;break; //S6
case 0XBD: ucKeyNumber = 7;break; //S7
case 0X7D: ucKeyNumber = 8;break; //S8
case 0XEB: ucKeyNumber = 9;break; //S9
case 0XDB: ucKeyNumber = 10;break; //S10
case 0XBB: ucKeyNumber = 11;break; //S11
case 0X7B: ucKeyNumber = 12;break; //S12
case 0XE7: ucKeyNumber = 13;break; //S13
case 0XD7: ucKeyNumber = 14;break; //S14
case 0XB7: ucKeyNumber = 15;break; //S15
case 0X77: ucKeyNumber = 16;break; //S16
}
ucMatrixStatus = 0;
}
break;
}
}
/*************************************************
* 按键执行 *
*************************************************/
void keyRun(void)
{
switch(ucKeyNumber)
{
case 1: king = 1;D1 = 0;ucKeyNumber = 0;break; //暂停
case 2: miao++;if(miao>=59)miao=0;ucKeyNumber = 0;break; //秒加
case 3: miao--;if(miao<=0)miao=0;ucKeyNumber = 0;break; //秒减
case 4: fen++;if(fen>=59)fen=0;ucKeyNumber = 0;break; //分加
case 5: fen--;if(fen<=0)fen=0;ucKeyNumber = 0;break; //分减
case 6: shi++;if(shi>=23)shi=0;ucKeyNumber = 0;break; //时加
case 7: shi--;if(shi<=0)shi=0;ucKeyNumber = 0;break; //时减
case 8: king = 0;D1 = 1;ucKeyNumber = 0;break; //开启
}
}
复制代码
12864时钟.rar
2019-5-11 15:34 上传
点击文件名下载附件
下载积分: 黑币 -5
41.65 KB, 下载次数: 18, 下载积分: 黑币 -5
作者:
admin
时间:
2019-5-6 17:23
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1