12864+DS18B20+DS1302
0赞
#include<iom16v.h>
#include<macros.h>
#define uchar unsigned char
#define uint unsigned int
//12864管脚定义
#define PSB_0 PORTB &= ~(1 << PB1)
#define PSB_1 PORTB |= (1 << PB1)
#define EN_0 PORTB &= ~(1 << PB0)
#define EN_1 PORTB |= (1 << PB0)
#define RW_0 PORTB &= ~(1 << PB2)
#define RW_1 PORTB |= (1 << PB2)
#define RS_0 PORTB &= ~(1 << PB3)
#define RS_1 PORTB |= (1 << PB3)
#define DATAPORT PORTA
//1302管脚定义
#define RST_CLR PORTC &= ~(1 << PC6)
#define RST_SET PORTC |= (1 << PC6)
#define RST_IN DDRC &= ~(1 << PC6)
#define RST_OUT DDRC |= (1 << PC6)
#define IO_CLR PORTC &= ~(1 << PC1)
#define IO_SET PORTC |= (1 << PC1)
#define IO_R PINC & (1 << PC1)
#define IO_IN DDRC &= ~(1 << PC1)
#define IO_OUT DDRC |= (1 << PC1)
#define SCK_CLR PORTC &= ~(1 << PC0)
#define SCK_SET PORTC |= (1 << PC0)
#define SCK_IN DDRC &= ~(1 << PC0)
#define SCK_OUT DDRC |= (1 << PC0)
uchar t;
uchar t,htem,ltem;//定义温度的十位和个位
uchar sec,min,hour,day,month,week,year,year2=20,ah=0,am=0;//定义时间各变量
uchar year_moon,month_moon,day_moon,week;
uchar c_sun,year_sun,month_sun,day_sun;
uchar Flag_1820Error=0;
uint operData;
void delay_5us(void) //5us左右
{
uchar x="7";
while(x)
{
x--;
}
}
void delay_15us(void) //15us左右
{
uchar x="27";
while(x)
{
x--;
}
}
void delay_60us(void) //60us左右
{
uchar x="117";
while(x)
{
x--;
}
}
void delay_nms(uint n)
{
uint i="0",j;
while(i<n)
{
for(j=1;j<1140;j++);
i++;
}
}
void m16_init()
{
PORTA="0x00";
DDRA="0xff";
PORTB="0x00";
DDRB="0xff";
PORTC="0xff";
DDRC="0xff";
}
void wcode(uchar command)
{
RS_0;
delay_nms(2);
RW_0;
delay_nms(2);
DATAPORT="command";
delay_nms(2);
EN_1;
delay_nms(2);
EN_0;
}
void wdata(uchar data)
{
RS_1;
delay_nms(2);
RW_0;
delay_nms(2);
DATAPORT="data";
delay_nms(2);
EN_1;
delay_nms(2);
EN_0;
}
void lcd_pos(uchar X,uchar Y)
{
uchar pos;
if(X==0)
{X=0x80;}
else if(X==1)
{X=0x90;}
else if(X==2)
{X=0x88;}
else if(X==3)
{X=0x98;}
pos="X"+Y;
wcode(pos);
}
void lcd_init()
{
PSB_1;
NOP();
NOP();
wcode(0x30);
delay_nms(1);
wcode(0x0c);
delay_nms(1);
wcode(0x01);
delay_nms(1);
}
void writeString(uchar * str)
{
uchar i = 0;
while(str[i] != '\0')
{
wdata(str[i++]);
}
}
void init_1820(void)
{
uchar i;
uint j="0";
PORTC|=(1<<7); //"1"
PORTC&=~(1<<7); //"0"
for(i=0;i<8;i++)delay_60us();//480us以上
PORTC|=(1<<7); //"1"
DDRC&=~(1<<7); //"PINC7 is INPUT"
delay_15us(); //15~60us
delay_15us();
Flag_1820Error=0;
while(PINC&(1<<7))
{ delay_60us();
j++;
if(j>=18000){Flag_1820Error=1;break;}
}
DDRC|=(1<<7); //PORTC7 is OUTPUT
PORTC|=(1<<7); //"1"
for(i=0;i<4;i++)delay_60us(); //240us
}
void write_1820(uchar x)
{
uchar m;
for(m=0;m<8;m++)
{
if(x&(1<<m)) //写数据,从低位开始
{PORTC&=~(1<<7);delay_5us(); //"0",5us
PORTC|=(1<<7); //write"1"
delay_15us(); //15~45us
delay_15us();
delay_15us();
}
else
{PORTC&=~(1<<7);delay_15us();//"0",15us
delay_15us(); //write"0"
delay_15us(); //15~45us
delay_15us();
PORTC|=(1<<7); //"1"
}
}
PORTC|=(1<<7); //"1"
}
uchar read_1820(void)
{
uchar temp,k,n;
temp="0";
for(n=0;n<8;n++)
{
PORTC&=~(1<<7); //"0"
delay_5us();
PORTC|=(1<<7); //"1"
delay_5us();
DDRC&=~(1<<7); //"PINC7 is INPUT"
k=(PINC&(1<<7)); //读数据,从低位开始
if(k)
temp|=(1<<n); //read"1"
else
temp&=~(1<<n); //read"0"
delay_15us(); //45us
delay_15us();
delay_15us();
DDRC|=(1<<7); //PORTC7 is OUTPUT
}
return (temp);
}
void read_temperature(void)
{
init_1820(); //复位18b20
write_1820(0xcc); // 发出转换命令
write_1820(0x44);
init_1820();
write_1820(0xcc); //发出读命令
write_1820(0xbe);
ltem="read"_1820(); //读数据byte1
htem="read"_1820(); //byte2
ltem=ltem>>4; //低字节右移4位,去掉小数位
t=htem<<4; //高字节左移4位,去掉符号位
t|=ltem; //合并整数部分
}
void writebyte(void)
{
uint i;
IO_OUT;
delay_nms(1);
for (i = 0; i < 8; i ++)
{
SCK_CLR;//SCK_CLR如果移到SCK_SET后面 则偶数显示不了,无论是写字节还是读字节 特别注意
if (operData & 0x01)
{
IO_SET;
}
else {
IO_CLR;
}
SCK_SET; //还是下降沿
operData = operData >> 1;
}
}
void readbyte(void)
{
uint i;
IO_IN;
for (i = 0; i < 8; i ++)
{
SCK_CLR;
operData = operData >> 1;
if (IO_R)
{
operData |= 0x80;
}
else
{
operData &= 0x7F;
}
SCK_SET;
}
}
void ds1302_write_byte(uchar addr, uchar d)
{
RST_CLR;
SCK_CLR;
RST_SET;
operData="addr";
writebyte();
operData="d";
writebyte();
RST_CLR;
SCK_SET;
}
uchar ds1302_read_byte(uchar addr)
{
SCK_CLR;
RST_CLR;
RST_SET;
operData=addr;
writebyte();
readbyte();
RST_CLR;
SCK_SET;
return(operData) ;
}
void ds1302_write_time()
{
ds1302_write_byte(0x8e,0x00); // 关闭写保护
ds1302_write_byte(0x8c,0x09); //年
ds1302_write_byte(0x88,0x11); //月
ds1302_write_byte(0x86,0x16); //日
ds1302_write_byte(0x84,0x14); //时
ds1302_write_byte(0x82,0x40); //分
ds1302_write_byte(0x80,0x06); //秒
ds1302_write_byte(0x8e,0x80); //打开写保护
}
void ds1302_read_time()
{
delay_nms(1);
sec="ds1302"_read_byte(0x81);//秒
sec=(sec>>4)*10+(sec&0x0f); //秒二进制转换
min=ds1302_read_byte(0x83); //分
min=(min>>4)*10+(min&0x0f);
hour="ds1302"_read_byte(0x85); //时
hour=(hour>>4)*10+(hour&0x0f);
day=ds1302_read_byte(0x87); //日
day=(day>>4)*10+(day&0x0f);
month=ds1302_read_byte(0x89); //月
month=(month>>4)*10+(month&0x0f);
year=ds1302_read_byte(0x8d); //读年
year=(year>>4)*10+(year&0x0f);
}
void ds1302_init(void)
{
RST_OUT;
SCK_OUT;
IO_OUT;
}
void show()
{
ds1302_read_time();
delay_nms(5);
read_temperature();
lcd_pos(0,0);
wdata(year2/10+0x30);wdata(year2%10+0x30);
wdata(year/10+0x30);wdata(year%10+0x30);
delay_nms(2);
writeString(" 年");
wdata((month/10)+0x30);wdata((month%10)+0x30);
writeString("月");
wdata((day/10)+0x30);wdata((day%10)+0x30);
writeString("日");
lcd_pos(1,0);
writeString("星期六");
wdata((hour/10)+0x30);wdata((hour%10)+0x30);
writeString(": ");
wdata((min/10)+0x30);wdata((min%10)+0x30);
writeString(": ");
wdata((sec/10)+0x30);wdata((sec%10)+0x30);
lcd_pos(2,0);
writeString("温度");
wdata(t/10+0x30);wdata(t%10+0x30);
writeString("℃");
}
void init()
{
m16_init();
lcd_init();
delay_nms(10);
init_1820();
delay_nms(10);
ds1302_init();
delay_nms(10);
ds1302_write_time();
delay_nms(10);// 写入时间初始值
}
void main()
{
init();
while(1)
{
show();
}
}
