单片机
返回首页

PIC16F84A读取时钟芯片DS1302的简单示例

2016-11-03 来源:eefocus

//引入文件***********************************************************

#include      'delay.h'
#include      'delay.c'
#include     
#include     

//熔丝配置***********************************************************
__CONFIG(XT & WDTDIS & PWRTEN & PROTECT);

//引脚定义***********************************************************
#define       RS        RB4                                //选寄存器
#define       EN        RB5                                //信号使能

//时钟芯片***********************************************************
#define       RST       RA0                                //芯片使能 
#define       CLK       RA1                                //芯片时钟
#define       DAT       RA2                                //芯片数据

//显示字符***********************************************************
     unsigned char TopChar[] = {'                '};       //显示缓冲 
     unsigned char BotChar[] = {'                '};       //

//*******************************************************************
//函数名称:portInit();
//输入参数:无
//输出参数:无
//功能描述:端口设置
//建造日期:2008.12.12
//*****************************************************************
void PortInit(void)
 {
     PORTA  = 0x00;                                        //端口设置 
     PORTB  = 0x00;                                        //
 
     TRISA  = 0x00;                                        //方向设置   
     TRISB  = 0x00;                                        //

     OPTION = 0x00;                                        //上拉便能
 }

//*******************************************************************
//函数名称: WriteData(data, rs);
//输入参数:待写数据,0 = 指令 1 = 数据 
//输出参数:无
//功能描述:写1602LCD
//建造日期:2008.12.12
//*******************************************************************
void WriteData(unsigned char data, unsigned char rs)
 {   
     RS = 0;                                               //假设指令

     if (rs & 0x01) RS = 1;                                //实际数据

     PORTB = ((PORTB & 0xf0 ) | (data >> 4));              //写高四位    
     EN = 1;                                               //使能下沿 
     EN = 0;                                               //
     DelayUs(50);                                          //
    
     PORTB = ((PORTB & 0xf0) | (data & 0x0f));             //写低四位
     EN = 1;                                               //使能下沿 
     EN = 0;                                               //                                            
     DelayUs(50);                                          //
 }

//*******************************************************************
//函数名称:AddrSite();
//输入参数:坐标参数
//输出参数:无
//功能描述:设置显示地址
//建造日期:2008.12.12
//*******************************************************************
void AddrSite(unsigned char x, unsigned char y)
 {     
     if (y == 0) WriteData((0x80 | x) , 0);                //首行地址
     
     else WriteData((0xc0 | x), 0);                        //次行地址 
 }

//*******************************************************************
//函数名称:PrintChar(*s, len);
//输入参数:缓冲区首址, 数据长度
//输出参数:无
//功能描述:字符串输出显示
//建造日期:2008.12.12
//*******************************************************************
void PrintChar(unsigned char *s, unsigned char len)
 {   
     do                                                    //循环发送                                      
     {
       WriteData(*s, 1);                                   //显示字符
       s++;                                                //下个字符
     }
     while (--len);                                        //显示一行
 }

//*******************************************************************
//函数名称:LcdInit();
//输入参数:无
//输出参数:无
//功能描述:液晶初始化
//建造日期:2008.12.12
//*******************************************************************
void LcdInit(void)
 {   
     unsigned char i = 3;

     RS = 0;                                               //选择命令
     PORTB = 0x03;                                         //接口设置

     do
     {
       EN = 1;                                             //使能下沿 
       EN = 0;                                             //
       DelayUs(50);      
     }
     while (--i);                                          //循环三次

     PORTB = 0x02;                                         //四线模式
     EN = 1;                                               //使能下沿 
     EN = 0;                                               //
     DelayUs(50);     

     WriteData(0x28, 0);                                   //接口设置
     WriteData(0x0c, 0);                                   //显示打开
     WriteData(0x01, 0);                                   //显示清屏
     WriteData(0x06, 0);                                   //地址递增
 }

//*******************************************************************
//函数名称:WriteByte(data);
//输入参数:待写数据
//输出参数:无
//功能描述:Ds1302写数据
//建造日期:2008.12.12
//*******************************************************************
void WriteByte(unsigned char data)
 {
     unsigned char i;
     
     TRISA2 = 0;                                           //输出方向
     i = 8;                                                //发送八位    

     do
     {
       DAT = 0;                                            //假设为假 
           
       if (data & 0x01) DAT = 1;                           //实际为真
       
       CLK = 1;                                            //时钟上升
       data >>= 1;                                         //右移一位
       CLK = 0;                                            //时钟清零
     }
     while (--i);                                          //循环发送  
 }

//*******************************************************************
//函数名称:ReadByte();
//输入参数:无
//输出参数:时钟数据
//功能描述:Ds1302读数据
//建造日期:2008.12.12
//*******************************************************************
unsigned char ReadByte(void)
 {
     unsigned char i, data;
     
     TRISA2 = 1;                                           //输入方向
     i = 8;                                                //收集八位

     do
     {
       data >>= 1;                                         //数据右移

       if (DAT) data |= 0x80;                              //记录一位

       CLK = 1;                                            //时钟置位
       NOP();                   
       CLK = 0;                                            //时钟下降
     }
     while (--i);                                          //循环接收

     return data;                                          //返回数据        
 }

//*******************************************************************
//函数名称:WriteDs1302(addr, code);
//输入参数:寄存器地址,指令
//输出参数:无
//功能描述:Ds1302写操作
//建造日期:2008.12.12
//*******************************************************************
void WriteDs1302(unsigned char addr, unsigned char code)
 {
     RST = 0;                                              //便能清零
     CLK = 0;                                              //时钟清零
     RST = 1;                                              //使用有效
      
     WriteByte(addr & 0xfe);                               //写入地址
     WriteByte(code);                                      //写入数据
   
     CLK = 1;                                              //时钟置位
     RST = 0;                                              //便能失效
 } 
//*******************************************************************
//函数名称:ReadDs1302(addr);
//输入参数:寄存器地址
//输出参数:功能数据
//功能描述:Ds1302读操作
//建造日期:2008.12.12
//*******************************************************************
unsigned char ReadDs1302(unsigned addr)
 {   
     unsigned char code;

     RST = 0;                                              //便能清零
     CLK = 0;                                              //时钟清零
     RST = 1;                                              //使用有效
      
     WriteByte(addr | 0x01);                               //写入地址
     code = ReadByte();                                    //读取数据
   
     CLK = 1;                                              //时钟置位
     RST = 0;                                              //便能失效

     return code;                                          //返回数据
 }

//*******************************************************************
//函数名称:TimeCahr();
//输入参数:无
//输出参数:无
//功能描述:时钟转换字符
//建造日期:2008.12.12
//*******************************************************************
void TimeCahr(void)
 {     
     unsigned char data;
     
     data = ReadDs1302(0x8c);                              //年  数据
     TopChar[2] = 0x30 + (data >> 4);                      //年  十位
     TopChar[3] = 0x30 + (data & 0x0f);                    //年  个位

     data = ReadDs1302(0x88);                              //月  数据
     TopChar[5] = 0x30 + (data >> 4);                      //月  十位
     TopChar[6] = 0x30 + (data & 0x0f);                    //月  个位
 
     data = ReadDs1302(0x86);                              //日  数据
     TopChar[8] = 0x30 + (data >> 4);                      //日  十位
     TopChar[9] = 0x30 + (data & 0x0f);                    //日  个位
     
     data = ReadDs1302(0x84);                              //时钟数据
     BotChar[0] = 0x30 + (data >> 4);                      //时  十位  
     BotChar[1] = 0x30 + (data & 0x0f);                    //时  个位
       
     data = ReadDs1302(0x82);                              //分钟数据
     BotChar[3] = 0x30 + (data >> 4);                      //分  十位  
     BotChar[4] = 0x30 + (data & 0x0f);                    //分  个位
       
     data = ReadDs1302(0x80);                              //秒钟数据
     BotChar[6] = 0x30 + (data >> 4);                      //秒  十位  
     BotChar[7] = 0x30 + (data & 0x0f);                    //秒  个位 
 }

//*******************************************************************
//函数名称:Picture();
//输入参数:无
//输出参数:无
//功能描述:显示图片
//建造日期:2008.12.12
//*******************************************************************
void Picture(void)
 {
     TopChar[0]  = '2';                                    //默认年号
     TopChar[1]  = '0';
     TopChar[4]  = '/';                                    //日期标号
     TopChar[7]  = '/';
     BotChar[2]  = ':';                                    //时钟标号
     BotChar[5]  = ':';
 }

//*******************************************************************
//函数名称:Ds1302Init();
//输入参数:无
//输出参数:无
//功能描述:时钟芯片设置
//建造日期:2008.12.12
//*******************************************************************
void Ds1302Init(void)
 {
     unsigned char code;    
    
     code = ReadDs1302(0x80);                              //读振荡器

     if (code & 0x80)                                      //是否停振
     {
       WriteDs1302(0x8e, 0x00);                            //允许写入
       WriteDs1302(0x8c, 0x08);                            //默认日期
       WriteDs1302(0x88, 0x01);
       WriteDs1302(0x86, 0x01);
       WriteDs1302(0x84, 0x00);                            //默认时间    
       WriteDs1302(0x82, 0x00);                           
       WriteDs1302(0x80, 0x00);
       WriteDs1302(0x8e, 0x80);                            //禁止写入
     } 
     
     code = ReadDs1302(0x90);                              //充电状态
      
     if (code != 0xab)                                     //设置不符 
     {
       WriteDs1302(0x8e, 0x00);                            //允许写入
       WriteDs1302(0x90, 0xab);                            //充电设置                                  
       WriteDs1302(0x8e, 0x80);                            //禁止写入
     }
 }

//*******************************************************************
//函数名称:main();
//输入参数:无
//输出参数:无
//功能描述:主要程序
//建造日期:2008.12.12
//*******************************************************************
void main(void)                                            
 {   
     unsigned char count, i;
 
     PortInit();                                           //脚位设置                   
     LcdInit();                                            //液晶设置
     Ds1302Init();                                         //时钟设置 
     TimeCahr();                                           //时间转换
     Picture();                                            //显示标号
 
     while (1)
     {
       AddrSite(0, 0);                                     //坐标设置
       PrintChar(TopChar, 16);                             //发送字符
       
       AddrSite(0, 1);                                     //坐标设置
       PrintChar(BotChar, 16);                             //发送字符

       DelayMs(100);                                       //更新周期
       TimeCahr();                                         //更新时间
     }  
 }

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

最新器件
精选电路图
  • 光控音效发生器电路

  • 非常简单的150W功放电路图

  • 一个简单的警笛电路图

  • 基于IC555的可变PWM振荡器电路

  • 分享一个电网倾角计电路

  • 电谐波图形均衡器示意图

    相关电子头条文章