⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcf8563.c

📁 PIC18F6720写DAC7612U,TA1604_LCD显示,I2C读写PCF8563,PIC单片机之间模拟I2C通讯,该软件已调试通过,已经在产品上使用,有中文说明.
💻 C
📖 第 1 页 / 共 2 页
字号:
#define PCF8563_SCLK PIN_C3
#define PCF8563_IO   PIN_C4
//#use i2c(master, sda=PCF8563_IO, scl=PCF8563_SCLK)
     // master设置成主机方式
     //除非指定了FORCE_HW,否则会产生模拟I2C的软件函数.
     //使能I2C_START,  I2C_STOP直到下一个#USE  I2C的出现为止.
     //使能I2C_READ,  I2C_WRITE直到下一个#USE  I2C的出现为止.
     //使能I2C_POLL直到下一个#USE  I2C的出现为止.
     //指定sda脚为EEPROM_SDA, 指定scl脚为EEPROM_SCL

//#define trisc 0xF94;   //定义端口C的方向寄存器地址为0xF94
//#byte trisc=0xF94;   //定义端口C的方向寄存器地址为0xF94
//#bit  PCF8563_IO_DIR=trisc.4

//主机发送"启动条件"函数;
 void I2CStart(void)
 {
 //EA=0;                   //屏蔽所有中断
 output_high(PCF8563_IO);   
 output_high(PCF8563_SCLK);//将PCF8563_IO脚和PCF8563_SCLK置为高电平,为发送启动条件做准备
 delay_us(4);
 output_low(PCF8563_IO);   //在PCF8563_SCLK为高电平期间,PCF8563_IO脚出现下降沿,表示"起动I2C"
 delay_us(4);
 output_low(PCF8563_SCLK); //PCF8563_SCLK脚置低电平,为下次移位做准备;
 }

//主机发送"停止条件"函数;
 void I2CStop(void)
 {
 output_low(PCF8563_SCLK);
 output_low(PCF8563_IO);   //将PCF8563_IO脚和PCF8563_SCLK置为低电平,为发送"停止条件"做准备
 delay_us(4);
 output_high(PCF8563_SCLK);
 delay_us(4);
 output_high(PCF8563_IO);  //在PCF8563_SCLK为高电平期间,PCF8563_IO脚出现上降沿,表示"停止I2C"
 //EA=1;                   //开所有中断允许位
 }


//从I2C输出一个字节
void write_I2C_byte(BYTE cmd) {
   BYTE i;
   for(i=0;i<=7;++i) {
      output_bit(PCF8563_IO, shift_left(&cmd,1,0) ); //将cmd所指的单元左移一位,右端补0,移出的位经PCF8563_IO脚输出
                                                     //先送出cmd所指单元的最高位
      output_high(PCF8563_SCLK);                     //PCF8563_SCLK脚上升沿到来时,PCF8563收到一位值;
      output_low(PCF8563_SCLK);                      //PCF8563_SCLK脚置低电平,为下次移位做准备;
   }
}

//从I2C读入一个字节
BYTE read_I2C_byte( ) {
   BYTE i,data;
   for(i=0;i<=7;++i) {
      shift_left(&data,1,input(PCF8563_IO));  //CPU从PCF8563读入1位,先读入的是发送数据的最高位;
      output_high(PCF8563_SCLK);              //PCF8563_SCLK脚上升沿到来时,告诉PCF8563已经移出一位值;
      delay_us(2);
      output_low(PCF8563_SCLK);               //PCF8563_SCLK脚置低电平,为PCF8563下次移位做准备
      delay_us(2);
   }
   return(data);
}


 /**-----------------------------------------------------------------------------
 函数说明:I2C专用,等待从器件接收方的应答
 ---------------------------------------------------------------------------------*/
 int1 WaitAck(void)
 {
 int errtime=255;//因故障接收方无ACK,超时值为255.
 //output_float(PCF8563_IO);  //将PCF8563_IO引脚设为输入,开集电极连接
 output_high(PCF8563_IO);
 delay_us(2);
 output_high(PCF8563_SCLK); //PCF8563_SCLK脚上升沿到来时,PCF8563发送ACK信号;
 delay_us(2);
 //bit_set(*0xF94,4); //端口C的方向寄存器地址为0xF94
                    //将端口C的方向寄存器的第4位,置1,即将PIN_C4设置为输入方式
                       
 while(input(PCF8563_IO)){
             errtime--; 
             if (!errtime) 
              {I2CStop();
               //bit_clear(*0xF94,4); //端口C的方向寄存器地址为0xF94,PCF8563_IO脚设置为输出
               //SystemError=0x11;
               return FALSE;
              }
            }
 bit_clear(*0xF94,4); //端口C的方向寄存器地址为0xF94
                      //将端口C的方向寄存器的第4位,置0,即将PIN_C4设置为输出方式
 output_low(PCF8563_SCLK);
 return TRUE;
 }

 /**-------------------------------------------------------------------------------
 函数说明:I2C专用,主器件为接收方,从器件为发送方时,应答信号。
 ---------------------------------------------------------------------------------*/
 void SendAck(void)
 {
  output_low(PCF8563_IO);    //将PCF8563_IO脚设置为低电平,该位值是即发出的"应答信号";
  delay_us(2);
  output_high(PCF8563_SCLK); //PCF8563_SCLK脚上升沿到来时,PCF8563收到一位值;
  delay_us(2);
  output_low(PCF8563_SCLK);  //PCF8563_SCLK脚置低电平,一个移位时钟结束;
 }

 /**-------------------------------------------------------------------------------
 函数说明:I2C专用,主器件为接收方,从器件为发送方时,非应答信号。
 }**-------------------------------------------------------------------------------*/
 void SendNotAck(void)
 {
  output_high(PCF8563_IO);  //将PCF8563_IO脚设置为高电平,该位值是即发出的"非应答信号";
  delay_us(2);
  output_high(PCF8563_SCLK);//PCF8563_SCLK脚上升沿到来时,PCF8563收到一位值;
  delay_us(2);
  output_low(PCF8563_SCLK); //PCF8563_SCLK脚置低电平,一个移位时钟结束;
 }

 //开始PCF8563T驱动程序
 /**-------------------------------------------------------------------------------
 函数说明:读取时钟芯片PCF8563的时间;
           设置要读的第一个时间类型firsttype,并设置读取的字节数count,则会一次把时间读取到buff中.
           顺序是:0x02:秒/0x03:分/0x04:小时/0x05:日/0x06:星期/0x07:月(世纪)/0x08:年
 ---------------------------------------------------------------------------------*/
 void GetPCF8563(int firsttype,int count,int *buff)
 {
   int i;
  I2CStart();            //发开始条件
  write_I2C_byte(0xA2);  //发送"写器件地址",PCF8563的"写器件地址"为0xA2
  WaitAck();             // 等待从器件接收方的应答 
  write_I2C_byte(firsttype);  //发送器件的子地址:0x02:秒/0x03:分/0x04:小时/0x05:日/0x06:星期/0x07:月(世纪)/0x08:年;
  WaitAck();             //等待PCF8563_IO脚被PCF8563拉低;

  I2CStart();           //发重新开始条件
  write_I2C_byte(0xA3); //发送"读器件地址"
  WaitAck();            //等待PCF8563_IO脚被PCF8563拉低;
  for (i=0;i<count;i++)
   {
    buff[i]=read_I2C_byte();
    if (i!=count-1) SendAck();//除最后一个字节外,其他都要从MASTER发应答。
   }
  SendNotAck();          //CPU发送不应答信号
  I2CStop();
 }

 /**-----------------------------------------------------------------------------
 函数说明:调整时钟;
        1, timetype是要改的时间类型: 0x02 是PCF8563的秒(second)计数器地址;
                                     0x03 是PCF8563的分钟(mintue)计数器地址;
                                     0x04 是PCF8563的小时(hour)计数器地址;
                                     0x05 是PCF8563的日(day)计数器地址;
                                     0x06 是PCF8563的星期(weekdays)计数器地址;
                                     0x07 是PCF8563的月(世纪)计数器地址;
                                     0x08 是PCF8563的年year计数器地址;
           value是新设置的时间值(BCD格式);
        
        2, timetype是要改的时间类型: 0x09 分钟报警寄存器地址;
                                     0x0A 小时报警寄存器地址;
                                     0x0B 日报警寄存器地址;
                                     0x0C 星期报警寄存器地址;
           value是新设置的时间值(BCD格式);
        
        3, timetype是要改的时间类型: 0x00 是控控制/状态寄存器1:TEST1 0 STOP 0 0 TESTC 0 0;
                                          当TEST1=0时,则设置为普通模式;
                                          当STOP=0时,芯片时钟运行;当STOP=1时,芯片时钟停止运行;
                                          当TESTC=0时,电源复位功能失效;当TESTC=1时,电源复位功能有效;
                                     0x01 是控制/状态寄存器2: 0 0 0 TI/TP AF TF AIE TIE
                                          当TIE=0时,定时器中断不允许;当TIE=1时,定时器中断允许;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -