原创 PCF8563 我自己的面包板,支持原创!!

2010-12-23 14:34 2100 7 8 分类: MCU/ 嵌入式

我自己焊了个面包板,自己测试软件和硬件,确认是没有问题的。


66a44313-54a5-455d-86cc-5f040041894c.jpg


#include<STC12C5A.h>
//#include <reg52.h>   //调用头文件(单片机内部的寄存器定义)
#include<stdio.h>
#include<main.h>
#include <intrins.h>
sbit SDA=P2^0;    // pcf8563数据
sbit SCL=P2^1;    // pcf8563时钟
#define MIN    0x02 //秒寄存器
#define SEC    0x03 //分寄存器
#define HOUR   0x04 //时寄存器
#define DAY    0x05 //日寄存器
#define WEEK   0x06 //周寄存器
#define MONTH  0x07 //月寄存器
#define YEAR   0x08 //年寄存器
#define read_ADD  0xA3 //写器件地址
#define write_ADD 0xA2 //读器件地址
           
unsigned char g8563_Store[7]={0xff,0xff,0xff,0xff,0xff,0xff,0xff}; /*时间交换区,全局变量声明*/
unsigned char code c8563_Store[7]={0x59,0x09,0x15,0x16,0x04,0x12,0x10}; /*写入时间初值:2010年12月16日,星期四 15:09:59*/
unsigned int jishu= 0x00;


bit   bdata SystemError;                // 从机应答错误标志位


/*----------------------------
Initial UART
----------------------------*/
void InitUart()
{
    BRT = 0xFD;
 SCON |= 0xF3;// mode 3
 AUXR |= 0x11;
 PCON &= 0x7F;
 IP |= 0x10;
 IPH &= 0xef;
  //  TR1 = 1;       //T1 start running      
}


/*----------------------------
Send one byte data to PC
Input: dat (UART data)
Output:-
----------------------------*/
 void SendData(unsigned char dat)
{
    while (!TI);                    //Wait for the previous data is sent
    TI = 0;                         //Clear TI flag
    SBUF = dat;                     //Send current data
}
void delayNOP(void)
{
  unsigned char i=0;
  for(i=0;i<20;i++)
  {
   _nop_();
   }
}  
//--------------------------------------------------------------------------------------------------
// 函数名称: iic_start()
// 函数功能: 启动I2C总线子程序
//--------------------------------------------------------------------------------------------------
void iic_start(void)
{  
 SDA = 1;        
 SCL = 1;
 delayNOP();      // 延时5us
 SDA = 0;
 delayNOP();
 SCL = 0;
 delayNOP();
}
//--------------------------------------------------------------------------------------------------
// 函数名称: iic_stop()
// 函数功能: 停止I2C总线数据传送子程序
//--------------------------------------------------------------------------------------------------
void iic_stop(void)
{
 SDA = 0;       //时钟保持高,数据线从低到高一次跳变,I2C通信停止
  delayNOP();
 SCL = 0;
 delayNOP();
 SCL = 1;
 delayNOP();
 SDA = 1;
 delayNOP();
}
//--------------------------------------------------------------------------------------------------
// 函数名称: slave_ACK
// 函数功能: 从机发送应答位子程序
//--------------------------------------------------------------------------------------------------
void slave_ACK(void)
{
 SCL = 0;
 delayNOP();
 SDA = 0;
 delayNOP();   
 SCL = 1;
 delayNOP();  
 SCL = 0;
 delayNOP();
}
//--------------------------------------------------------------------------------------------------
// 函数名称: slave_NOACK
// 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束
//--------------------------------------------------------------------------------------------------
void slave_NOACK(void)
{
 SCL = 0;
 delayNOP();
 SDA = 1;
 delayNOP();  
 SCL = 1;
 delayNOP();
 SCL = 0;
 delayNOP();


}
//--------------------------------------------------------------------------------------------------
// 函数名称: check_ACK
// 函数功能: 主机应答位检查子程序,迫使数据传输过程结束
//--------------------------------------------------------------------------------------------------
void check_ACK(void)
{
 unsigned char tmp = 0x00;
 SCL = 0;
  delayNOP();
 SDA = 1;      // 将p1.0设置成输入,必须先向端口写1
  delayNOP();
 SCL = 1;
  delayNOP();
 F0 = 0;
 if(SDA == 1)    // 若SDA=1表明非应答,置位非应答标志F0
  F0 = 1;
 
 SCL = 0;
}


//--------------------------------------------------------------------------------------------------
// 函数名称: IICSendByte
// 入口参数: ch
// 函数功能: 发送一个字节
//--------------------------------------------------------------------------------------------------
void IICSendByte(unsigned char ch)
{
 unsigned char idata n=8;     // 向SDA上发送一位数据字节,共八位
 while(n--)
 {
   SCL = 0;
   delayNOP();
  if((ch&0x80) == 0x80)    // 若要发送的数据最高位为1则发送位1
  {
   SDA = 1;    // 传送位1
//   SCL = 1;
//   delayNOP();
//   SDA = 0;
//   SCL = 0;   
  }
  else
  { 
   SDA = 0;    // 否则传送位0
//   SCL = 1;
 //  delayNOP();
//   SCL = 0; 
  }
  ch = ch<<1;    // 数据左移一位
  delayNOP();
  SCL = 1;
   delayNOP();


 }
     SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: IICreceiveByte
// 返回接收的数据
// 函数功能: 接收一字节子程序
//--------------------------------------------------------------------------------------------------
unsigned char IICreceiveByte(void)
{
 unsigned char idata n=8;    // 从SDA线上读取一上数据字节,共八位
 unsigned char tdata=0;
 SDA = 1;
  delayNOP();
 while(n--)
 { 
  tdata = tdata<<1;    // 左移一位,或_crol_(temp,1)
  SCL = 0;
  delayNOP();
  SCL = 1;
  delayNOP();
  if(SDA == 1)   
   tdata = tdata|0x01;    // 若接收到的位为1,则数据的最后一位置1
  else
   tdata = tdata&0xfe;    // 否则数据的最后一位置0
 
 }
 SCL=0;
 delayNOP();
 return(tdata);
}
//--------------------------------------------------------------------------------------------------
// 用户调用子程序
// 函数名称: write_CFGbyte
// 入口参数: CFG_add寄存器地址,CFG_data要写入寄存器的数值
// 函数功能: 发送n位数据子程序
//--------------------------------------------------------------------------------------------------
void write_CFGbyte(unsigned char CFG_add,unsigned char CFG_data)
{         
 //unsigned char idata send_da,i=0;
 iic_start();                // 启动I2C
 IICSendByte(write_ADD);     // 发送器件写地址
 check_ACK();                // 检查应答位
    if(F0 == 1)
 {
  SystemError = 1;
  return;    // 若非应答表明器件错误或已坏,置错误标志位SystemError
 }
 IICSendByte(CFG_add);       // 发送寄存器地址
 check_ACK();                // 检查应答位
    if(F0 == 1)
 {
  SystemError = 1;
  return;    // 若非应答表明器件错误或已坏,置错误标志位SystemError
 }
    IICSendByte(CFG_data);       // 发送寄存器数据
 check_ACK();                // 检查应答位
    if(F0 == 1)
 {
  SystemError = 1;
  return;    // 若非应答表明器件错误或已坏,置错误标志位SystemError
 }
 iic_stop();         // 全部发完则停止 
}
//--------------------------------------------------------------------------------------------------
// 用户调用子程序
// 函数名称: receiveNbyte
// 入口参数: CFG_add寄存器地址地址
// 出口参数: receive_da
// 函数功能: 接收某个寄存器数据子程序
//--------------------------------------------------------------------------------------------------
unsigned char receive_CFGbyte(unsigned char idata CFG_add)
{
 unsigned char idata receive_da;
 iic_start();
    IICSendByte(write_ADD);  //器件写地址
 check_ACK();
 if(F0 == 1)
 {
  SystemError = 1;
  return(0);
 }
 IICSendByte(CFG_add);  //寄存器地址
 check_ACK();
 if(F0 == 1)
 {
  SystemError = 1;
  return(0);
 }
     iic_start();
    IICSendByte(read_ADD);  //器件读地址
  if(F0 == 1)
 {
  SystemError = 1;
  return(0);
 }
    receive_da=IICreceiveByte();
    slave_NOACK();       // 收到最后一个字节后发送一个非应答位
 iic_stop();
 return(receive_da);
}
//--------------------------------------------------------------------------------------------------
// 用户调用函数
// 函数名称: receive_CFGNbyte
// 入口参数: CFG_add寄存器地址地址,n连续读数位,* buff存储区地址
// 函数功能: 接收n个寄存器数据子程序
//--------------------------------------------------------------------------------------------------
void receive_CFGNbyte(unsigned char CFG_add, unsigned char n,unsigned char * buff)
{
 unsigned char  receive_da,i=0;
 iic_start();
    IICSendByte(write_ADD);  //器件写地址
 check_ACK();
 if(F0 == 1)
 {
  SystemError = 1;
  return;
 }
 IICSendByte(CFG_add);  //寄存器地址
 check_ACK();
 if(F0 == 1)
 {
  SystemError = 1;
  return;
 }
   iic_start();
    IICSendByte(read_ADD);  //器件读地址
  check_ACK();


  if(F0 == 1)
 {
  SystemError = 1;
  return;
 }
 while(n--)
 {
  receive_da=IICreceiveByte();
  buff[i++]=receive_da;
  slave_ACK();    // 收到一个字节后发送一个应答位
 }
 slave_NOACK();    // 收到最后一个字节后发送一个非应答位
 iic_stop();
}
//--------------------------------------------------------------------------------------------------
// 用户调用函数
// 函数名称: P8563_Readtime
// 函数功能: 读出时间信息
//--------------------------------------------------------------------------------------------------
/*void P8563_Readtime()
{   unsigned char time[7];
    receive_CFGNbyte(MIN,0x07,time);
    g8563_Store[0]=time[0]&0x7f; //秒
    g8563_Store[1]=time[1]&0x7f; //分
    g8563_Store[2]=time[2]&0x3f; //小时
    g8563_Store[3]=time[4]&0x07; //星期
} */


void P8563_Readtime()
{   unsigned char time[7];
    receive_CFGNbyte(MIN,0x01,time);
    receive_CFGNbyte(SEC,0x01,&time[1]);
    receive_CFGNbyte(HOUR,0x01,&time[2]);
 receive_CFGNbyte(DAY,0x01,&time[3]);  //日
 receive_CFGNbyte(WEEK,0x01,&time[4]); //星
 receive_CFGNbyte(MONTH,0x01,&time[5]);  //月
 receive_CFGNbyte(YEAR,0x01,&time[6]); //年
 
 
  
    g8563_Store[0]=time[0]&0x7f; /*秒*/
    g8563_Store[1]=time[1]&0x7f; /*分*/
    g8563_Store[2]=time[2]&0x3f; /*小时*/
 g8563_Store[3]=time[3]&0x3f; /*日*/
    g8563_Store[4]=time[4]&0x07; /*星期*/
 g8563_Store[5]=time[5]&0x13; /*月*/
    g8563_Store[6]=time[6]&0xff; /*年*/
}
//--------------------------------------------------------------------------------------------------
// 用户调用函数
// 函数名称: P8563_settime
// 函数功能: 写时间修改值
//--------------------------------------------------------------------------------------------------
void P8563_settime()
{
     unsigned char i;
     for(i=2;i<=8;i++) { write_CFGbyte(i,g8563_Store[i-2]); }
    // write_CFGbyte(6,g8563_Store[3]);
}
//--------------------------------------------------------------------------------------------------
// 用户调用函数
// 函数名称: P8563_init
// 函数功能: 初始设置
//--------------------------------------------------------------------------------------------------
void P8563_init()
{
    unsigned char i;
    if((receive_CFGbyte(0x0a))!=0x8) /*检查是否第一次启动,是则初始化时间*/
    {
        for(i=0;i<=6;i++)
        g8563_Store=c8563_Store; /*初始化时间*/
        P8563_settime();
        write_CFGbyte(0x0,0x00);
        write_CFGbyte(0xa,0x8);  /*8:00报警*/
        write_CFGbyte(0x01,0x12); /*报警有效*/
        write_CFGbyte(0xd,0xf0);
    }
}


void DelayLong(unsigned int a )
{
  while(a--)
  {
     _nop_();
  _nop_();
  _nop_();
  _nop_();
  }
}
main()
{
  InitUart();
  DelayLong(65535);
  SendData(0x55);


  P8563_init();
   while(1)
   { 
   jishu++;
   if(jishu>= 60000)
   {
      jishu=0;
   P8563_Readtime();
   SendData(g8563_Store[6]);
      SendData(g8563_Store[5]);
      SendData(g8563_Store[4]);
   SendData(g8563_Store[3]); 
      SendData(g8563_Store[2]);
      SendData(g8563_Store[1]);
      SendData(g8563_Store[0]); 
   }


2ea37949-20eb-4de9-b806-087c000c5eb8.jpg


 

文章评论1条评论)

登录后参与讨论

用户547841 2010-12-20 15:48

这是单片机返还给串口的数据 10 12 04 16 15 00 03 10 12 04 16 15 00 03 10 12 04 16 15 00 03 10 12 04 16 15 00 04 10 12 04 16 15 00 04 10 12 04 16 15 00 04 10 12 04 16 15 00 04 10 12 04 16 15 00 04 10 12 04 16 15 00 05 10 12 04 16 15 00 05 10 12 04 16 15 00 05 10 12 04 16 15 00 05 10 12 04 16 15 00 06 10 12 04 16 15 00 06 10 12 04 16 15 00 06 10 12 04 16 15 00 06 10 12 04 16 15 00 07 10 12 04 16 15 00 07 10 12 04 16 15 00 07 10 12 04 16 15 00 07 10 12 04 16 15 00 07 10 12 04 16 15 00 08 10 12 04 16 15 00 08 10 12 04 16 15 00 08 10 12 04 16 15 00 08 10 12 04 16 15 00 09 10 12 04 16 15 00 09 10 12 04 16 15 00 09 10 12 04 16 15 00 09 10 12 04 16 15 00 09 10 12 04 16 15 00 10 10 12 04 16 15 00 10 10 12 04 16 15 00 10 10 12 04 16 15 00 10 10 12 04 16 15 00 11 10 12 04 16 15 00 11 10 12 04 16 15 00 11 10 12 04 16 15 00 11 10 12 04 16 15 00 12 10 12 04 16 15 00 12 10 12 04 16 15 00 12 10 12 04 16 15 00 12 10 12 04 16 15 00 12 10 12 04 16 15 00 13 10 12 04 16 15 00 13 10 12 04 16 15 00 13 10 12 04 16 15 00 13 10 12 04 16 15 00 14 10 12 04 16 15 00 14 10 12 04 16 15 00 14 10 12 04 16 15 00 14 10 12 04 16 15 00 14 10 12 04 16 15 00 15 10 12 04 16 15 00 15 10 12 04 16 15 00 15 10 12 04 16 15 11 08 10 12 04 16 15 11 08 10 12 04 16 15 11 09 10 12 04 16 15 11 09 10 12 04 16 15 11 09
相关推荐阅读
用户547841 2011-01-05 21:36
DC power supply
...
用户547841 2010-12-23 14:31
工程硕士专业课,中科院
 ...
用户547841 2010-10-13 07:52
PCF8563驱动程序演示实验
PCF8563驱动程序演示实验一、实验目的PCF8563是一款性价比极高的时钟芯片。它已被广泛用于电表、水表、气表、电话、传真机、便携式仪器以及电池供电的仪器仪表等产品领域。本实验示例展示了如何在Sm...
用户547841 2010-10-13 07:26
单片机
...
用户547841 2010-10-06 21:32
data xdata code
keil c51 v8.08汉字支持能力太差了。显示的注释就跟乱码似的,根本没法看。换掉!Keil C51 V8.02注释的汉字倒是没有错误了,但一注解汉字,过一会立刻找不到鼠标的定位点,然后就程序出...
我要评论
1
7
关闭 站长推荐上一条 /2 下一条