原创 MCF51AC128 PCF8563 RTC驱动

2010-8-1 17:40 3254 11 13 分类: MCU/ 嵌入式

这是我们新近开发的一款freescale coldfire v1开发板的演示例程的一部分。这个开发板采用的是mcf51ac128 微控制器,LQFP80封装,50MHZ主频,集成i2c,spi,uart,mscan等。是比较适合一般的工业控制或一些家电控制,或者行业类的应用的MCU。


这个是利用其硬件i2c模块操作pcf8563的简单驱动。转载请注明出处:http://blog.ednchina.com/bluehacker


-------------------------------------------------------------------------------------------------------------


/*File: MCF51AC128_IIC_driver.c


* MCF51AC128 I2C driver


* Nicrosystem 2010-7-19


*author: bluedream


*/


#include "MCF51AC128_IIC_driver.h"
#include "delay.h"
/*
**功能:iic模块初始化
*/
void iic_init()
{
  /*iic波特率=25Mhz/(4*104)=60kb/s*/
  IICF=0x96;
 
  /*iic模块中断禁止*/
  IICC1_IICIE=0;
 
  /*不发送应答信号*/
  IICC1_TXAK=1;
 
  /*选择从设备模块*/
  IICC1_MST=0;
 
   /*iic模块使能*/
  IICC1_IICEN=1;
}
/*
**产生START信号
*/
void iic_start()
{
  /*判断总线是否处于忙的状态*/
  while(IICS_BUSY) ;
 
  /*选择发送模式*/
  IICC1_TX=1;
  IICC1_MST=1;
}
/*
**功能:产生STOP信号
*/
void iic_stop()
{
  IICC1_MST=0;
}
/*
**功能:产生RESTART信号
*/
void iic_restart()
{
  IICC1_RSTA=1; 
}
/*
**功能:iic发送一个字节数据
**参数:data:要写入的数据
**return:0:发送成功
**       1:发送失败
*/
unsigned char iic_send_byte(unsigned char data)
{
  IICD=data;
  while(!IICS_IICIF) ;
  IICS_IICIF=1;
  if(IICS_RXAK==0)
     return 0;//success     
  else
     return 1;//fail
}
/*
**功能:iic接收一个字节数据
**参数:ack:0:接收一字节后发送应答信号
**          1:接收一字节后不发送应答信号
**return:接收到的数据
*/
unsigned char iic_recv_byte(unsigned char ack)
{
   unsigned char recvdata;
   if(ack>0)
    {
      IICC1_TXAK=1;
    }
   else
    {
      IICC1_TXAK=0;
    }
   /*选择接收模式*/
   IICC1_TX=0;
   recvdata=IICD;
   while(!IICS_IICIF) ;
   IICS_IICIF=1;
   return recvdata;
}


------------------------------------------------------------------------------------------------


/* File:pcf8563.c


* Nicrosystem 2010-7-19


*author: bluedream


*/


#include "MCF51AC128_IIC_driver.h"
#include "pcf8563.h"


int alarm_flag=0;
extern alarm_flag;
/*
**功能:向pcf8563写数据
**参数:addr: pcf8563任意指定的寄存器地址
**      data:要写入的数据
**返回值:1:写入失败
**        0:写入成功
*/
unsigned char pcf8563_write_byte(unsigned char addr,unsigned char data)
{
 iic_start();
 if(iic_send_byte(WRPCF8563))
 {
     
  iic_stop();
  return 1;
 }
 if(iic_send_byte(addr))
 {
  
  iic_stop();
  return 1;
 } 
 if(iic_send_byte(data))
 {
    
  iic_stop();
  return 1;
 }
 iic_stop();
 return 0;//success
}


/*
**功能:读取pcf8563的数据
**参数:addr: pcf8563任意指定的寄存器地址
**      *buf:存放读出的数据
**返回值:1:读取失败
**        0:读取成功
*/
unsigned char pcf8563_read_byte(unsigned char addr, unsigned char *buf)
{
 unsigned char i=0;
 iic_start();
 if(iic_send_byte(WRPCF8563))
 {
  iic_stop();
  return 1;
 }
 if(iic_send_byte(addr))
 {
  iic_stop();
  return 1;
 }
 
 iic_restart();
 
 if(iic_send_byte(RDPCF8563))
 {
  iic_stop();
  return 1;
 }


     iic_recv_byte(0);
 *buf=iic_recv_byte(1) ;
 iic_stop();
 return 0;//success
}


/*
** 功能:pcf8563初始化
*/
void pcf8563_init()
{
 unsigned char i;
 
 pcf8563_write_byte(0x00,0);
 pcf8563_write_byte(0x01,0); 
     pcf8563_read_byte(0x07,&i);
 i&=0x7f; 
 pcf8563_write_byte(0x07,i);
 pcf8563_write_byte(0x0d,0x03);
 pcf8563_write_byte(0x0e,0x03);
    
}


/*
**功能:向pcf8563写具体的报警时间
**参数:*time :要写入的报警时间
**            time[0]---week
**            time[1]---date
**            time[2]---hour
**            time[3]---minute
** return:1:写入失败
**        0:写入成功
*/
unsigned char pcf8563_set_alarmtime(unsigned char *time)
{
     unsigned char i,ret=0;
 
 //将十进制转换成BCD码
     for(i=0;i<4;i++)
 {
  time=(unsigned char)(((time/10)<<4)+((time%10)&0x0f));
 }
 
 for(i=0;i<4;i++)
 {
     ret=pcf8563_write_byte((unsigned char)(0x0C-i),time);
  if(ret)
   return ret;
 }
     return 0;
}


void pcf8563_alarm_deal()
{
     unsigned char flag;
     pcf8563_read_byte(0x01,&flag);
     if((flag&0x08)==0x08)
     {
      pcf8563_write_byte(0x01,0);
      alarm_flag=1;
     }
     else
     {
      alarm_flag=0;
     }
}
/*
**功能:读取 pcf8563里的时间
**参数: *time:读取到的当前时间
**            time[0]---year,
**            time[1]---month
**            time[2]---date
**            time[3]---week
**            time[4]---hour
**            time[5]---minute
**            time[6]---second
**return:1:读取失败
**       0:读取成功
*/


unsigned char pcf8563_read_time(unsigned char *time)
{
 unsigned char i,ret=0;
 for(i=0;i<7;i++)
 {
    ret=pcf8563_read_byte((unsigned char)(0x08-i),&time) ;
  if(ret)
   return ret;
 }
 time[1]&=0x1f;
 time[2]&=0x07;
 time[3]&=0x3f;
 time[4]&=0x3f;
 time[5]&=0x7f;
 time[6]&=0x7f;
 
 /*将BCD码转换成十进制*/
 for(i=0;i<7;i++)
 {
  time=(unsigned char)(((time>>4)&0x0f)*10+(time&0x0f)) ;
 }
 
 i=time[2];
 time[2]=time[3];
 time[3]=i;
     return 0;
}
/*
**功能:向 pcf8563写时间
**参数:*time:要写入的具体时间
**            time[0]---year,
**            time[1]---month
**            time[2]---week
**            time[3]---date
**            time[4]---hour
**            time[5]---minute
**            time[6]---second
**return:1:写入失败
**       0:写入成功
*/
unsigned char pcf8563_write_time(unsigned char *time)
{
 unsigned char i,ret=0;
 
 /*将十进制转换成BCD码*/
     for(i=0;i<7;i++)
 {
  time=(unsigned char)(((time/10)<<4)+((time%10)&0x0f)) ;
 }
 
 for(i=0;i<7;i++)
 {
     ret=pcf8563_write_byte((unsigned char)(0x08-i),time) ;
  if(ret)
   return ret;
 }
     return 0;
     
}



 

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户1361860 2010-8-9 18:31

非常感谢你的指教

shaoziyang 2010-8-6 09:31

对于iic_recv_byte函数,可以稍微修改一下,这样就不需要每次都需要多调用iic_recv_byte。因为这个函数读取的实际上是上次的IICD,而不是本次的。 unsigned char iic_recv_byte(unsigned char ack) { unsigned char recvdata; if(ack>0) { IICC1_TXAK=1; } else { IICC1_TXAK=0; } /*选择接收模式*/ IICC1_TX=0; recvdata=IICD; while(!IICS_IICIF) ; IICS_IICIF=1; /*改为发送后读取IICD就不会启动接收*/ IICC1_TX=1; return IICD; }
相关推荐阅读
用户1361860 2012-06-28 23:44
Nicrosystem Freescale Kinetis教程---SDHC
这是研究生翻译的SDHC的中文文档,里面很多句子不通,但我现在没时间去修改了。先放出来,应该还是会有一点作用  ...
用户1361860 2012-06-26 12:39
Nicrosystem Freescale Kinetis教程--低功耗定时器
Freescale Kinetis内部集成了一个独特的低功耗定时器,它可以在系统处于低功耗模式下,仍然以极低功耗运行,可以用于在适当时候唤醒系统进入正常工作模式  ...
用户1361860 2012-06-24 22:11
Nicrosystem Freescale Kinetis教程----RTC实时时钟
Nicrosystem的飞思卡尔kinetis教程之片上RTC  ...
用户1361860 2012-06-22 10:21
TI C2000微控制器指南
这是官方的C2000的介绍,C2000做电机控制那是业界最好的。  ...
用户1361860 2012-06-20 23:52
Nicrosystem Freescale Kinetis教程--PIT定时器教程
这是PIT定时器的教程,PIT是 Kinetis支持的另一种定时器,相对于上一讲的flextimer要简单。 今晚赶到北京,到宾馆发一篇博客  ...
用户1361860 2012-06-19 13:15
Nicrosystem Freescale Kinetis教程--Flextimer教程
Kinetis的Flextimer定时器教程 kinetis集成了众多功能各异的定时器,flextimer是其中最为复杂的一个  ...
EE直播间
更多
我要评论
2
11
关闭 站长推荐上一条 /3 下一条