//#include <pic.h> //调用头文件
#include <pic16f7x7.h>//使用内部晶振8MHZ。
#define NOP() asm("nop")
#define uchar unsigned char
#define uint unsigned int
///LCD1602接口定义
#define LCD_DATA_PORT PORTB //定义LCD的D0-D7所在端口
#define LCD_DATA_POUT TRISB=0x00 //定义LCD数据端口为输出
#define LCD_EN_1 RC7=1 //LCD使能端
#define LCD_EN_0 RC7=0
#define LCD_RS_1 RC6=1 //数据/指令选择端
#define LCD_RS_0 RC6=0
#define LCD_RSADD TRISC6=0
#define LCD_ENADD TRISC7=0
/***********18B20接口***************/
#define DQ RA4
#define DQ_HIGH() TRISA4=1
#define DQ_LOW() TRISA4=0;DQ=0
//联接DS1302的端口定义
#define ds1302_rst RA1//RC2 //定义1302的RST接在PC4
#define ds1302_io RA0//RC1 //定义1302的IO接在PC3
#define ds1302_sclk RA6//RC0 //定义1302的时钟接在PC2
#define set_ds1302_rst_ddr() TRISA1=0 //复位端置为输出
#define set_ds1302_rst() ds1302_rst=1 //复位端置1
#define clr_ds1302_rst() ds1302_rst=0 //复位端清0
#define set_ds1302_io_ddr() TRISA0=0 //数据端置为输出
#define set_ds1302_io() ds1302_io=1 //数据端置1
#define clr_ds1302_io() ds1302_io=0 //数据端清0
#define clr_ds1302_io_ddr() TRISA0=1 //数据端置为输入
#define in_ds1302_io() RA0=1 //数据端输入数据
#define set_ds1302_sclk_ddr() TRISA6=0 //时钟端置为输出
#define set_ds1302_sclk() ds1302_sclk=1 //时钟端置1
#define clr_ds1302_sclk() ds1302_sclk=0 //时钟端清0
#define ds1302_sec_add 0x80 //秒数据地址
#define ds1302_min_add 0x82 //分数据地址
#define ds1302_hr_add 0x84 //时数据地址
#define ds1302_date_add 0x86 //日数据地址
#define ds1302_month_add 0x88 //月数据地址
#define ds1302_day_add 0x8a //星期数据地址
#define ds1302_year_add 0x8c //年数据地址
#define ds1302_control_add 0x8e //控制数据地址
#define ds1302_charger_add 0x90
#define ds1302_clkburst_add 0xbe
#define sw PORTA //按钮定义
#define swin TRISA2=1; TRISA3=1
#define speak RC1
#define speakout TRISC1=0
/////全局数据定义
uchar timer[7]; //时钟数据
uchar nian,nian1,ye,ye1,ri,ri1,shi,shi1,fen,fen1,miao,miao1;
bank3 uchar START_DISPLAY2[]={"Hang Li Fang"};
bank3 uchar START_DISPLAY1[]={"I Love You"};
bank3 uchar gu[]={"2010-11-06"};
bank3 uchar gu1[]={"19:30:20 25.3'C"};
bank3 uchar s1[]={"Mon"};
bank3 uchar s2[]={"Tue"};
bank3 uchar s3[]={"Wed"};
bank3 uchar s4[]={"Thu"};
bank3 uchar s5[]={"Fri"};
bank3 uchar s6[]={"Sat"};
bank3 uchar s7[]={"Sun"};
uchar t1,t2,t3;
uchar po=0;
////函数声明
void delay(uint x);//延时';:.
void delayus(uint x,uchar y);
void lcd_init(void);//LCD初使化
void LCD_en_write(void);//写使能LCD
void set_LCD_xy(uchar d, uchar c );//设定XY坐标
void LCD_write_onechar(uchar COMM,uchar DAT); //写指令或数据
void LCD_write_string(uchar d,uchar c,bank3 uchar *string); //字符串写
void LCD_write(uchar d,uchar c,uchar data); //单个字串写
void mcu_inti();
void ds1302_write(uchar add,uchar data);//DS1301add为写入地址码,data为写入数据
uchar ds1302_read(uchar add);//从1302中读出数据:
void ds1302_write_time(void);//向1302中写入时钟数据
void ds1302_read_time(void);//从1302中读出当前时钟
void Process(void);//示数据转换函数
void reset();//18B20初始化
void write_byte(uchar date);//18B20写指令
uchar read_byte();//读操作
void get_tem();//温度转换
void didi(uchar data);
void saomiao();
/****************************************************
函数名称:main
功能描述:主函数
输 入: 无
输 出: 无
日期:2009-4-8
***********************************************************************************************************************************/
void main(void)
{
mcu_inti();
lcd_init();
/* timer[0]=0x10; //年
timer[1]=0x11; //月
timer[2]=0x08; //日
timer[3]=0x01; //周
timer[4]=0x10; //时
timer[5]=0x31; //分
timer[6]=0x00; //秒
ds1302_write_time(); //写入初始时钟*/
didi(1);
LCD_write_string(3,0,START_DISPLAY1);
LCD_write_string(2,1,START_DISPLAY2);
delay(5000);
didi(3);
LCD_write_onechar(0x01,0);
// set_LCD_xy(1,0);
// LCD_write_onechar(0,"2"); //写指令或数据
// LCD_write_onechar(0,"0"); //写指令或数据
// set_LCD_xy(5,0);
// LCD_write_onechar(0,"-"); //写指令或数据
// set_LCD_xy(8,0);
// LCD_write_onechar(0,"-"); //写指令或数据
// set_LCD_xy(3,1);
// LCD_write_onechar(0,":"); //写指令或数据
LCD_write_string(1,0,gu); //字符串写
LCD_write_string(12,0,s6); //字符串写
LCD_write_string(1,1,gu1); //字符串写
while(1)
{
get_tem();
saomiao();
if(po==1)
{
po=0;
didi(10);
}
if(po==2)
{
po=0;
didi(1);
}
// didi(2);
/* NOP();
NOP();
delayus(140,66);
NOP();
delayus(10,8);
NOP();
delayus(100,26);
NOP();
delayus(2,1);
NOP();
delayus(6,4);
NOP();
delayus(4,3);
NOP();*/
}
}
void mcu_inti()
{
OSCCON=0X70;///内部晶振设定8MHZ
NOP();NOP();NOP();
ADCON1=0x0f;//AD中的IO数定接口
set_ds1302_rst_ddr();
set_ds1302_sclk_ddr();
LCD_RSADD;
LCD_ENADD;
LCD_DATA_POUT;
speak=0;
swin;
speakout;
}
//////蜂鸣器声
void didi(uchar data)
{
uchar teme;
for(teme=0;teme<data;teme++)
{
speak=1;
delay(100);
speak=0;
delay(100);
}
}
//按健扫描
void saomiao()
{
uchar key;
key=sw&0X0C;
if(key!=0xc)
{
if(key==0x04)
po=2;
else if(key==0x08) po=1;
else po=0;
}
/* if(sw1==0)
{
delay(8);
if(sw1==0)
po=1;
}
if(sw2==0)
{
delay(8);
if(sw2==0)
po=2;
}
po=0;*/
}
/****************************************************
函数名称:lcd_init
功能描述:LCD初始化
输 入: 无
输 出: 无
日期:2009-4-8
说明:注意初始化过程并加上适当延时
后面LCD的显示方式可按实际需要修改
*****************************************************/
void lcd_init(void)
{
LCD_write_onechar(0x38,0);
LCD_write_onechar(0x0c,0); /*显示关闭*/
LCD_write_onechar(0x06,0); /*显示清屏*/
LCD_write_onechar(0x01,0); /*显示光标移动设置*/
LCD_write_onechar(0x80,0); /*显示开及光标设置*/
}
/****************************************************
函数名称:LCD_en_write
功能描述:EN端产生一个脉冲,写LCD
输 入: 无
输 出: 无
日期:2009-4-8
*****************************************************/
void LCD_en_write(void)
{
LCD_EN_1;
delay(5); //E脉冲周期最小150ns
LCD_EN_0;
}
/****************************************************
函数名称:LCD_write_onechar
功能描述:写一个字节到LCD
输 入: COMM(指令) DAT(显示数据)
输 出: 无
日期:2009-4-8
*****************************************************/
void LCD_write_onechar(uchar COMM,uchar DAT)
{
if(COMM==0)
{
LCD_RS_1; //RS高电平向LCD写数据
LCD_DATA_PORT=DAT;
}
else
{
LCD_RS_0;
LCD_DATA_PORT=COMM;
}
LCD_en_write();
}
/****************************************************
函数名称:LCD_write_string
功能描述:LCD字符串显示函数
输 入: x/y(X与Y坐标) *string(字符串首地址)
输 出: 无
日期:2009-4-8
*****************************************************/
void LCD_write_string(uchar d,uchar c,bank3 uchar *string)
{
set_LCD_xy( d, c ); //设置LCD显示坐标
while (*string)
{
LCD_write_onechar(0,*string );
string ++; //指向下一显示字符地址
}
}
/****************************************************
函数名称:LCD_write_string
功能描述:LCD字符串显示函数
输 入: x/y(X与Y坐标) *string(字符串首地址)
输 出: 无
日期:2009-4-8
*****************************************************/
void LCD_write(uchar d,uchar c,uchar data)
{
set_LCD_xy( d, c ); //设置LCD显示坐标
LCD_write_onechar(0,data );
}
/****************************************************
函数名称:set_LCD_xy
功能描述:设置显示坐标
输 入: x/y(X与Y坐标)
输 出: 无
日期:2009-4-8
说明: LMB1602第一行首地址为0x80
第二行为0xC0
日期:2009-4-7
*****************************************************/
void set_LCD_xy(uchar d, uchar c )
{
if (c==0)
LCD_write_onechar(0x80+d,0);
else
LCD_write_onechar(0xc0+d,0); //第二行X列
}
void delay(uint x) //子函数(延时子程序)
{ //主函数delay(实数)时间是实数,单位是为毫秒
uint a,b;
for(a=x;a>0;a--)
for(b=213;b>0;b--);//213
}
/*************************************/
/* DS1302操作函数组 *
*************************************/
//写入1302数据函数:
//入口:add为写入地址码,data为写入数据
//返回:无
void ds1302_write(uchar add,uchar data)
{
uchar i=0;
set_ds1302_io_ddr(); //配置IO为输出
clr_ds1302_rst(); //清复位,停止所有操作
clr_ds1302_sclk(); //清时钟,准备操作
set_ds1302_rst(); //置复位,开始操作
for(i=8;i>0;i--) //此循环写入控制码
{
if(add&0x01)
set_ds1302_io(); //当前位为1,置数据位
else
clr_ds1302_io(); //当前位为0,清数据位
NOP();NOP();
set_ds1302_sclk(); //产生时钟脉冲,写入数据
NOP();NOP();
clr_ds1302_sclk();
NOP();NOP();
add>>=1; //移位,准备写入下1位
}
for(i=8;i>0;i--) //此循环写入数据码
{
if(data&0x01)
set_ds1302_io();
else
clr_ds1302_io();
NOP();NOP();
set_ds1302_sclk();
NOP();NOP();
clr_ds1302_sclk();
NOP();NOP();
data>>=1;
}
clr_ds1302_rst();
NOP();NOP();
clr_ds1302_io_ddr(); //清输出状态
}
//从1302中读出数据:
//入口:add为读数据所在地址
//返回:读出的数据data
uchar ds1302_read(uchar add)
{
uchar data=0;
uchar i=0;
add+=1; //读标志
set_ds1302_io_ddr(); //端口输出
clr_ds1302_rst(); //清复位
clr_ds1302_sclk(); //清时钟
set_ds1302_rst(); //置复位
for(i=8;i>0;i--) //此循环写入地址码
{
if(add&0x01)
{set_ds1302_io();}
else
{clr_ds1302_io();}
NOP();NOP();
set_ds1302_sclk();
NOP();NOP();
clr_ds1302_sclk();
NOP();NOP();
add>>=1;
}
clr_ds1302_io_ddr(); //端口输入
NOP();NOP();
for(i=8;i>0;i--) //此循环读出1302的数据
{
data>>=1;
if(in_ds1302_io())
{data|=0x80;}
NOP();NOP();
set_ds1302_sclk();
NOP();NOP();
clr_ds1302_sclk();
NOP();NOP();
}
clr_ds1302_rst();
return(data);
}
//向1302中写入时钟数据
void ds1302_write_time(void)
{
ds1302_write(ds1302_control_add,0x00); //关闭写保护
ds1302_write(ds1302_sec_add,0x80); //暂停
ds1302_write(ds1302_charger_add,0xa9); //涓流充电
ds1302_write(ds1302_year_add,timer[0]); //年
ds1302_write(ds1302_month_add,timer[1]); //月
ds1302_write(ds1302_date_add,timer[2]); //日
ds1302_write(ds1302_day_add,timer[3]); //周
ds1302_write(ds1302_hr_add,timer[4]); //时
ds1302_write(ds1302_min_add,timer[5]); //分
ds1302_write(ds1302_sec_add,timer[6]); //秒
ds1302_write(ds1302_control_add,0x80); //打开写保护
}
//从1302中读出当前时钟
void ds1302_read_time(void)
{
timer[0]=ds1302_read(ds1302_year_add); //年
timer[1]=ds1302_read(ds1302_month_add); //月
timer[2]=ds1302_read(ds1302_date_add); //日
timer[3]=ds1302_read(ds1302_day_add); //周
timer[4]=ds1302_read(ds1302_hr_add); //时
timer[5]=ds1302_read(ds1302_min_add); //分
timer[6]=ds1302_read(ds1302_sec_add); //秒
}
void Process(void)//示数据转换函数
{
nian=((timer[0]&0xF0)>>4)+0x30;
nian1=(timer[0]&0x0F)+0x30;
ye=((timer[1]&0xF0)>>4)+0x30;
ye1=(timer[1]&0x0F)+0x30;
ri=((timer[2]&0xF0)>>4)+0x30;
ri1=(timer[2]&0x0F)+0x30;
shi=((timer[4]&0xF0)>>4)+0x30;
shi1=(timer[4]&0x0F)+0x30;
fen=((timer[5]&0xF0)>>4)+0x30;
fen1=(timer[5]&0x0F)+0x30;
miao=((timer[6]&0xF0)>>4)+0x30;
miao1=(timer[6]&0x0F)+0x30;
set_LCD_xy(3,0);
LCD_write_onechar(0,nian); //写指令或数据
LCD_write_onechar(0,nian1); //写指令或数据
set_LCD_xy(6,0);
LCD_write_onechar(0,ye); //写指令或数据
LCD_write_onechar(0,ye1); //写指令或数据
set_LCD_xy(9,0);
LCD_write_onechar(0,ri); //写指令或数据
LCD_write_onechar(0,ri1); //写指令或数据
switch(timer[3])
{
case 1: LCD_write_string(12,0,s1);break;
case 2: LCD_write_string(12,0,s2);break;
case 3: LCD_write_string(12,0,s3);break;
case 4: LCD_write_string(12,0,s4);break;
case 5: LCD_write_string(12,0,s5);break;
case 6: LCD_write_string(12,0,s6);break;
case 7: LCD_write_string(12,0,s7);break;
}
set_LCD_xy(1,1);
LCD_write_onechar(0,shi); //写指令或数据
LCD_write_onechar(0,shi1); //写指令或数据
set_LCD_xy(4,1);
LCD_write_onechar(0,fen); //写指令或数据
LCD_write_onechar(0,fen1); //写指令或数据
set_LCD_xy(7,1);
LCD_write_onechar(0,miao); //写指令或数据
LCD_write_onechar(0,miao1); //写指令或数据
set_LCD_xy(10,1);
LCD_write_onechar(0,t1+0x30); //写指令或数据
LCD_write_onechar(0,t2+0x30); //写指令或数据
LCD_write_onechar(0,'.'); //写指令或数据
LCD_write_onechar(0,t3+0x30); //写指令或数据
}
//////////////////////////////////////////////////////////////////////////////////////////
/*************18B20操作***************/
void delayus(uint x,uchar y)
{
uint i;
uchar j;
for(i=x;i>0;i--);
for(j=y;j>0;j--);
}
void reset()
{
uchar st=1;
DQ_HIGH();
NOP();NOP();NOP();NOP();///111
while(st)
{
DQ_LOW();
delayus(140,66);
DQ_HIGH();
delayus(10,8);
if(DQ==1)
st=1;
else
st=0;
delayus(100,26);
}
}
void write_byte(uchar date)
{
uchar i,temp;
DQ_HIGH();
NOP();NOP();NOP();NOP();///111
for(i=8;i>0;i--)
{
temp=date&0x01;
DQ_LOW();
delayus(2,1);
if(temp==1)
DQ_HIGH();
delayus(6,4);
DQ_HIGH();
date=date>>1;
}
}
uchar read_byte()
{
uchar i;
uint date;
static bit j;
for(i=8;i>0;i--)
{
date=date>>1;
DQ_HIGH();
NOP();NOP();NOP();NOP();//11111111111
DQ_LOW();
NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();/////////////11111111
DQ_HIGH();
NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();//1111111
j=DQ;
if(j==1)
date=date|0x8000;
delayus(4,3);
}
return (date);
}
void get_tem()
{
uint temper;
float aaa;
uchar num,tem1,tem2;
reset(); //复位
write_byte(0xCC);//跳过ROM
write_byte(0x44);//温度转换/750ms
for(num=4;num>0;num--)
{
ds1302_read_time(); //读出当前时钟
Process(); //显示数据转换
delay(10); //每100MS读一次48
}
reset();
write_byte(0xCC);
write_byte(0xBE);
tem1=read_byte();
tem2=read_byte();
aaa=(tem2*256+tem1)*6.25;
temper=(int)aaa;
t1=temper/1000;
t2=temper%1000/100;
t3=temper%100/10;
}
试试这样
tem1=read_byte();
tem2=read_byte();
//aaa=(tem2*256+tem1)*6.25;
temper=(tem2<<4)|(tem1>>4); // unsgined char temper;
if(tem2&0xf0) {temper=~temper; if((tem1&0xf)==0) temper++;} //负数
t1=temper/100;
t2=(temper%100)/10;
t3=temper%10;
however, I would try to bifurcate the issue and see if it is display related or it is rtc related. you can find out the answer by returning a known value from the rtc routine and see how your display module deal with it; hard code a value for the display unit.
once you know the result, you can further narrow it down.
先试下看
t1=1;
t2=2;
t3=3;
这样的显示结果,如果正常,说明显示程序没问题
再往前
tem1=0xb0;
tem2=0x7;
看结果是不是123度等等确定错误的位置
一周热门 更多>