IIC的PCF8563实用时钟程序(iccavr)

发布者:明石轩最新更新时间:2016-10-29 来源: eefocus关键字:IIC  PCF8563  时钟程序  iccavr 手机看文章 扫描二维码
随时随地手机看文章
/*************************************

* PCF8563时钟程序    *
* 文 件 名:1602_8563.c     *
* 版    本:V22.02       *
* 主控芯片:Mega16L      *
* 工作频率:7.3728MHz     *
*************************************/
#include
#include
#include
#include
#include
#include
#include

//数据简化宏定义
#define uchar unsigned char
#define uint unsigned int

//全局变量定义
uchar timer[8];         //时钟数据

/**********************************
*         蜂鸣器发声函数        *
* 函数功能:蜂鸣器发出声响    *
* 入    口:n 声次数       *
*    i 声时长,i*10ms   *
* 返    回:无         *
* 发声频率:固定1KHz 无源    *
**********************************/
void spk(uchar i,uchar n)
    {
 uint a;
 for(;n;n--)
     {
  a=i*10;               //计算每声响的长度:MS
  for(;a;a--)
      {
   delay_us(500);     //响声频率为1KHZ
   SPK_TG;
   delay_us(500);
   SPK_TG;
   }
  SPK_OFF;            //响完关闭蜂鸣器
  delay_ms(100);      //每声响之间隔100MS
  }
 }

/**********************************
*          读出数据函数     *
**********************************/
uchar read_timer(void)
    {
 start();                //启动总线
 waitack();        //等待启动完成
 if(chkack()!=START)return I2C_ERR;    //检查是否启动成功
 write_tim(SLA_W);      //发送写地址
 write_tim(0x02);      //写数据地址
 
 start();
 waitack();        //等待启动完成
 if(chkack()!=RESTART)return I2C_ERR;   //检查是否启动成功
 write_tim(SLA_R);      //发送读地址
 
 timer[0]=read_tim()&0x7F;    //读出秒数据
 timer[1]=read_tim()&0x7F;    //读出分数据
 timer[2]=read_tim()&0x3F;    //读出时数据
 timer[3]=read_tim()&0x3F;    //读出日数据
 timer[4]=read_tim()&0x07;    //读出周数据
    if(timer[4]==0)timer[4]=7;
 timer[5]=read_tim();       //读出月数据
    if((timer[5]&0x80)==0)
         timer[7]=0x20;      //世纪位为0,是21世纪
    else timer[7]=0x19;     //世纪位不为0,是20世纪
 timer[5]=timer[5]&0x1F;
 timer[6]=read_tim();     //读出年数据
 stop();
 return I2C_CRR;
 }

/**********************************
*          写入时钟函数     *
**********************************/
uchar write_timer(void)
    {
 start();                //启动总线
 waitack();        //等待启动完成
 if(chkack()!=START)return I2C_ERR;    //检查是否启动成功
 write_tim(SLA_W);      //发送写地址
 write_tim(0x00);      //写数据首地址
 write_tim(0x20);      //写控制/状态寄存器1,暂停计时
 write_tim(0x00);      //写控制/状态寄存器2
 write_tim(0x00);      //写秒数据为0
 write_tim(timer[1]);     //写分数据
 write_tim(timer[2]);     //写时数据
 write_tim(timer[3]);     //写日数据
 write_tim(timer[4]);     //写周数据
 write_tim(timer[5]);     //写月数据
 write_tim(timer[6]);     //写年数据
 stop();
 return I2C_CRR;
 }
 
/**********************************
*          启动时钟函数     *
**********************************/
uchar start_timer(void)
    {
 start();                //启动总线
 waitack();        //等待启动完成
 if(chkack()!=START)return I2C_ERR;    //检查是否启动成功
 write_tim(SLA_W);      //发送写地址
 write_tim(0x00);      //写数据首地址
 write_tim(0x00);      //写控制/状态寄存器1,暂停计时
 stop();
 return I2C_CRR;
 }

/**********************************
*   将时钟数据转换后在LCD上显示   *
**********************************/ 
void timer_lcd(void)
    {
 locate(1,4);        //写指令:第1行第4列地址

 lcd_da((timer[7]>>4)+0x30);
 lcd_da((timer[7]&0x0f)+0x30);
 lcd_da((timer[6]>>4)+0x30);   //显示年
 lcd_da((timer[6]&0x0f)+0x30);
 lcd_da('/');
 lcd_da((timer[5]>>4)+0x30);   //显示月
 lcd_da((timer[5]&0x0f)+0x30);
 lcd_da('/');
 lcd_da((timer[3]>>4)+0x30);   //显示日
 lcd_da((timer[3]&0x0f)+0x30);

 locate(2,2);       //写指令:第2行地址
   
    lcd_da((timer[2]>>4)+0x30);   //时
 lcd_da((timer[2]&0x0f)+0x30);
 lcd_da(':');
 lcd_da((timer[1]>>4)+0x30);   //分
 lcd_da((timer[1]&0x0f)+0x30);
 lcd_da(':');   
 lcd_da((timer[0]>>4)+0x30);   //秒
 lcd_da((timer[0]&0x0f)+0x30);

 lcd_da(20);       //时间与星期间留1空格
 lcd_da('W');      //星期的前导字
 lcd_da('e');
 lcd_da('e');
 lcd_da('k');
 lcd_da((timer[4]&0x0f)+0x30);  //星期数据
 }

//定时器1:每秒从8563中读取4次数据,更新显示
void timer1_init(void)        //定时器1初始化:250毫秒定时,预分频256
    {
 TCCR1B = 0x00;          //停止定时器
 TCNT1H = 0x8F;      //初值高字节
 TCNT1L = 0x81;      //定时初值低字节
 TCCR1A = 0x00;
 TCCR1B = 0x03;           //启动定时器
 }

#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)     //定时器1中断入口:250MS中断一次
    {
 TCNT1H = 0x8F;      //重装初值
 TCNT1L = 0x81;   
 read_timer();            //读出当前时钟
 timer_lcd();         //显示数据转换
 }

/**********************************
*          调整显示函数1    *
**********************************/
void set_xs1(uchar i)
    {
 lcd_da((timer>>4)+0x30);   //显示数据
 lcd_da((timer&0x0f)+0x30);
 }

/**********************************
*          调整显示函数2    *
**********************************/
void set_xs2(uchar data)
    {
 lcd_da((data>>4)+0x30);   //显示数据
 lcd_da((data&0x0f)+0x30);
 lcd(0x20);
 }

/**********************************
*           程序主函数        *
**********************************/
void main(void)
    {
 uchar set_flag=0;      //调整与正常工作标志
 uchar set_time;       //调整数据类型标志
 uchar set_bh=0;       //调整变化标志
 uchar a,a1;
 
 port_init();
 LED_ON;           //开LCD背光
 lcd_init();
 delay_ms(500);
 tonghe();
 delay_ms(2000);
 
 Twi_Init();
 delay_ms(100);
 CLI();         //关总中断
 timer1_init();     //定时器1初始化
 MCUCR = 0x00;
 GICR  = 0x00;
 TIMSK = 0x04;      //开放定时器0中断和比较中断
 SEI();        //开总中断
 
 cls();
 delay_ms(50);

 while(1)
     {
  a=KEY_RD;
  if(a!=0)
      {
   delay_ms(20);
   a1=KEY_RD;
   if(a1==a)
       {
    switch(a)
        {
     case 0x01:
      spk(10,1);
      if(set_flag==0)
          {
       TCCR1B=0x00;
       LED_ON;
       set_flag=1;
       cls();
       locate(1,4);     //显示“时间调整”
       xs_lcd("SET:");
       }
      else
       {
       TCCR1B=0x04;       //开启时钟
       set_flag=0;
       if(set_bh==1)
           {
        write_timer();    //写入新时间
        set_bh=0;
        }
       }
      break;
     case 0x02:
         if(set_flag==1)
          {
       spk(10,1);
       set_time++;     
       locate(2,2);      //显示待调整的数据
       switch(set_time)
              {
        case 1:
               xs_lcd("year:");
         set_xs1(6);   //显示年
         break;
        case 2:
            xs_lcd("muth:");
         set_xs1(5);   //显示月
         break;
        case 3:
            xs_lcd(" day:");
         set_xs1(3);   //显示日
         break;
        case 4:
            xs_lcd("hour:");
         set_xs1(2);   //显示时
         break;
        case 5:
            xs_lcd("mine:");
         set_xs1(1);   //显示分
         break;
        case 6:
            xs_lcd("week:");
         set_xs1(4);   //显示周
         break;
        default:set_time=0;break;
        }
       }
      break;
     case 0x04:
         if(set_flag==1)
          {
       spk(10,1);
       set_bh=1;
       locate(2,7);     //显示“时间调整”
       switch(set_time)
           {
        case 1:
            timer[6]-=0x01;
         if((timer[6]&0x0F)==0x0F)timer[6]&=0xF9;
         if(timer[6]>0x99)timer[6]=0x99;
         set_xs1(6);   //显示年
         break;
        case 2:
            timer[5]-=0x01;
         if((timer[5]&0x0F)==0x0F)timer[5]&=0xF9;
         if(timer[5]==0x00)timer[5]=0x12;
         set_xs1(5);   //显示月
         break;
        case 3:
            timer[3]-=0x01;
         if((timer[3]&0x0F)==0x0F)timer[3]&=0xF9;
         if(timer[3]==0x00)timer[3]=0x30;
         set_xs1(3);   //显示日
         break;
        case 4:
            timer[2]-=0x01;
         if((timer[2]&0x0F)==0x0F)timer[2]&=0xF9;
         if(timer[2]>0x24)timer[2]=0x23;
         set_xs1(2);   //显示时
         break;
        case 5:
            timer[1]-=0x01;
         if((timer[1]&0x0F)==0x0F)timer[1]&=0xf9;
         if(timer[1]>0x59)timer[1]=0x59;
         set_xs1(1);   //显示分
         break;
        case 6:
            timer[4]-=0x01;
         if(timer[4]>6)timer[4]=0x06;
         set_xs1(4);   //显示周
         break;
        default:set_time=0;break;
        }
       }
      else
       start_timer();
      break;
     case 0x08:
         if(set_flag==1)
          {
       spk(10,1);
       set_bh=1;
       locate(2,7);     //显示“时间调整”
       switch(set_time)
        {
        case 1:
         timer[6]+=0x01;
         if((timer[6]&0x0F)==0x0A)timer[6]=(timer[6]&0xF0)+0x10;
         if(timer[6]>0x99)timer[6]=0x00;
         set_xs1(6);   //显示年
         break;
        case 2:
         timer[5]+=0x01;
         if((timer[5]&0x0F)==0x0A)timer[5]=(timer[5]&0xF0)+0x10;
         if(timer[5]>=0x13)timer[5]=0x01;
         set_xs1(5);   //显示月
         break;
        case 3:
         timer[3]+=0x01;
         if((timer[3]&0x0F)==0x0A)timer[3]=(timer[3]&0xF0)+0x10;
         if(timer[3]>=0x31)timer[3]=0x01;
         set_xs1(3);   //显示日
         break;
        case 4:
         timer[2]+=0x01;
         if((timer[2]&0x0F)==0x0A)timer[2]=(timer[2]&0xF0)+0x10;
         if(timer[2]>=0x24)timer[2]=0x00;
         set_xs1(2);   //显示时
         break;
        case 5:
         timer[1]+=0x01;
         if((timer[1]&0x0F)==0x0A)timer[1]=(timer[1]&0xf0)+0x10;
         if(timer[1]>0x59)timer[1]=0x00;
         set_xs1(1);   //显示分
         break;
        case 6:
         timer[4]+=0x01;
         if(timer[4]>6)timer[4]=0x00;
         set_xs1(4);   //显示周
         break;
        default:set_time=0;break;
        }
       }
      else
       LED_OFF;      //关背光
      break;
     default:break;
     }
    }
   while(a!=0)
       {
    a=KEY_RD;
    delay_ms(10);
    }
   }
  }
 }

关键字:IIC  PCF8563  时钟程序  iccavr 引用地址:IIC的PCF8563实用时钟程序(iccavr)

上一篇:定时器1基础实验:让PB口上接的LED循环闪亮
下一篇:基于DS1302的实用时钟程序(iccavr)

推荐阅读最新更新时间:2024-03-16 15:18

MSP430通信资源之IIC通信
1. IIC描述 上图说明了在IIC总线拓扑中应该含有至少一个微控制器。该控制器通过IIC总线的SCL和SDA线与其他关联设备进行通信。基于传统的串行总线通信机制,IIC总线通信也是通过SDA与SCL配合实现,传输速率包含标注准(100kps)、快速(400kps)、高速(3.4Mbps)三大类。 2. IIC总线时序 启动时序:当SCL为高电平时,SDA下降沿,表示启动。 停止时序:当SCL为高电平时,SDA上升沿,表示停止。 ※由此可知,数据的传送应该在SCL为低电平时发生的,不能再高电平期间发生。进一步可知,SDA电平是在SCL为高电平时被读取。 数据帧的内容包括 起止信号、7位或者10位的从机地址,传送方向标志
[单片机]
MSP430通信资源之<font color='red'>IIC</font>通信
单片机时钟电路程序设计
引 言 X1226具有时钟和日历的功能,时钟依赖时、分、秒寄存器来跟踪,日历依赖日期、星期、月和年寄存器来跟踪,日历可正确通过2099年,具有自动闰年修正。 拥有强大的双报警功能,能够被设置到任何时钟/日历值上,精确度可到ls。可用软件设置1 Hz,4096 Hz或32768Hz中任意一个频率输出。 该器件提供一个备份电源输入脚VBACK1允许器件用电池或大容量电容备份供电。许多电池类型能够用做Xicor公司实时时钟器件X1226的备份电池,3.OV或3.6V的锂离子电池较为适合,使用期限为10年。另外一种用法可选择一个大容量的电容,备份时间可持续几天至两个星期,时间的长短依赖于电容容量的大小。用一个简单的硅或肖特基二
[单片机]
单片机<font color='red'>时钟</font>电路<font color='red'>程序</font>设计
关于我对IIC协议的一些理解
在谈IIC前,我们先将IIC的通信分为三步,准备、通信、结束阶段 1. 通信准备 IIC通信至少要两条通道,一条时钟线SCL,一条数据线SDA,而这两条线可以连接很多的设备。虽然IIC连接着很多的设备,但是在IIC没有与各个设备通信时,IIC均处于休眠状态,这时候就需要通过主机来唤醒设备了。 我们首先看时序图,怎么开始IIC的动作,及怎么结束II: 然后再看代码(somenop()为延时函数,延时时间主要是看单片的时钟周期,我所使用的单片机芯片是IAP15F2K6102) void somenop(void) { uchar t; _nop_(); _nop_(); t = 12; while(--t)
[单片机]
HMC5883 IIC测试程序
//*************************************** // HMC5883 IIC测试程序 // 使用单片机STC89C51 // 晶振:11.0592M // 显示:LCD1602 // 编译环境 Keil uVision2 // 参考宏晶网站24c04通信程序 // 时间:2011年3月1日 //**************************************** #include REG51.H #include math.h //Keil library #include stdio.h //Keil library #include INTRINS.H #def
[单片机]
STM32F4——IIC总线与SPI总线
一、简介: I2C总线为两线式的串行总线,用于连接微控制器和外围设备,其总线有数据线SDA和时钟线SCL,可以用来发送和接收数据。 二、信号与时序: I2C总线有三种类型的信号,分别为:开始信号,结束信号和应答信号。 开始信号:SCL为高电平时,SDA由高电平跳变为低电平。 结束信号;SCL为高电平时,SDA由低电平跳变为高电平。 应答信号:接收数据的外设在接收到数据后,向发送数据的控制器发送应答信号表示接收到数据,控制器向外设发送数据后等待控制器的应答信号,当接收到应答信号后,根据应答信号做出相应的判断。 其相关时序如下所示: 起始和停止时序: 应答时序: 三、相关代码:
[单片机]
并口模拟IIC的经验之谈
由于工作需要,用计算机来读写AT24C01A,用VC语言实现并口模拟I2C 。 (一)试验前的准备知识: 一、I2C总线:i2c总线是 Philips 公司首先推出的一种两线制串行传输总线。它由一根数据线(SDA)和一根 时钟线(SDL)组成。i2c总线的数据传输过程如图3所示,基本过程为: 1、主机发出开始信号。 2、主机接着送出1字节的从机地址信息,其中最低位为读写控制码(1为读、0为写),高7位为从机器件地址 代码。 3、从机发出认可信号。 4、主机开始发送信息,每发完一字节后,从机发出认可信号给主机。 5、主机发出停止信号。 I2C总线上各信号的具体说明: 开始信号:在时钟线(SCL)为高电平其间,数据线(SDA)由
[单片机]
关于STM32模拟IIC的理解
从书上看到STM32的硬件IIC远没有硬件SPI好用,书上给的例子也是模拟IIC的,因为之前只用过51的准双向口控制过简单的IIC器件,所以好好看了下。 IIC总线是由数据线SDA和时钟线SCL两条线构成的通信线路,既可以发送数据,也可以接收数据。在MCU和被控IC之间,IC和IC之间都可以进行双向传输。 这是一个IIC总线系统硬件结构图,SCL和SDA均需接上拉电阻。 在模拟IIC总线通信时,需写出几个关键部分的函数。 #define IIC_SCL PCout(12) //SCL #define IIC_SDA PCout(11) //SDA #define READ_SDA PCin(11) (1):总
[单片机]
关于STM32模拟<font color='red'>IIC</font>的理解
高准确度时钟程序算法
    摘要: 通过对引起实时时钟计时误差因数的分析,给出了一种提高实时时钟长期计时准确度的实用而有效的软件方法。该方法具有成本低、易实现、通用性强、彻底校正等优点。     关键词: 实时时钟 准确度 定时器 软件校正 电子计时器通常以石英晶振为时钟源。时钟源的频率通常为几十kHz乃至几十MHz,而学用时钟的最小计单位一般在0.01s~1s。高频的时钟源脉冲通过分频器后产生基本定时脉冲。电子计时器的计时部分就是对基本定时脉冲进行累加,产生秒、分、时等时间信息乃至日、月、年等日期信息。 1 引起计时误差的因数 一个常规电子计时器的计时准确度,取决于晶振标称频率(fs)与实际频率(fo)的频率偏差和晶振
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved