Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2012742
  • 博文数量: 356
  • 博客积分: 8284
  • 博客等级: 中将
  • 技术积分: 4580
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-15 20:25
个人简介

天行健,君子以自强不息

文章分类

全部博文(356)

文章存档

2018年(1)

2016年(4)

2015年(13)

2014年(14)

2013年(2)

2012年(25)

2011年(43)

2010年(65)

2009年(189)

分类: C/C++

2010-04-13 20:00:48

c程序:
文件: 51+ds1302+key(存在小故障).rar
大小: 29KB
下载: 下载
原理图:
pcb图:
文件: 万年历pcb.pdf
大小: 17KB
下载: 下载
pcb工程文件:
文件: 51+ds1302+key(存在小故障).rar
大小: 29KB
下载: 下载
//注:第一次下载的时候不注释setRtc(),第二次下载的时候注释掉它。
 
-----------------------------------------------------------------------------------程序修正版:
可以显示时间和温度,在P1^1口接18b20,工程如下:
文件: bishe.rar
大小: 1342KB
下载: 下载
---------------------------------------------------------------------------------
ds1302驱动
#include
#include
 
sbit SCK=P3^6;  
sbit SDA=P3^4;  
sbit RST=P3^5;
/*复位脚*/
#define RST_CLR RST=0/*电平置低*/
#define RST_SET RST=1/*电平置高*/

/*双向数据*/
#define IO_CLR SDA=0/*电平置低*/
#define IO_SET SDA=1/*电平置高*/
#define IO_R SDA/*电平读取*/

/*时钟信号*/
#define SCK_CLR SCK=0/*时钟信号*/
#define SCK_SET SCK=1/*电平置高*/

#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
unsigned char time_buf1[8] = {20,9,3,13,18,51,00,6};//空年月日时分秒周
unsigned char time_buf[8] ;//空年月日时分秒周
/*向DS1302写入一字节数据*/
void ds1302_write_byte(unsigned char addr, unsigned char d) {
 unsigned char i;
 RST_SET;     /*启动DS1302总线*/
 
 /*写入目标地址:addr*/
 addr = addr & 0xFE;/*最低位置零*/
 for (i = 0; i < 8; i ++) {
    
  if (addr & 0x01) {
   IO_SET;
   }
  else {
   IO_CLR;
   }
  SCK_SET;
  SCK_CLR;
  addr = addr >> 1;
  }
 
 /*写入数据:d*/
 for (i = 0; i < 8; i ++) {
    
  if (d & 0x01) {
   IO_SET;
   }
  else {
   IO_CLR;
   }
  SCK_SET;
  SCK_CLR;
  d = d >> 1;
  }
 RST_CLR;     /*停止DS1302总线*/
}
/*从DS1302读出一字节数据*/
unsigned char ds1302_read_byte(unsigned char addr) {
 unsigned char i;
 unsigned char temp;
 RST_SET;     /*启动DS1302总线*/
 /*写入目标地址:addr*/
 addr = addr | 0x01;/*最低位置高*/
 for (i = 0; i < 8; i ++) {
     
  if (addr & 0x01) {
   IO_SET;
   }
  else {
   IO_CLR;
   }
  SCK_SET;
  SCK_CLR;
  addr = addr >> 1;
  }
 
 /*输出数据:temp*/
 for (i = 0; i < 8; i ++) {
  temp = temp >> 1;
  if (IO_R) {
   temp |= 0x80;
   }
  else {
   temp &= 0x7F;
   }
  SCK_SET;
  SCK_CLR;
  }
 
 RST_CLR;     /*停止DS1302总线*/
 return temp;
}
/*向DS302写入时钟数据*/
void ds1302_write_time(void) {
    
    unsigned char i,tmp;
 for(i=0;i<8;i++){           //BCD处理
  tmp=time_buf1[i]/10;
  time_buf[i]=time_buf1[i]%10;
  time_buf[i]=time_buf[i]+tmp*16;
 }
 ds1302_write_byte(ds1302_control_add,0x00);   //关闭写保护
 ds1302_write_byte(ds1302_sec_add,0x80);    //暂停
 ds1302_write_byte(ds1302_charger_add,0xa9);   //涓流充电
 ds1302_write_byte(ds1302_year_add,time_buf[1]);  //年
 ds1302_write_byte(ds1302_month_add,time_buf[2]); //月
 ds1302_write_byte(ds1302_date_add,time_buf[3]);  //日
 ds1302_write_byte(ds1302_day_add,time_buf[7]);  //周
 ds1302_write_byte(ds1302_hr_add,time_buf[4]);  //时
 ds1302_write_byte(ds1302_min_add,time_buf[5]);  //分
 ds1302_write_byte(ds1302_sec_add,time_buf[6]);  //秒
 ds1302_write_byte(ds1302_day_add,time_buf[7]);  //周
 ds1302_write_byte(ds1302_control_add,0x80);   //打开写保护
}
/*从DS302读出时钟数据*/
void ds1302_read_time(void)  {
        unsigned char i,tmp;
 time_buf[1]=ds1302_read_byte(ds1302_year_add);  //年
 time_buf[2]=ds1302_read_byte(ds1302_month_add);  //月
 time_buf[3]=ds1302_read_byte(ds1302_date_add);  //日
 time_buf[4]=ds1302_read_byte(ds1302_hr_add);  //时
 time_buf[5]=ds1302_read_byte(ds1302_min_add);  //分
 time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7F;//秒
 time_buf[7]=ds1302_read_byte(ds1302_day_add);  //周

 for(i=0;i<8;i++){           //BCD处理
  tmp=time_buf[i]/16;
  time_buf1[i]=time_buf[i]%16;
  time_buf1[i]=time_buf1[i]+tmp*10;
 }
}
/*DS302初始化函数*/
void ds1302_init(void) {
 
 RST_CLR;   /*RST脚置低*/
 SCK_CLR;   /*SCK脚置低*/
}
-----------------------------------------------------------------------------------
18b20驱动:
#include
#include
sbit DQ=P1^1;
unsigned char tempL=0; //临时变量低位
unsigned char tempH=0; //临时变量高位
float temperature; //温度值
/****************************************************************************
函数功能:延时子程序
入口参数:k
出口参数:
****************************************************************************/
void delay(unsigned int k)
{
unsigned int n;
n=0;
while(n < k)
{n++;}
return;
}
/****************************************************************************
函数功能:数码管扫描延时子程序
入口参数:
出口参数:
****************************************************************************/
void delay1(void)
{
int k;
for(k=0;k<400;k++);
}
 
/****************************************************************************
函数功能:DS18B20初始化子程序
入口参数:
出口参数:
****************************************************************************/
Init_DS18B20(void)
{
unsigned char x=0;
DQ=1; //DQ先置高
delay(8); //延时
DQ=0; //发送复位脉冲
delay(85); //延时(>480ms)
DQ=1; //拉高数据线
delay(14); //等待(15~60ms)
}
/****************************************************************************
函数功能:向DS18B20读一字节数据
入口参数:
出口参数:dat
****************************************************************************/
ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat=0;
for (i=8;i>0;i--)
{
DQ=1;
delay(1);
DQ=0;
dat>>=1;
DQ=1;
if(DQ)
dat|=0x80;
delay(4);
}
return(dat);
}
/****************************************************************************
函数功能:向DS18B20写一字节数据
入口参数:dat
出口参数:
****************************************************************************/
WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;
}
delay(4);
}
/****************************************************************************
函数功能:向DS18B20读温度值
入口参数:
出口参数:temperature
****************************************************************************/
float ReadTemperature(void)
{
Init_DS18B20(); //初始化
WriteOneChar(0xcc); //跳过读序列号的操作
WriteOneChar(0x44); //启动温度转换
delay(125); //转换需要一点时间,延时
Init_DS18B20(); //初始化
WriteOneChar(0xcc); //跳过读序列号的操作
WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位)
tempL=ReadOneChar(); //读出温度的低位LSB
tempH=ReadOneChar(); //读出温度的高位MSB
//温度转换,把高低位做相应的运算转化为实际温度
temperature=((tempH*256)+tempL)*0.0625;
delay(200);
return(temperature);
}
-----------------------------------------------------------------------------------
1602驱动:
#include
#include
#include
sbit RS = P2^7;//Pin4
sbit RW = P2^6; //Pin5
sbit E  = P2^5;//Pin6
#define Data  P0    //数据端口
unsigned char TempData[8];
unsigned char  SecondLine[]="                ";
unsigned char  FirstLine[] ="                ";
/******************************************************************/
/*                    函数声明                                    */
/******************************************************************/
void DelayUs(unsigned char us)//delay us
{
 unsigned char uscnt;
 uscnt=us>>1;/* Crystal frequency in 12MHz*/
 while(--uscnt);
}
/******************************************************************/
void DelayMs(unsigned char ms)//delay Ms
{
 while(--ms)
   {
     DelayUs(250);
     DelayUs(250);
  DelayUs(250);
  DelayUs(250);
   }
}
void WriteCommand(unsigned char c)
{
 DelayMs(5);//short delay before operation
 E=0;
 RS=0;
 RW=0;
 _nop_();
 E=1;
 Data=c;
 E=0;
}
/****************************************************************/
void WriteData(unsigned char c)
{
 DelayMs(5);   //short delay before operation
 E=0;
 RS=1;
 RW=0;
 _nop_();
 E=1;
 Data=c;
 E=0;
 RS=0;
}
/*********************************************************************/
void ShowChar(unsigned char pos,unsigned char c)
{
 unsigned char p;
 if (pos>=0x10)
    p=pos+0xb0; //是第二行则命令代码高4位为0xc
 else
    p=pos+0x80; //是第二行则命令代码高4位为0x8
 WriteCommand (p);//write command
 WriteData (c);   //write data
}
/*************************************************************************/
void ShowString (unsigned char line,char *ptr)
{
 unsigned char l,i;
 l=line<<4;
 for (i=0;i<16;i++)
  ShowChar (l++,*(ptr+i));//循环显示16个字符
}
/*********************************************************************/
void InitLcd()
{
 DelayMs(15);
 WriteCommand(0x38); //display mode
 WriteCommand(0x38); //display mode
 WriteCommand(0x38); //display mode
 WriteCommand(0x06); //显示光标移动位置
 WriteCommand(0x0c); //显示开及光标设置
 WriteCommand(0x01); //显示清屏
}
void dist(int x)
{
   SecondLine[11]='0'+x/100;
   SecondLine[12]='0'+x%100/10;
   SecondLine[13]='0'+x%10;
   ShowString(1,SecondLine);
}
/////////////////////////////////////////////////////////////////
void disp(int x)
{
 //年-月-日 ^周^
 FirstLine[0]='2';
 FirstLine[1]='0';
 FirstLine[2]='0'+TempData[1]/10;
 FirstLine[3]='0'+TempData[1]%10;
 FirstLine[4]='-';
 FirstLine[5]='0'+TempData[2]/10;
 FirstLine[6]='0'+TempData[2]%10;
 FirstLine[7]='-';
 FirstLine[8]='0'+TempData[3]/10;
 FirstLine[9]='0'+TempData[3]%10;
 FirstLine[15]='0'+TempData[7]%10;
 
 
 SecondLine[0]='0'+TempData[4]/10;
 SecondLine[1]='0'+TempData[4]%10;
 SecondLine[2]=':';
 SecondLine[3]='0'+TempData[5]/10;
 SecondLine[4]='0'+TempData[5]%10;
 SecondLine[5]=':';
 SecondLine[6]='0'+TempData[6]/10;
 SecondLine[7]='0'+TempData[6]%10;
 if(x>100)
 {
  SecondLine[11]='0'+x/100;
  SecondLine[12]='0'+x%100/10;
  SecondLine[13]='.';
  SecondLine[14]='0'+x%10;
  SecondLine[15]='C';
 }
 else if(x>10)
 {
     SecondLine[11]='0'+x/100;
  SecondLine[12]='.';
  SecondLine[13]='0'+x%100/10;
  SecondLine[14]='0'+x%10;
  SecondLine[15]='C';
 }
 else
 {
  SecondLine[11]='0'+x/100;
  SecondLine[12]='0'+x%100/10;
  SecondLine[13]='0'+x%10;
  SecondLine[15]='C';
 }

ShowString(0,FirstLine);
//时:分:秒
ShowString(1,SecondLine);
 
}
-----------------------------------------------------------------------------------
主函数:

#include
#include"ds1302.h"
#include"LCD1602.h"
#include "ds18b20.h"
sbit LACTCH1=P2^0;//锁存端口定义
sbit LACTCH2=P2^3;

bit SetFlag;      //更新时间标志位
unsigned char time_buf2[16];
void UART_Init(void)
{
   // SCON  = 0x50;          /* SCON: 模式 1, 8-bit UART, 使能接收         */
    TMOD |= 0x20;               /* TMOD: timer 1, mode 2, 8-bit reload        */
    TH1   = 0xFD;               /* TH1:  reload value for 9600 baud @ 11.0592MHz   */
    TR1   = 1;                  /* TR1:  timer 1 run                          */
    //EA    = 1;                  /*打开总中断*/
    //ES    = 1;                  /*打开串口中断*/
}
int get_temp()
{
temperature=ReadTemperature();
return  (int)(temperature*10);
}
main()
{
  unsigned char i;
       UART_Init();
       P0=0;       //取显示数据,屏蔽数码管显示
       LACTCH1=1;  //锁存
       LACTCH1=0;
      
    P0=0;       //取段码
       LACTCH2=1;  // 锁存
       LACTCH2=0;
  
       ds1302_init(); /*DS302初始化函数*/
       //ds1302_write_time();
       InitLcd();     //初始化LCD
    Init_DS18B20();
       DelayMs(15);   //延时用于稳定功能
  while(1)
       {
     ds1302_read_time();//读取时钟信息
 
  //dist(get_temp());
  disp(get_temp());         //液晶显示时间信息
   //dist(123);
  //delay(1000);
        for(i=1;i<8;i++)
     TempData[i]=time_buf1[i];
           //disp();         //液晶显示时间信息
           //KeyPro();
     /*
     if(SetFlag)     //如果接收到串口信息则更新时钟
       {
     for(i=0;i<8;i++)
     {
     time_buf1[i]=time_buf2[2*i]*10+time_buf2[2*i+1];//数据整合,如2个数 1和5整合成15
     }
     ds1302_write_time();
     SetFlag=0;     //时钟信息更新后标志位清零
    }
    */
      }
 
  }
/******************************************************************/
/*                  串口中断程序                                  */
/******************************************************************/
void UART_SER (void) interrupt 4 //串行中断服务程序
{
    unsigned char Temp;          //定义临时变量
   
    unsigned char i;
   if(RI)                        //判断是接收中断产生
     {
   RI=0;                      //标志位清零
   Temp=SBUF;                 //读入缓冲区的值
   time_buf2[i]=Temp&0x0F;
   i++;
   if(i==16)                  //连续接收16个字符信息
    {
     i=0;
  SetFlag=1;               //接收完成标志位置1
    }
      SBUF=Temp; //把接收到的值再发回电脑端
   //P1=Temp&0x0F; //调试时候显示
  }
   if(TI)  //如果是发送标志位,清零
     TI=0;
}

阅读(1634) | 评论(0) | 转发(0) |
0

上一篇:1602(sprintf函数使用)

下一篇:212

给主人留下些什么吧!~~