搜索
bottom↓
回复: 10

用MEGA88的I/O口模拟I2C读写PCF8563的程序,已经调试成功.送给需要的朋友!

[复制链接]

出0入0汤圆

发表于 2007-1-12 11:26:14 | 显示全部楼层 |阅读模式
//该程序LCD用的PORTB0,1,2,3口;

//模拟I2C口是SDA为PORTD6.SCL为PORTD5

#include<avr/io.h>

#include<avr/signal.h>

#include<avr/interrupt.h>

#define uint unsigned int

#define uchar unsigned char

#define PCF8536_ADDR 0XA2

#define TW_WRITE  0

#define TW_READ  1

uchar g_aTimeBuf[16]={0,0x02,0x50,0x44,0x10,0x12,0x05,0x01,0x07,0x45,0x80,0x80,0x80,0x00,0x00,0x00};

//写入2007年01月12日,10:44:50,分钟报警功能有效(45)其他功能无效

uchar g_aTimeBin[7];//时钟/日历bcd格式缓冲区



/***********************端口初始化************************/

//*******PC4=SDA;*******PC5=SCL

//用PC4、5来模拟

void port_init(void)

{

DDRC=_BV(PC4)|_BV(PC5);

PORTC=0X00;

PORTC|=_BV(PC4)|_BV(PC5);

DDRD=0x00;//中断入口置为输入

PORTD=0xff;//使能内部上拉电阻

}

/***************************中断初始化***********************/

//如果要用到PCF8563的中断功能,只需要把PCF8563的INT/引脚接到单片机的外部中断0或1

//在这里我接的是中断1口

void INT_init(void)

{

EICRA=0x00;//外部中断1低电平触发

EIMSK=0x02;//使能外部中断1

}



/*************PCF8536 操作********************开始**************/

//*******PC4=SDA;*******PC5=SCL  

//DDRC    _SFR_IO8 (0x07)

//PORTC   _SFR_IO8 (0x08)

void DELAY_us(void)//延时5US

  {

  asm volatile("nop"::);

  asm volatile("nop"::);

  asm volatile("nop"::);

  asm volatile("nop"::);

  asm volatile("nop"::);

  }

void i2c_start(void)//起始信号

  {

   asm volatile ("cbi 0x08,5"::);

     asm volatile("nop"::);//延时1US

   asm volatile ("sbi 0x08,5"::);

    asm volatile("nop"::);//延时1US

   asm volatile ("sbi 0x08,4"::);

     DELAY_us();

   asm volatile ("cbi 0x08,4"::);

    DELAY_us();

   asm volatile ("cbi 0x08,5"::);

    asm volatile("nop"::);//延时1US

  }//起始信号后SCL,SDA都为低电平



void i2c_stop(void)//停止信号

  {

   asm volatile ("cbi 0x08,5"::);

    asm volatile("nop"::);//延时1US

   asm volatile ("cbi 0x08,4"::);

   DELAY_us();

  asm volatile ("sbi 0x08,5"::);

   DELAY_us();

  asm volatile ("sbi 0x08,4"::);

  }//停止信号后SCL,SDA都为高电平

void i2c_ack(uchar ack_data) //读PCF8563时用的

{

  //asm volatile ("cbi 0x08,5"::);

    //asm volatile("nop"::);//延时1US

  if(ack_data==0)

    asm volatile ("cbi 0x08,4"::);//应答拉低SDA

  else

   asm volatile ("sbi 0x08,4"::);//不应答拉高SDA

    DELAY_us();

  asm volatile ("sbi 0x08,5"::);

   DELAY_us();

  asm volatile ("cbi 0x08,5"::);

    asm volatile("nop"::);//延时1US

}

/****************************************************************/

uchar i2c_writebyte(uchar c)

{//将字节发送出去,可以是地址,也可以是数据,发完后等待应答并返回

  uchar ack_flag;

  for(uchar i=0;i<8;i++)

   {

      if((c<<i)&0x80)

       asm volatile ("sbi 0x08,4"::);

      else

       asm volatile ("cbi 0x08,4"::);

       DELAY_us();  

      asm volatile ("sbi 0x08,5"::); //置时钟线为高,通知被控器开始接收数据位

       DELAY_us();//保证时钟高电平周期大于4μs

      asm volatile ("cbi 0x08,5"::);

   }

   DELAY_us();

  asm volatile ("cbi 0x08,4"::);  

  asm volatile ("cbi 0x07,4"::);//SDA引脚位变为输入

   asm volatile("nop"::);

  asm volatile ("sbi 0x08,5"::);

    DELAY_us();

    DELAY_us();

  if(PINC&0x10)//判断是否接收到应答信号

   ack_flag=0;

  else

   ack_flag=1;//有应答信号

  asm volatile ("sbi 0x07,4"::);//SDA引脚位变为输出

   asm volatile("nop"::);

  asm volatile ("cbi 0x08,5"::);

  asm volatile("nop"::);

  return(ack_flag);

}



uchar i2c_readbyte(void) //读一个字节

{

  uchar get_data=0;

asm volatile ("cbi 0x07,4"::);//SDA引脚位变为输入

  for(uchar i=0;i<8;i++)

   {

    asm volatile("nop"::);

    asm volatile ("cbi 0x08,5"::);//置时钟线为低,准备接收数据位

     DELAY_us();//时钟低电平周期5μs;

   asm volatile ("sbi 0x08,5"::); //置时钟线为高使数据线上数据有效

   get_data<<=1;

   if(PINC&0x10)//如果SDA数据线为高电平  

    get_data++;

   asm volatile("nop"::);

   asm volatile("nop"::);

   }

  asm volatile ("cbi 0x08,5"::);

   asm volatile ("sbi 0x07,4"::);//SDA引脚位变为输出

   asm volatile("nop"::);

  return(get_data);

}

//当对PCF8563连续读的时候最后一个字节不需要主接受器应答

/********************************************************************/

uchar write_8563(uchar addr,uchar *buf,uchar len)//对PCF8536 连续的写操作

{

uchar i;

i2c_start();//起始信号

i2c_writebyte(PCF8536_ADDR|TW_WRITE);

i2c_writebyte(addr);//write address

for(i=0;i<len;i++)

i2c_writebyte(buf);

i2c_stop();

}



uchar read_8563(uchar addr,uchar *buf,uchar len)//对PCF8536 连续的读操作

{

uchar i;

i2c_start();

i2c_writebyte(PCF8536_ADDR|TW_WRITE);

i2c_writebyte(addr);//write word address

i2c_start();

i2c_writebyte(PCF8536_ADDR|TW_READ);

for(i=0;i<len-1;i++)

{

buf=i2c_readbyte();

i2c_ack(0);

}

buf[len-1]=i2c_readbyte();

i2c_ack(1);

i2c_stop();

}

void PCF8563_CAF(void)//在中断函数里清除8563AF标志位

{

uchar TimeBuf[2];

read_8563(0x01, TimeBuf,1);

  TimeBuf[0]&=0x17;

write_8563(0x01,TimeBuf,1);//清除AF

}

/*-------------------------------------------------------------------------   

功能:将读出的时间数据的无关位屏蔽掉

说明:PCF8563时钟寄存器的有些无关位的状态是不定的,所以应该将无效位屏蔽掉

---------------------------------------------------------------------------*/

void Data_ajust(void) //时间无效位屏蔽

{     

   g_aTimeBin[0]=g_aTimeBin[0]&0x7f;//秒时间无效位的屏蔽  

   g_aTimeBin[1]=g_aTimeBin[1]&0x7f;//分钟时间无效位的屏蔽

   g_aTimeBin[2]=g_aTimeBin[2]&0x3f;//小时时间无效位的屏蔽  

   g_aTimeBin[3]=g_aTimeBin[3]&0x3f;//日时间无效位的屏蔽

   g_aTimeBin[4]=g_aTimeBin[4]&0x07;//星期时间无效位的屏蔽   

   g_aTimeBin[5]=g_aTimeBin[5]&0x1f;//月/世纪时间无效位的屏蔽,如果最高位0,世纪为21,  

   g_aTimeBin[6]=g_aTimeBin[6]&0xff;//年时间无效位的屏蔽   

}

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2007-1-12 12:41:59 | 显示全部楼层
应该鼓励一下

出0入0汤圆

发表于 2008-7-16 22:46:23 | 显示全部楼层
呵呵很好,谢谢!

出0入0汤圆

发表于 2008-7-17 08:27:30 | 显示全部楼层
有硬接口不用?

出0入42汤圆

发表于 2008-7-17 09:04:31 | 显示全部楼层
顶!

出0入0汤圆

发表于 2010-4-24 23:03:32 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-3-28 00:03:21 | 显示全部楼层
留个记号先!

出0入0汤圆

发表于 2013-6-3 16:29:37 | 显示全部楼层
向LZ学习,觉的编译器inline assembly这个功能很好!谢谢。。。

出0入0汤圆

发表于 2015-1-6 19:23:50 来自手机 | 显示全部楼层
请教楼主一下 关闭闹铃的操作使用您的这种AF的方法 还是把闹铃位都屏蔽掉?

出0入0汤圆

发表于 2015-9-12 22:56:11 | 显示全部楼层
留个记号先!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 03:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表