请大家检查检查
错误
各部分程序
/******************************************************************/
1602显示程序
/*****************************************************************/
//以下是1602头文件
#ifndef __1602LCD_H__
#define __1602LCD_H__
//--包含头文件--//
#include <pic.h>
//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
//--定义1602的IO口--//
#define E_1602 RA5 //液晶使能
#define RW_1602 RA4 //读/写选择端(H/L)
#define RS_1602 RA3 //数据/命令选择端(H/L)
void write_com_1602(uchar com); //写命令
void write_data_1602(uchar _data);//写数据
void Display_1602(uchar x,unsigned char y,uchar *p,uchar count);//指定位置显示
void write_oneline_1602(uchar add_1602,uint date_1602);
void write_twoline_1602(uchar add_1602,uint date_1602);
void lcdinit_1602(); //1602初始化
#endif
//以下是1602 C程序
/****************************
*1602模块未检忙 *
*****************************/
#include <pic.h>
#include "1602lcd.h"
#include "delay.h"
/*******写命令*******/
void write_com_1602(uchar com)
{
E_1602=0;
RW_1602=0;
RS_1602=0; //写命令
PORTD=com;
E_1602=1; //上升沿有效
delay1ms(1);
E_1602=0;
}
/*******写数据******/
void write_data_1602(uchar _data)
{
E_1602=0;
RW_1602=0;
RS_1602=1; //写数据
PORTD=_data;
E_1602=1; //上升沿有效
delay1ms(1);
E_1602=0;
}
/**********************************************************
*功能:指定位置显示数据 *
* x:列显示地址(1~16) *
* y:行显示地址(1~2) *
* count:显示字符个数 *
* *p:指定字符串指针 *
* Display_1602(1,1,"sgy",3) *
***********************************************************/
void Display_1602(unsigned char x,unsigned char y,unsigned char *p,unsigned char count)
{
unsigned char i;
for(i=0;i<count;i++)
{
if(1==y) //显示第一行
{
x|=0x80; //x=x|0x80 当要显示第一行时地址码+0x80
}
else
{
x|=0xc0; ////在第二行显示是地址码+0xC0;
}
write_com_1602(x-1);
write_data_1602(*p);
x++;
p++;
}
}
//在1602上写时间函数 即在1602第一行指定位
void write_oneline_1602(uchar add_1602,uint date_1602)
{
uchar ge,shi;
shi=date_1602/10; //取整
ge=date_1602%10; //取余
write_com_1602(0x80+add_1602);
write_data_1602(0x30+ge);
write_com_1602(0x80+add_1602-1);
write_data_1602(0x30+shi);
}
//在1602上写时间函数 即在1602第二行指定位
void write_twoline_1602(uchar add_1602,uint date_1602)
{
uchar shi,ge;
shi=date_1602/10;
ge=date_1602%10;
write_com_1602(0x80+0x40+add_1602-1);
write_data_1602(0x30+shi);
write_com_1602(0x80+0x40+add_1602);
write_data_1602(0x30+ge); 在1602第二行指定位
}
void lcdinit_1602() //1602初始化函数
{
E_1602=0;
//write_byte_74hc595(0X02);//关流水灯使能 关蜂鸣器 光继电器 打开1602背光打开
write_com_1602(0x38); //设置16x2显示,5x7点阵,8位数据接口
// write_com_1602(0x0e); //开显示、显示光标、光标不闪烁
write_com_1602(0x0c); //开显示 不显示光标
write_com_1602(0x06); //当写一个字符是,地址指针加 1、光标加1 整屏左移
write_com_1602(0x01); //显示清屏
}
/******************************************************************/
Ds1302显示程序
/*****************************************************************/
//以下是ds1302头文件
#ifndef __DS1302_H_
#define __DS1302_H_
//---包含头文件---//
#include<pic.h>
//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
//---定义ds1302使用的IO口---//
#define IO RA2
#define RST RA0
#define SCLK RA1
#define IO_IN TRISA2=1 //输入
#define IO_OUT TRISA2=0 //输出
#define RST_IN TRISA0=1 //输入
#define RST_OUT TRISA0=0 //输出
#define SCLK_IN TRISA1=1 //输入
#define SCLK_OUT TRISA1=0 //输入
//---定义全局函数---//
void delay1();
void write_byte(uchar dat); //写入一字节数据
uchar read_byte(void); //读一字节数据
void write_ds1302(uchar addr,uchar data); //指定命令写数据
uchar read_ds1302(uchar addr); //读指定地址的数据
void ds1302_init(); //ds1302初始化
uchar BCD_10(uchar BCD); //BCD转换为十进制
uchar D_BCD(uchar D); //十进制转BCD
void get_time(); //显示时间
void set_time();//设置时间
extern uchar shi,fen,miao,year,month,day,week;
#endif
//以下是ds1302c文件
#include"ds1302.h"
#include "1602lcd.h"
void delay1()
{
int i;
for(i=100;i--;);
}
/*******从ds1302读一个字节数据*****/
uchar read_byte(void)
{
uchar i,dat=0;
IO_IN; //置为输入
IO=0; //不带上拉电阻
for(i=0;i<7;i++) //读7位
{
SCLK=0;
if(IO) //读取数据端口状态
{dat=dat|0x80;} //1
else
{dat=dat&0x7f;} //0
SCLK=1; //上升沿读数据
dat=dat>>1;
}
IO_OUT; //恢复输出
SCLK=0;
return dat; //返回读取的数据
}
/*****向ds1302写一个字节数据******/
void write_byte(uchar dat) //写入一字节数据
{
uchar i;
for(i=0;i<8;i++)
{
IO=0;
SCLK=0;
if(dat&0x01) //写数据
{
IO=1;
}
else
{
IO=0;
}
SCLK=1;
dat>>=1; //数据右移1位
}
SCLK=0;
}
/*******从ds1302指定地址读一个字节数据*****/
uchar read_ds1302(uchar addr)
{
char data;
RST=0;
SCLK=0;
delay1();
RST=1;
delay1();
write_byte(addr);
//delay1();
data=read_byte();
SCLK=0;
RST=0;
return data;
}
void write_ds1302(uchar addr,uchar data)
{
RST=0;
SCLK=0;
delay1();
RST=1;
//delay1();
write_byte(addr); //写入命令地址
SCLK=0;
write_byte(data); //写入命令地址
SCLK=0;
RST=0;
}
void ds1302_init()
{
RST=0;
SCLK=0;
RST_OUT;
SCLK_OUT;
write_ds1302(0x8e,0x00); //允许写
//write_ds1302(0x80,0x80); //停止
/*write_ds1302(0x80,0x11); //设置秒
write_ds1302(0x82,0x30); //设置fen
write_ds1302(0x84,0x11); //设置shi
write_ds1302(0x86,0x05); //设day
write_ds1302(0x88,0x12); //设yue
write_ds1302(0x8c,0x15); //设置nian
write_ds1302(0x8a,0x06); //设置秒
write_ds1302(0x80,0x00);*/
write_ds1302(0x90,0xab); //写充电器
write_ds1302(0x8e,0x80); //写保护、禁止写
RST=1;
}
uchar BCD_10(uchar BCD) //BCD转换为十进制
{
BCD=BCD/16*10+BCD%16;
return BCD;
}
uchar D_BCD(uchar D) //十进制转BCD
{
D=D/10*16+D%10;
return D;
}
/*void set_time(uchar Time[])//设置时间
{
write_ds1302(0x8e,0x00); //WP=0 允许写
write_ds1302(0x80,0x80); //停止
write_ds1302(0x80,Time[0]); //设置秒
write_ds1302(0x82,Time[1]); //设置fen
write_ds1302(0x84,Time[2]); //设置shi
write_ds1302(0x86,Time); //设day
write_ds1302(0x88,month); //设yue
write_ds1302(0x8c,year); //设置nian
write_ds1302(0x8a,week); //设置秒
write_ds1302(0x8e,0x80); //WP=1 禁止写
}*/
void get_time()
{
//*********读时间、显示时间************************
miao=BCD_10(read_ds1302(0x81)); //读秒*
fen=BCD_10(read_ds1302(0x83)); //读分*
shi=BCD_10(read_ds1302(0x85)); //读时*
write_twoline_1602(10,miao); //显示秒*
write_twoline_1602(7,fen); //显示分*
write_twoline_1602(4,shi); //显示时*
//*************************************************
//****************读日历、显示日历*****************
day=BCD_10(read_ds1302(0x87)); //读日 *
month=BCD_10(read_ds1302(0x89)); //读月 *
year=BCD_10(read_ds1302(0x8D)); //读年 *
write_oneline_1602(11,day); //显示日 *
write_oneline_1602(8,month); //显示月 *
write_oneline_1602(5,year); //显示年 *
//**************************************************
//**************显示星期****************************************
week=BCD_10(read_ds1302(0x8B)); //读星期 *
//write_oneline_1602(15,week);//显示星期 *
switch(week)
{
case(1):Display_1602(14,1,"MON",3); // 星期一*
break;
case(2):Display_1602(14,1,"TUE",3); //星期二*
break;
case(3):Display_1602(14,1,"WED",3); //星期三*
break;
case(4):Display_1602(14,1,"THU",3); //星期四*
break;
case(5):Display_1602(14,1,"FRI",3); //星期五*
break;
case(6):Display_1602(14,1,"SAT",3); //星期六*
break;
case(7):Display_1602(14,1,"SUN",3); //星期日*
break;
//*************************************************************
}
}
/******************************************************************/
键盘扫描程序/*****************************************************************/
//以下是键盘扫描的头文件
#ifndef __KEY_SCAN_H__
#define __KEY_SCAN_H__
#define uchar unsigned char
#define uint unsigned int
//extern uchar shi,fen,miao,day,month,year,week;
void key_scan();
extern uchar start,flag;
#endif
//以下是键盘扫描的c文件
/****************************************
*函数:key_scan() *
*功能:k1:闹钟/时间(1闹钟 2时间) *
* k2:模式(年月日、时分秒、星期) *
k3:时间加 *
* k4:时间减 *
*****************************************/
#include <pic.h>
#include "key_scan.h"
#include "1602lcd.h"
#include "delay.h"
#include "ds1302.h"
#define k1 RC0
#define k2 RC1
#define k3 RC2
#define k4 RC3
uchar moshi=0;
uchar Time[7]; //缓冲时间 秒 分 时 日 月 年 星期
void key_scan()
{
TRISC=0B00001111; //RC0~3 按键
/********************
* k2下时间界面 *
* 设置时间 *
********************/
if(!k2)
{
delay1ms(10);
if(!k2)
{
while(!k2);
moshi++;
start=1;
flag=0;
write_ds1302(0x8e,0x00); //WP=0 允许写
//write_ds1302(0x80,0x80); //停止运行
}
}
if(moshi==1) //秒
{
write_com_1602(0x80+0x40+0x0a); //指定位置显示光标、光标闪烁
write_com_1602(0x0f);
}
if(moshi==2) //分
{
write_com_1602(0x80+0x40+0x07); //指定位置显示光标、光标闪烁 write_com_1602(0x0f);
}
if(moshi==3) //时
{
write_com_1602(0x80+0x40+0x04); //指定位置显示光标、光标闪烁 write_com_1602(0x0f);
}
if(moshi==4) //星期
{
write_com_1602(0x80+0x0f); //指定位置显示光标、光标闪烁
write_com_1602(0x0f);
}
if(moshi==5) //日
{
write_com_1602(0x80+0x0b); //指定位置显示光标、光标闪烁
write_com_1602(0x0f);
}
if(moshi==6) //月
{
write_com_1602(0x80+0x08); //指定位置显示光标、光标闪烁
write_com_1602(0x0f);
}
if(moshi==7) //年
{
write_com_1602(0x80+0x05); //指定位置显示光标、光标闪烁
write_com_1602(0x0f);
}
if(moshi==8)
{
moshi=0;
write_com_1602(0x0c); //设置开显示、不显示光标
write_ds1302(0x80,Time[0]); //刷新秒
write_ds1302(0x82,Time[1]); //刷新fen
write_ds1302(0x84,Time[2]); //刷新时
write_ds1302(0x86,Time[3]); //刷新天
write_ds1302(0x88,Time[4]); //刷新月
write_ds1302(0x8c,Time[5]); //刷新年
write_ds1302(0x8a,Time[6]); //刷新星期
//write_ds1302(0x80,0x00); //开钟
write_ds1302(0x8e,0x80); //禁止写
start=0;
}
//****模式1下
if(moshi==1)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
miao++;
if(miao>=60)
{
miao=0;
}
write_twoline_1602(10,miao); //设置秒++
write_com_1602(0x80+0x40+0x0a);//防止初始化后显示地址发生变化
Time[0]=D_BCD(miao); //转换为BCD码
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
if(miao==0)
{
miao=60;
}
miao--;
write_twoline_1602(10,miao); //设置秒--
write_com_1602(0x80+0x40+0x0a);//防止初始化后显示地址发生变化
Time[0]=D_BCD(miao); //转换为BCD码
}
}
}
//****模式2下设置分
if(moshi==2)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
fen++;
if(fen>=60)
{
fen=0;
}
Time[1]=D_BCD(fen); //转换为BCD码
write_twoline_1602(7,fen); //设置秒++
write_com_1602(0x80+0x40+0x07);//防止初始化后显示地址发生变化
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
if(fen==0)
{
fen=60;
}
fen--;
Time[1]=D_BCD(fen); //转换为BCD码
write_twoline_1602(7,fen); //设置秒--
write_com_1602(0x80+0x40+0x07);//防止初始化后显示地址发生变化
}
}
}
//****模式3下设置时
if(moshi==3)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
shi++;
if(shi>=24)
{
shi=0;
}
Time[2]=D_BCD(shi); //转换为BCD码
write_twoline_1602(4,shi); //设置时++
write_com_1602(0x80+0x40+0x04);//防止初始化后显示地址发生变化
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
if(shi==0)
{
shi=24;
}
shi--;
Time[2]=D_BCD(shi); //转换为BCD码
write_twoline_1602(4,shi); //设置时--
write_com_1602(0x80+0x40+0x04);//防止初始化后显示地址发生变化
}
}
}
//****模式4下设置星期
if(moshi==4)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
week++;
if(week>=8)
{
week=1;
}
Time[6]=D_BCD(week); //转换为BCD码
write_oneline_1602(15,week); //设置周++
write_com_1602(0x80+0x0f);//防止初始化后显示地址发生变化
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
week--;
if(week==0)
{
week=7;
}
Time[6]=D_BCD(week); //转换为BCD码
write_oneline_1602(15,week); //设置周--
write_com_1602(0x80+0x0f);//防止初始化后显示地址发生变化
}
}
}
//****模式5下设置日
if(moshi==5)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
day++;
if(day>31)
{
day=0;
}
Time[3]=D_BCD(day); //转换为BCD码
write_oneline_1602(11,day); //设置日++
write_com_1602(0x80+0x0b);//防止初始化后显示地址发生变化
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
if(day==0)
{
day=32;
}
day--;
Time[3]=D_BCD(day); //转换为BCD码
write_oneline_1602(11,day); //设置日--
write_com_1602(0x80+0x0b);//防止初始化后显示地址发生变化
}
}
}
//****模式6下设置月
if(moshi==6)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
month++;
if(month>=13)
{
month=1;
}
Time[4]=D_BCD(month); //转换为BCD码
write_oneline_1602(8,month); //设置月++
write_com_1602(0x80+0x08);//防止初始化后显示地址发生变化
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
if(month==0)
{
month=13;
}
month--;
Time[4]=D_BCD(month); //转换为BCD码
write_oneline_1602(8,month); //设置月--
write_com_1602(0x80+0x08);//防止初始化后显示地址发生变化
}
}
}
//****模式7下设置年
if(moshi==7)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
year++;
if(year==100)
{
year=0;
}
Time[5]=D_BCD(year); //转换为BCD码
write_oneline_1602(5,year); //设置年++
write_com_1602(0x80+0x05);//防止初始化后显示地址发生变化
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
if(year==0)
{
year=100;
}
year--;
Time[5]=D_BCD(year); //转换为BCD码
write_oneline_1602(5,year); //设置年--
write_com_1602(0x80+0x05);//防止初始化后显示地址发生变化
}
}
}
}
/******************************************************************/
主程序/*****************************************************************/
#include <pic.h>
#include "delay.h"
#include "1602lcd.h"
#include "ds1302.h"
#include "key_scan.h"
#define BEEP RC4
#define k1 RC0 //设置闹钟
#define k2 RC1 //设置时间
#define k3 RC2 //时间+
#define k4 RC3 //时间-
void beep ();
void clock();
void set_clock();
__CONFIG(XT & WDTDIS & LVPDIS & BORDIS);
uchar Time[7]={0x01,0x03,0x05,0x05,0x12,0x15,0x06}; //缓冲时间 秒 分 时 日 月 年 星期
uchar miao,fen,shi,day,month,year,week;
uchar amiao=1,afen=1,ashi=1;
uchar start=0,flag=0,moshi1,FLAG=0,naozhong;
void main()
{
ADCON1=0x07; //RA端口设为普通端口
TRISD=0; //全输出
TRISA=0;
TRISB=0b00000001;
TRISC=0B00001111; //RC0~3 按键
lcdinit_1602(); //1602初始化
ds1302_init();
Display_1602(1,1," 2015-12-05 ",16);
Display_1602(1,2," 14:44:31 ",16);
while(1)
{
key_scan();
set_clock();
if(start==0)
{
get_time();//时钟界面
}
if(flag==1) //闹钟界面
{
clock();
}
if((amiao==miao)&&(ashi==shi)&&(afen==fen))
{
naozhong=1; //标志位
}
if(naozhong==1) //闹钟响
{
beep();
if(!RB0)
{
delay1ms(10);
while(!RB0);
naozhong=0;
}
}
}
}
void set_clock()
{
if(!k1)
{
if(FLAG==0)
{
FLAG=0;
moshi1++;
write_com_1602(0x01); //显示清屏
Display_1602(1,2," : : ",16);
Display_1602(1,1," clock ",16);
start=1; //关闭时钟界面
flag=1; //开启闹钟界面
}
}
else
FLAG=0;
if(moshi1==1) //秒
{
write_com_1602(0x80+0x40+0x0a); //指定位置显示光标、光标闪烁
write_com_1602(0x0f);
}
if(moshi1==2) //分
{
write_com_1602(0x80+0x40+0x07); //指定位置显示光标、光标闪烁
write_com_1602(0x0f);
}
if(moshi1==3) //时
{
write_com_1602(0x80+0x40+0x04); //指定位置显示光标、光标闪烁
write_com_1602(0x0f);
}
if(moshi1==4)
{
moshi1=0;
flag=0; //关闹钟
write_com_1602(0x01); //显示清屏
write_com_1602(0x0c); //设置开显示、不显示光标
Display_1602(1,1," 2015- - ",16);
Display_1602(1,2," : : ",16);
start=0; //开时钟显示
}
//****模式1下
if(moshi1==1)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
amiao++;
if(amiao>=60)
{
amiao=0;
}
write_twoline_1602(10,amiao); //设置秒++
write_com_1602(0x80+0x40+0x0a);//防止初始化后显示地址发生变化
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
if(amiao==0)
{
amiao=60;
}
amiao--;
write_twoline_1602(10,amiao); //设置秒--
write_com_1602(0x80+0x40+0x0a);//防止初始化后显示地址发生变化
}
}
}
//****模式2下设置分
if(moshi1==2)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
afen++;
if(afen>=60)
{
afen=0;
}
write_twoline_1602(7,afen); //设置秒++
write_com_1602(0x80+0x40+0x07);//防止初始化后显示地址发生变化
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
//fen--;
if(afen==0)
{
afen=60;
}
afen--;
write_twoline_1602(7,afen); //设置秒--
write_com_1602(0x80+0x40+0x07);//防止初始化后显示地址发生变化
}
}
}
//****模式3下设置时
if(moshi1==3)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
ashi++;
if(ashi>=24)
{
ashi=0;
}
write_twoline_1602(4,ashi); //设置时++
write_com_1602(0x80+0x40+0x04);//防止初始化后显示地址发生变化
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
if(ashi==0)
{
ashi=24;
}
ashi--;
write_twoline_1602(4,ashi); //设置时--
write_com_1602(0x80+0x40+0x04);//防止初始化后显示地址发生变化
}
}
}
}
void clock()
{
write_twoline_1602(4,ashi);
write_twoline_1602(7,afen);
write_twoline_1602(10,amiao);
}
void beep()
{
BEEP=0;
delay1ms(1);
BEEP=1;
delay1ms(100);
}
/******************************************************************/
/*****************************************************************/
//delay.h
#ifndef __DELAY_H_
#define __DELAY_H_
/******重定义关键字**********/
#ifndef uint
#define uint unsigned int
#endif
#ifndef uchar
#define uchar unsigned char
#endif
//delay.c
void delay1ms(uint x); //延时1ms
#endif
#include"delay.h"
void delay1ms(uint x)
{
uchar a,b;
for(x;x>0;x--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
|