MCU

12864+DS18B20+DS1302

0
阅读(3147)

#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();
 }
}