基于PIC16F877A的万年历程序
/*-- 文字: ℃ --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x02,0x05,0xE2,0x18,0x04,0x02,0x02,0x02,0x02,0x02,0x02,0x04,0x1E,0x00,0x00,
0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x18,0x00,0x00,
/*-- 文字: 廿 --*/
/*-- 黑体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x30,0x30,0x30,0x30,0xFF,0xFF,0x30,0x30,0x30,0x30,0xFF,0xFF,0x30,0x30,0x30,0x00,
0x00,0x00,0x00,0x00,0x7F,0x7F,0x18,0x18,0x18,0x18,0x7F,0x7F,0x00,0x00,0x00,0x00,
};
const unsigned int table[101] = {0x4693,
0xDA9B, 0x052B, 0x2A5B, 0xDAAE, 0x756A, 0xDDD5, 0x0BA4, 0x5B49, 0xDD53, 0x0A95,
0x452D, 0xD55D, 0x9AB5, 0xDBAA, 0x05D2, 0x6DA5, 0xEE8A, 0x0D4A, 0x4C95, 0xDA9E,
0x0556, 0x2AB5, 0xDADA, 0x66D2, 0xD765, 0x0725, 0x564B, 0xD657, 0x0CAB, 0x355A,
0xD56E, 0xBB69, 0xDF52, 0x0B52, 0x5B25, 0xDD2B, 0x0A4B, 0x54AB, 0xD2BB, 0x05AD,
0x2B6A, 0xDDAA, 0x7D92, 0xDEA5, 0x0D25, 0x5A55, 0xEA4D, 0x04B6, 0x35B5, 0xE6D2,
0x8EC9, 0xDF92, 0x0E92, 0x6D26, 0xE516, 0x0A57, 0x44D6, 0xE365, 0x0755, 0x3749,
0xD74B, 0x7693, 0xDAAB, 0x052B, 0x5A5B, 0xDABA, 0x056A, 0x4B65, 0xDBAA, 0x8B4A,
0xDD95, 0x0A95, 0x652D, 0xD56D, 0x0AB5, 0x55AA, 0xE5C5, 0x0DA5, 0x3D4A, 0xDE4D,
0x7C96, 0xDCCE, 0x0556, 0x5AB5, 0xEAD2, 0x06D2, 0x5EA5, 0xD72A, 0x868B, 0xD697,
0x04AB, 0x655B, 0xE556, 0x0B6A, 0x4752, 0xDB95, 0x0B25, 0x2A8B, 0xDA4F, 0x04AB
};
void delay(unsigned int t)
{
unsigned int i,j;
for(i=0;i
for(j=0;j<10;j++)
{
asm("NOP");
}
}
}
void data_cvt (unsigned char yy, unsigned char mm, unsigned char dd, unsigned char *moon)
{ unsigned char i,j,leap;
unsigned int days1,days2,x;
days1 = yy * 365 + ((yy+3)>>2) + (mm-1)*30 + dd;
if ((mm >2) && ((yy & 3) == 0) && (yy != 100))
days1 ++;
switch(mm)
{
case 3: days1--;
break;
case 11:
case 12: days1 ++;
case 9:
case 10: days1 ++;
case 8: days1 ++;
case 2:
case 6:
case 7: days1 ++;
}
days1 -=35;
days2=0;
leap=0xFF;
for (i=0; i<=100; i++)
{x=table[i];
for (j=0; j<12; j++)
{
days2 += 29 + (x & 1);
if (days2 >= days1)
break;
if (j==leap)
{
days2 + =16 + (table[i] >> 12);
if (days2 >= days1)
{ j |= 0x80;
x = !(table[i] >> 12);
break;
}
}
x >>= 1;
}
if (days2 >= days1)
break;
leap = x-1;
}
* moon++ = i; //output result
* moon++ = j+1;
* moon = (unsigned char) (29 + (x & 1) -(days2-days1));
}
void delay_T(unsigned char x,unsigned char y)
{
unsigned char z;
do{
z=y;
do{
;
}while(--z);
}while(--x);
}
void init(void)
{
asm("CLRWDT");
ADCON1=0X06;
OPTION=0x81;
TRISA=0B00000000;
TRISB=0B00000000;
TRISC=0B00000000;
TRISD=0B00000000;
TRISE=0B00000000;
PORTA=0x01;
PORTB=0x00;
PORTC=0x00;
PORTD=0x00;
PORTE=0x00;
RBIE=0;
}
unsigned char reset(void)
{
unsigned char outbit;
DQ_LOW(); //主机拉至低电平
delay_T(2,50); //延时503us(480us~960us)
DQ_HIGH(); //释放总线等电阻拉高总线,并保持15~60us
delay_T(2,8); //这里延时70us
if(DQ==1) outbit=0; //检测响应,没有接收到应答信号,说明复位不正确,下次继续复位
else outbit=1; //接收到应答信号
delay_T(2,60); //延时430us ,等待总线恢复高电平
return outbit;
}
void write_byte(unsigned char val)
{
unsigned char i;
unsigned char temp;
for(i=8;i>0;i--)
{
temp=val&0x01; //依次提取每一位
DQ_LOW(); //从高拉至低电平,产生写时间隙
NOP();
NOP();
NOP();
NOP();
NOP();
if(temp==1) DQ_HIGH(); //如果写1,拉高电平
delay_T(2,7); //延时63us(>45us)
DQ_HIGH(); //拉高电平,以备下次写数据
NOP();
NOP();
val=val>>1; //右移一位
}
}
unsigned char read_byte(void)
{
unsigned char i;
unsigned char value=0; //读出温度
static bit j;
for(i=8;i>0;i--)
{
value>>=1; //已经读取的位右移一位
DQ_LOW();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP(); //6us
DQ_HIGH(); //拉至高电平
NOP();
NOP();
NOP();
NOP();
NOP(); //4us
j=DQ; //检测收到的位
if(j) value|=0x80; //收到1,value最高位置1
delay_T(2,7); //63us
}
return(value);
}
void convert_T(void)
{
if(reset()==1) //ds18b20响应了
{
write_byte(0xcc); // 跳过多器件识别
write_byte(0x44); // 启动温度转换
}
}
void read_T(void)
{
unsigned char Lsb,Msb;
if(reset()==1)
{
write_byte(0xcc); // 每次读写前,跳过多器件识别
write_byte(0xbe); // 读暂存器
Lsb=read_byte(); // 低字节
Msb=read_byte(); // 高字节
temp2=Lsb&0x0f; //取出低字节的小数部分的四位
temp1=(Lsb>>4)|(Msb<4); //将高字节的低四位与低字节的高四位和在一块,即位代表温度的整数部分
}
}
PIC16F877A万年历程 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)