請大家檢查檢查
錯誤
各部分程序
/******************************************************************/
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 //數(shù)據(jù)/命令選擇端(H/L)
void write_com_1602(uchar com); //寫命令
void write_data_1602(uchar _data);//寫數(shù)據(jù)
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;
}
/*******寫數(shù)據(jù)******/
void write_data_1602(uchar _data)
{
E_1602=0;
RW_1602=0;
RS_1602=1; //寫數(shù)據(jù)
PORTD=_data;
E_1602=1; //上升沿有效
delay1ms(1);
E_1602=0;
}
/**********************************************************
*功能:指定位置顯示數(shù)據(jù) *
* x:列顯示地址(1~16) *
* y:行顯示地址(1~2) *
* count:顯示字符個數(shù) *
* *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上寫時間函數(shù) 即在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上寫時間函數(shù) 即在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初始化函數(shù)
{
E_1602=0;
//write_byte_74hc595(0X02);//關流水燈使能 關蜂鳴器 光繼電器 打開1602背光打開
write_com_1602(0x38); //設置16x2顯示,5x7點陣,8位數(shù)據(jù)接口
// 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 //輸入
//---定義全局函數(shù)---//
void delay1();
void write_byte(uchar dat); //寫入一字節(jié)數(shù)據(jù)
uchar read_byte(void); //讀一字節(jié)數(shù)據(jù)
void write_ds1302(uchar addr,uchar data); //指定命令寫數(shù)據(jù)
uchar read_ds1302(uchar addr); //讀指定地址的數(shù)據(jù)
void ds1302_init(); //ds1302初始化
uchar BCD_10(uchar BCD); //BCD轉(zhuǎn)換為十進制
uchar D_BCD(uchar D); //十進制轉(zhuǎn)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讀一個字節(jié)數(shù)據(jù)*****/
uchar read_byte(void)
{
uchar i,dat=0;
IO_IN; //置為輸入
IO=0; //不帶上拉電阻
for(i=0;i<7;i++) //讀7位
{
SCLK=0;
if(IO) //讀取數(shù)據(jù)端口狀態(tài)
{dat=dat|0x80;} //1
else
{dat=dat&0x7f;} //0
SCLK=1; //上升沿讀數(shù)據(jù)
dat=dat>>1;
}
IO_OUT; //恢復輸出
SCLK=0;
return dat; //返回讀取的數(shù)據(jù)
}
/*****向ds1302寫一個字節(jié)數(shù)據(jù)******/
void write_byte(uchar dat) //寫入一字節(jié)數(shù)據(jù)
{
uchar i;
for(i=0;i<8;i++)
{
IO=0;
SCLK=0;
if(dat&0x01) //寫數(shù)據(jù)
{
IO=1;
}
else
{
IO=0;
}
SCLK=1;
dat>>=1; //數(shù)據(jù)右移1位
}
SCLK=0;
}
/*******從ds1302指定地址讀一個字節(jié)數(shù)據(jù)*****/
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轉(zhuǎn)換為十進制
{
BCD=BCD/16*10+BCD%16;
return BCD;
}
uchar D_BCD(uchar D) //十進制轉(zhuǎn)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文件
/****************************************
*函數(shù):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);//防止初始化后顯示地址發(fā)生變化
Time[0]=D_BCD(miao); //轉(zhuǎn)換為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);//防止初始化后顯示地址發(fā)生變化
Time[0]=D_BCD(miao); //轉(zhuǎn)換為BCD碼
}
}
}
//****模式2下設置分
if(moshi==2)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
fen++;
if(fen>=60)
{
fen=0;
}
Time[1]=D_BCD(fen); //轉(zhuǎn)換為BCD碼
write_twoline_1602(7,fen); //設置秒++
write_com_1602(0x80+0x40+0x07);//防止初始化后顯示地址發(fā)生變化
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
if(fen==0)
{
fen=60;
}
fen--;
Time[1]=D_BCD(fen); //轉(zhuǎn)換為BCD碼
write_twoline_1602(7,fen); //設置秒--
write_com_1602(0x80+0x40+0x07);//防止初始化后顯示地址發(fā)生變化
}
}
}
//****模式3下設置時
if(moshi==3)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
shi++;
if(shi>=24)
{
shi=0;
}
Time[2]=D_BCD(shi); //轉(zhuǎn)換為BCD碼
write_twoline_1602(4,shi); //設置時++
write_com_1602(0x80+0x40+0x04);//防止初始化后顯示地址發(fā)生變化
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
if(shi==0)
{
shi=24;
}
shi--;
Time[2]=D_BCD(shi); //轉(zhuǎn)換為BCD碼
write_twoline_1602(4,shi); //設置時--
write_com_1602(0x80+0x40+0x04);//防止初始化后顯示地址發(fā)生變化
}
}
}
//****模式4下設置星期
if(moshi==4)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
week++;
if(week>=8)
{
week=1;
}
Time[6]=D_BCD(week); //轉(zhuǎn)換為BCD碼
write_oneline_1602(15,week); //設置周++
write_com_1602(0x80+0x0f);//防止初始化后顯示地址發(fā)生變化
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
week--;
if(week==0)
{
week=7;
}
Time[6]=D_BCD(week); //轉(zhuǎn)換為BCD碼
write_oneline_1602(15,week); //設置周--
write_com_1602(0x80+0x0f);//防止初始化后顯示地址發(fā)生變化
}
}
}
//****模式5下設置日
if(moshi==5)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
day++;
if(day>31)
{
day=0;
}
Time[3]=D_BCD(day); //轉(zhuǎn)換為BCD碼
write_oneline_1602(11,day); //設置日++
write_com_1602(0x80+0x0b);//防止初始化后顯示地址發(fā)生變化
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
if(day==0)
{
day=32;
}
day--;
Time[3]=D_BCD(day); //轉(zhuǎn)換為BCD碼
write_oneline_1602(11,day); //設置日--
write_com_1602(0x80+0x0b);//防止初始化后顯示地址發(fā)生變化
}
}
}
//****模式6下設置月
if(moshi==6)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
month++;
if(month>=13)
{
month=1;
}
Time[4]=D_BCD(month); //轉(zhuǎn)換為BCD碼
write_oneline_1602(8,month); //設置月++
write_com_1602(0x80+0x08);//防止初始化后顯示地址發(fā)生變化
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
if(month==0)
{
month=13;
}
month--;
Time[4]=D_BCD(month); //轉(zhuǎn)換為BCD碼
write_oneline_1602(8,month); //設置月--
write_com_1602(0x80+0x08);//防止初始化后顯示地址發(fā)生變化
}
}
}
//****模式7下設置年
if(moshi==7)
{
if(!k3)
{
delay1ms(10);
if(!k3)
{
while(!k3);
year++;
if(year==100)
{
year=0;
}
Time[5]=D_BCD(year); //轉(zhuǎn)換為BCD碼
write_oneline_1602(5,year); //設置年++
write_com_1602(0x80+0x05);//防止初始化后顯示地址發(fā)生變化
}
}
if(!k4)
{
delay1ms(10);
if(!k4)
{
while(!k4);
if(year==0)
{
year=100;
}
year--;
Time[5]=D_BCD(year); //轉(zhuǎn)換為BCD碼
write_oneline_1602(5,year); //設置年--
write_com_1602(0x80+0x05);//防止初始化后顯示地址發(fā)生變化
}
}
}
}
/******************************************************************/
主程序/*****************************************************************/
#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);//防止初始化后顯示地址發(fā)生變化
}
}
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);//防止初始化后顯示地址發(fā)生變化
}
}
}
//****模式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);//防止初始化后顯示地址發(fā)生變化
}
}
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);//防止初始化后顯示地址發(fā)生變化
}
}
}
//****模式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);//防止初始化后顯示地址發(fā)生變化
}
}
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);//防止初始化后顯示地址發(fā)生變化
}
}
}
}
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--);
}
|