PIC16F877万年历.docx
- 文档编号:3274574
- 上传时间:2022-11-21
- 格式:DOCX
- 页数:64
- 大小:30.52KB
PIC16F877万年历.docx
《PIC16F877万年历.docx》由会员分享,可在线阅读,更多相关《PIC16F877万年历.docx(64页珍藏版)》请在冰豆网上搜索。
PIC16F877万年历
/*******************************************
*标题:
DS18B20测温
*日期:
2008年1月13日
*说明:
使用DS18B20芯片测温
******************************************/
#defineDQRA3//定义18B20数据端口
#defineDQ_DIRTRISC3//定义18B20D口方向寄存器
ucharTemp;
floatf_temp;
voiddelay_18b20(uinti)
{
while(i--);
}
voidinit_DS18B20()//系统初始化函数
{
ucharx=0;
ADCON1=0X07;//设置A口为普通数字口
TRISA=0X00;//设置A口方向为输出
TRISC3=0;
DQ=1;//DQ复位
delay_18b20(8);//稍做延时
DQ=0;//单片机将DQ拉低
delay_18b20(80);//精确延时大于480us--900us
DQ=1;//拉高总线
delay_18b20(14);//拉高36us
x=DQ;//稍做延时后如果x=0则初始化成功x=1则初始化失败
delay_18b20(20);//设置C口方向为输出
}
reset_DS18B20(void)//复位DS18B20函数
{
charpresence=1;
while(presence)
{
DQ=0;//主机拉至低电平
delay(2,90);//延时503us
DQ=1;//释放总线等电阻拉高总线,并保持15~60us
delay(2,8);//延时70us
if(DQ==1)presence=1;//没有接收到应答信号,继续复位
elsepresence=0;//接收到应答信号
delay(2,70);//延时430us
}
}
voidWait_DS18B20()//等待程序,等待ds18b20应答
{
uchari;
while(DQ);
while(!
DQ);
i=6;
while(i>0)i--;
}
voidwrite_byte(uchardat)//写18b20写字节函数
{
uchari,j;
bittemp1;
for(j=8;j>0;j--)
{
temp1=dat&0x01;//最低位移出
dat=dat>>1//从高拉至低电平,产生写时间隙
if(temp1)
{
DQ=0;
i++;i++;i++;i++;
DQ=1;
i=13;
while(i>0)i--;
DQ=1;//如果写1,拉高电平
i++,i++,i++,i++;//延时63us
}
else
{
DQ=0;
i=13;
while(i>0)i--;
DQ=1;
i++;i++;i++;i++;
}
}
}
bitread_temp_bit()//读取18b20一位数据函数
{
uchari;
bitdat;
DQ=0;i++;
DQ=1;i++;i++;
dat=DQ;
i=8;
while(i>0)i--;
return(dat);
}
uchread_temp_byte(void)//读取18b20读一字节函数
{
uchari,j,value=0;
for(i=8;i>0;i--)
{
j=read_temp_bit();
value=(j<<7)|(dat>>1);
}
return(value);
}
voidtemp_Convert(void)//开始转换
{
Reset_DS18B20();
Wait_DS18B20();//等待应答脉冲
Write_byte(0xcc);//跳过序列号脉冲
Write_byte(0x44);//转换命令
}
uintget_temp()//启动温度转换函数
{
inti;
ucharL_18B20,H_18B20;
init_DS18B20();
delay_DS18B20
(1);
reset_DS18B20();
Wait_DS18B20();//复位等待从机应答
write_byte(0XCC);//忽略ROM匹配
write_byte(0Xbe);//发送温度转化命令
L_18B20=Read_temp_byte();//读取低八位数据
H_18B20=Read_temp_byte();//读取高八位数据
temp=H_18B20;
temp<<=8;
temp=temp|L_18B20;
f_temp=temp*0.0625;
temp=f_temp*10+0.5;
return(temp);
}
/**************************************************
*标题:
DS1302读写
*日期:
2008年1月14日
*说明:
日历显示范围:
2000年--2099年
**************************************************/
#defineucharunsignedchar
#defineuintunsignedint
#defineRSTRA5
#defineSCLKRA3
#defineIORA4
ucharflag=0;
intNaoling_hour=6;
intNaoling_minute=30;
intNaoling_hour_1;
intNaoling_minute_1;
intNaoling_hour_2;
intNaoling_minute_2;
intNaoling_hour_3;
intNaoling_minute_3;
ucharkk=0;
ucharsecond=1,minute=1,hour=1,
year=1,month=1,date=1,day=1,
Naohour=1,Naominute=1,kaiguan=1;
ucharclock[]={0};
ucharDisCash[]={0x00,0x30,0x09,0x16,0x01,0x03,0x09};
voidRTInputByte(uchard)//往1302写入1Byte数据
{
uchari;
TRISA=0x00;//A口输出
for(i=8;i>0;i--)
{
IO=d&0x01;//取最低位
SCLK=1;//上升沿发送
SCLK=0;//恢复
d=d>>1;
}
}
ucharRTOutputByte(void)//从1302读取1Byte数据
{
uchari,val=0;
TRISA4=1;//RA4设置为输入
for(i=8;i>0;i--)
{
val=val>>1;
if(IO)val=val|0x80;//从最低位开始接收
SCLK=1;//下降沿接收
SCLK=0;
}
return(val);
}
voidW1302(ucharucAddr,ucharucDa)//先写地址,后写命令/数据
{
RST=0;
SCLK=0;
RST=1;//打开DS1302
RTInputByte(ucAddr);//地址,命令
RTInputByte(ucDa);//写1Byte数据
RST=0;//关闭DS1302
SCLK=1;
}
ucharR1302(ucharucAddr)//先写地址,后读命令/数据
{
ucharucData;
RST=0;
SCLK=0;
RST=1;
RTInputByte(ucAddr);//地址,命令
ucData=RTOutputByte();//读1Byte数据
RST=0;
SCLK=1;
return(ucData);
}
voidSet1302(uchar*pClock)//向1302写入秒分时日月星期年
{
uchari;
ucharucAddr=0x80;//起使地址
W1302(0x8e,0x00);//控制命令,WP=0,允许写操作
for(i=7;i>0;i--)
{
W1302(ucAddr,*pClock);//秒分时日月星期年
pClock++;
ucAddr+=2;//写地址加2
}
W1302(0x8e,0x80);//控制命令,WP=1,写保护
}
voidv_Get1302(ucharucCurtime[])//从1302读出秒分时日月星期年
{
uchari;
ucharucAddr=0x81;
for(i=0;i<7;i++)
{
ucCurtime[i]=R1302(ucAddr);//格式为:
秒分时日月星期年
ucAddr+=2;
}
}
/**************************************************
*标题:
LCD操作
*日期:
2008年1月12日
*说明:
KS0108系列液晶不带字库
**************************************************/
#include
#defineERA0//液晶使能端
#defineRWRA1//读写控制端
#defineDIRA2//数据/指令通道
#defineCSARA5//片选
#defineCSBRA3//片选
#definenop()asm("nop")
voiddelay(charx,chary)//延时
{
charz;
do{
z=y;
do{;}while(--z);
}while(--x);
}
//其指令时间为:
7+(3*(Y-1)+7)*(X-1)如果再加上函数调用的call指令、页面设定、传递参数花掉的7个指令。
则是:
14+(3*(Y-1)+7)*(X-1)。
voidCheckState()//状态检查
{
unsignedintdat;
RW=1;//读状态
DI=0;
TRISB=0xff;//设置口为输入
while
(1)
{
E=1;//高电平读数据
dat=PORTB&0x90;//当4、7位为0时为正常状态
E=0;
if(dat==0x00)break;
}
TRISB=0x00;//恢复口为输出
}
voidWriteData(unsignedchardat)/写显示数据
{
CheckState();
DI=1;//写数据
RW=0;
PORTB=dat;
E=1;
E=0;
}
//command:
操作LCD的指令//写指令
voidWriteCommand(unsignedchardat)
{
CheckState();
RW=0;//写指令
PORTB=dat;
E=1;
E=0;
}
voidSetLine(unsignedcharline)//设定页地址----X:
0--7
{
line=line&0x07;//0<=line<=7
line=line|0xb8;
WriteCommand(line);
}
voidSetColumn(unsignedcharcolumn)//设定列地址----Y:
0--63
{
column=column&0x3f;//0<=column<=63
column=column|0x40;
WriteCommand(column);
}
voidSetStartLine(unsignedcharstartline)//设定开始行
{
startline=startline&0x3f;//0<=startline<=63
startline=startline|0xc0;
WriteCommand(startline);
}
voidSetOnOff(unsignedcharstate)//开关显示1:
开0:
关
{
state=state|0x3e;
WriteCommand(state);
}
voidSlectScreen(unsignedcharscreen)//选择屏幕
//screen:
1:
左屏2:
右屏
{
switch(screen)
{
case1:
CSA=0;
CSB=1;//左屏
break;
case2:
CSA=1;
CSB=0;//右屏
break;
}
}
voidClearScreen(unsignedcharscreen)//清屏
//screen:
1:
左屏2:
右屏
{
unsignedchari,j;
SlectScreen(screen);
for(i=0;i<8;i++)
{
SetLine(i);
for(j=0;j<64;j++)
{
WriteData(0x00);
WriteData(0x00);
}
}
}
//显示一个16X16的汉字
voidShow16X16(unsignedcharline,unsignedcharcolumn,constunsignedchar*pt,uchmode)
{
unsignedchari,column_temp;
uchwei_1,wei_2;
if(mode==0){wei_1=0x00;wei_2=0x00;}
if(mode==1){wei_1=0x01;wei_2=0x00;}
if(mode==2){wei_1=0x00;wei_2=0x80;}
column_temp=column;
SlectScreen
(1);//选通左屏
SetColumn(column);//设置起始列
SetLine(line);//设置行
for(i=0;i<16;i++)
{
if(column>=64)//如果列>=64,则选通右屏
{
SlectScreen
(2);
column=column%64;//设置右屏起始列
SetColumn(column);
SetLine(line);
}
WriteData(*pt|wei_1);//写数据
*pt++;//
column++;
}
SlectScreen
(1);
SetLine(line+1);//设置汉字下半部分显示页
column=column_temp;
SetColumn(column);
for(i=0;i<16;i++)
{
if(column>=64)
{
SlectScreen
(2);
column=column%64;
SetColumn(column);
SetLine(line+1);
}
WriteData(*pt|wei_2);
*pt++;
column++;
}
}
//显示一个8X16的字符
voidShow8X16(unsignedcharline,unsignedcharcolumn,constunsignedchar*pt,uchmode)
{
unsignedchari,column_temp;
uchwei_1,wei_2;
if(mode==0){wei_1=0x00;wei_2=0x00;}
if(mode==1){wei_1=0x01;wei_2=0x00;}
if(mode==2){wei_1=0x00;wei_2=0x80;}
column_temp=column;
SlectScreen
(1);//选通左屏
SetColumn(column);//设置起始列
SetLine(line);//设置行
for(i=0;i<8;i++)
{
if(column>=64)//如果列>=64,则选通右屏
{
SlectScreen
(2);
column=column%64;//设置右屏起始列
SetColumn(column);
SetLine(line);
}
WriteData(*pt|wei_1);//写数据
*pt++;
column++;
}
SlectScreen
(1);
SetLine(line+1);//设置汉字下半部分显示页
column=column_temp;
SetColumn(column);
for(i=0;i<8;i++)
{
if(column>=64)
{
SlectScreen
(2);
column=column%64;
SetColumn(column);
SetLine(line+1);
}
WriteData(*pt|wei_2);
*pt++;
column++;
}
}
//显示一个16X32的字符
voidShow16X32(unsignedcharline,unsignedcharcolumn,constunsignedchar*pt)
{
Unsignedchari,column_temp1,column_temp2,column_temp3;
column_temp1=column;
column_temp2=column;
column_temp3=column;
SlectScreen
(1);//选通左屏
SetColumn(column);//设置起始列
SetLine(line);//设置行
for(i=0;i<16;i++)
{
if(column>=64)//如果列>=64,则选通右屏
{
SlectScreen
(2);
column=column%64;//设置右屏起始列
SetColumn(column);
SetLine(line);
}
WriteData(*pt);//写数据
*pt++;
column++;
}
SlectScreen
(1);
SetLine(line+1);
column=column_temp1;
SetColumn(column);
for(i=0;i<16;i++)
{
if(column>=64)
{
SlectScreen
(2);
column=column%64;
SetColumn(column);
SetLine(line+1);
}
WriteData(*pt);
*pt++;
column++;
}
SlectScreen
(1);
SetLine(line+2);
column=column_temp2;
SetColumn(column);
for(i=0;i<16;i++)
{
if(column>=64)
{
SlectScreen
(2);
column=column%64;
SetColumn(column);
SetLine(line+2);
}
WriteData(*pt);
*pt++;
column++;
}
SlectScreen
(1);
SetLine(line+3);
column=column_temp3;
SetColumn(column);
for(i=0;i<16;i++)
{
if(column>=64)
{
SlectScreen
(2);
column=column%64;
SetColumn(column);
SetLine(line+3);
}
WriteData(*pt);
*pt++;
column++;
}
}
voidLCDinit()//LCD初始化子程序
{
ADCON1=0x06;
TRISA=0x00;
TRISB=0x00;
PORTB=0x00;
SetOnOff
(1);
}
//调用LCD显示子程序
voidChangeToLCD(uchline,uchcolumn,uchdata,uchmode)
{
intD_ge,D_shi;
D_ge=data%10;//取个位
D_shi=data%100/10;//取十位
switch(D_ge)
{
case0:
{Show8X16(line,column+8,s0,mode);break;}
case1:
{Show8X16(line,column+8,s1,mode);break;}
case2:
{Show8X16(line,column+8,s2,mode);break;}
case3:
{Show8X16(line,column+8,s3,mode);break;}
case4:
{Show8X16(line,column+8,s4,mode);break;}
case5:
{Show8X16(line,column+8,s5,mode);break;}
case6:
{Show8X16(line,column+8,s6,mode);break;}
c
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- PIC16F877 万年历