搜索
bottom↓
回复: 4

用mega88驱动PCF8563的详细程序,GCC编译

[复制链接]

出0入0汤圆

发表于 2006-11-15 09:03:36 | 显示全部楼层 |阅读模式
本程序参考了应用示例,注意由于PCF8563的晶振启动较慢,所以开机一定要加延时,否则肯定不稳定:

#include<avr/io.h>

#define uint unsigned int

#define uchar unsigned char

#define PCF8536_ADDR 0XA2

//#define TW_ACK 1

//#define TW_NACK 0

#define TW_READ 1

#define TW_WRITE 0

#define TW_START                0x08

#define TW_REP_START                0x10

/* Master Transmitter */

#define TW_MT_SLA_ACK                0x18

#define TW_MT_SLA_NACK                0x20

#define TW_MT_DATA_ACK                0x28

#define TW_MT_DATA_NACK                0x30

#define TW_MT_ARB_LOST                0x38

/* Master Receiver */

#define TW_MR_ARB_LOST                0x38

#define TW_MR_SLA_ACK                0x40

#define TW_MR_SLA_NACK                0x48

#define TW_MR_DATA_ACK                0x50

#define TW_MR_DATA_NACK                0x58

/* Slave Transmitter */

#define TW_ST_SLA_ACK                0xA8

#define TW_ST_ARB_LOST_SLA_ACK        0xB0

#define TW_ST_DATA_ACK                0xB8

#define TW_ST_DATA_NACK                0xC0

#define TW_ST_LAST_DATA                0xC8

/* Slave Receiver */

#define TW_SR_SLA_ACK                0x60

#define TW_SR_ARB_LOST_SLA_ACK        0x68

#define TW_SR_GCALL_ACK                0x70

#define TW_SR_ARB_LOST_GCALL_ACK 0x78

#define TW_SR_DATA_ACK                0x80

#define TW_SR_DATA_NACK                0x88

#define TW_SR_GCALL_DATA_ACK        0x90

#define TW_SR_GCALL_DATA_NACK        0x98

#define TW_SR_STOP                0xA0

/* Misc */

#define TW_NO_INFO                0xF8

#define TW_BUS_ERROR                0x00

/*

* The lower 3 bits of TWSR are reserved on the ATmega163.

* The 2 LSB carry the prescaler bits on the newer ATmegas.

*/

#define TW_STATUS_MASK                (_BV(TWS7)|_BV(TWS6)|_BV(TWS5)|_BV(TWS4)|_BV(TWS3))

#define TW_STATUS                (TWSR & TW_STATUS_MASK)

#define     max         3



uchar lcdbuf[]={0x18,0xDB,0x8C,0X89,0X4B,0X29,0X28,0X9B,0X08,0X09,0X60,};

//从0~9是对的

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

uchar displaybuf[7];       

/************************延时函数***********************/

void delay1(uint us)

{

while(us--);

}



void delay2(uint ms)

{

uint i,j;

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

for(j=0;j<10;j++)

delay1(1);

}

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

void port_init(void)

{

DDRC=_BV(PC0)|_BV(PC1)|_BV(PC2);

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

}

/***************************lcd操作部分**********************/

void lcd_clk(void)

{

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

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

}



void sendbyte(uchar date)

{

uchar t;

for(t=0;t<8;t++)

{

if((date>>t)&0x01)

{

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

lcd_clk();

}

else

{

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

lcd_clk();

}

}

}

void displaylcd(uchar *buff)//一次发送7个字节显示lcd

{

uchar m;

for(m=0;m<7;m++)

sendbyte(buff[m]);

}



/*************atmega主模式TWI 操作部分*****开始**************/

void twi_init(void)

{

TWCR= 0X00; //disable twi

TWBR= 0x20; //set bit rate

TWSR=0x00; //set prescale

TWAR= 0x00; //set slave address

TWCR= 0x04; //enable twi

}

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

uchar write_8563(uchar addr,uchar *buf,uchar num )

{

   uchar twst,i,n=0x00,rv=0x01;

   restart:

      if(n++>=max)

         goto error;

   begin:

      TWCR = _BV(TWINT)|_BV(TWSTA)|_BV(TWEN);//发送开始信号

      while((TWCR&_BV(TWINT))==0x00);//等待发送完毕

      switch((twst=TW_STATUS))

      {

         case   TW_REP_START://有可能出现

         case   TW_START://0x08

               break;

         case   TW_MT_ARB_LOST:

               goto   begin;

         default:

               goto   error;

      }

      TWDR=PCF8536_ADDR|TW_WRITE;//发送SLAV+W

      TWCR=_BV(TWINT)|_BV(TWEN);//清TWINT,开始传输

      while((TWCR&_BV(TWINT))==0x00);//等待传输完毕

      

      switch((twst = TW_STATUS))

      {

         case  TW_MT_SLA_ACK: //0x18

               break;

         case  TW_MT_SLA_NACK://器件忙,有可能处于内部写周期

               goto   restart;

         case  TW_MT_ARB_LOST:

               goto   begin;

         default:

               goto   error;

      }

      TWDR=addr|TW_WRITE;//发送addr+W

      TWCR=_BV(TWINT)|_BV(TWEN);//清TWINT,开始传输

      while((TWCR & _BV(TWINT))==0x00);//等待传输完毕

      

      switch((twst=TW_STATUS))

      {

         case TW_MT_DATA_ACK://0x28

               break;

         case TW_MT_DATA_NACK://器件忙,有可能处于内部写周期

               goto  restart;

         case TW_MT_ARB_LOST:

               goto  begin;

         default:

               goto  error;

      }

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

      {

         TWDR=*buf|TW_WRITE;

         TWCR=_BV(TWINT)|_BV(TWEN);//清TWINT,开始传输

         while((TWCR&_BV(TWINT))==0x00);//等待传输完毕

         switch((twst=TW_STATUS))

         {

            case  TW_MT_DATA_ACK://0x28

                  break;

            case  TW_MT_DATA_NACK://器件忙,有可能处于内部写周期

                  goto   restart;

            case  TW_MT_ARB_LOST:

                  goto   begin;

            default:

                  goto   error;

         }

         buf++;

      }

   quit:   

      TWCR=_BV(TWINT)|_BV(TWSTO)|_BV(TWEN);//发送停止信号

      return   rv;// 正确返回1

   error:

      rv=0x0; //错误返回0

   goto   quit;   

}





uchar read_8563(uchar addr,uchar *buf,uchar num)

{

   uchar twst,i,n=0x00,rv=0x01;

   restart:

      if(n++>=max)

         goto error;

   begin:

      TWCR=_BV(TWINT)|_BV(TWSTA)|_BV(TWEN);//发送开始信号

      while((TWCR&_BV(TWINT))==0x00);//等待发送完毕

      switch((twst = TW_STATUS))

      {

         case   TW_REP_START://有可能出现

         case   TW_START: //0x08

               break;

         case   TW_MT_ARB_LOST:

               goto begin;

         default:

               goto error;

      }

      TWDR=PCF8536_ADDR|TW_WRITE;//发送SLAV+W

      TWCR=_BV(TWINT)|_BV(TWEN);//清TWINT,开始传输

      while((TWCR&_BV(TWINT))==0x0);//等待传输完毕

      

      switch((twst = TW_STATUS))

      {

         case  TW_MT_SLA_ACK: //0x18

               break;

         case  TW_MT_SLA_NACK://器件忙,有可能处于内部写周期

               goto   restart;

         case  TW_MT_ARB_LOST:

               goto  begin;

         default:

               goto  error;

      }

      TWDR=addr|TW_WRITE;//发送addr+W

      TWCR=_BV(TWINT)|_BV(TWEN);//清TWINT,开始传输

      while((TWCR & _BV(TWINT))==0x00);//等待传输完毕

      

      switch((twst=TW_STATUS))

      {

         case  TW_MT_DATA_ACK: //0x28

               break;

         case  TW_MT_DATA_NACK://器件忙,有可能处于内部写周期

               goto   restart;

         case  TW_MT_ARB_LOST:

               goto  begin;

         default:

               goto  error;

      }

      TWCR=_BV(TWINT)|_BV(TWSTA)|_BV(TWEN);//发送(重新)开始信号

      while((TWCR&_BV(TWINT))==0x00);//等待发送完毕

      

      switch((twst=TW_STATUS))

      {

         case  TW_REP_START://正确的状态 ,0x10

               break;

         case  TW_MT_ARB_LOST:

               goto  begin;

         default:

               goto  error;

      }

      TWDR=PCF8536_ADDR|TW_READ;//发送SLAV+R

      TWCR=_BV(TWINT)|_BV(TWEN);//清TWINT,开始传输

      while((TWCR&_BV(TWINT))==0x00);//等待传输完毕

      

      switch((twst=TW_STATUS))

      {

         case  TW_MR_SLA_ACK: //0x40

               break;

         case  TW_MR_SLA_NACK://器件忙,有可能处于内部写周期

               goto  restart;

         case  TW_MR_ARB_LOST:

               goto  begin;

         default:

               goto  error;

      }

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

      {

         if(i==(num-1))

         {

            TWCR=_BV(TWINT)|_BV(TWEN);//清TWINT,最后一个字节,开始传输(无应答)

         }

         else

         {

            TWCR=_BV(TWINT)|_BV(TWEN)|_BV(TWEA) ;//清TWINT,开始传输(有应答)

         }

         while((TWCR&_BV(TWINT))==0x00);//等待传输完毕

         switch((twst=TW_STATUS))

         {

            case   TW_MR_DATA_NACK:

            case   TW_MR_DATA_ACK:

                  *buf=TWDR;

                  buf++;

                  break;

            default:

                  goto   error;

         }

      }

   quit:   

      TWCR=_BV(TWINT)|_BV(TWSTO)|_BV(TWEN);//发送停止信号

      return   rv; //正确返回1

   error:

      rv=0x00; //错误返回0

   goto   quit;   

}

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

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

说明: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;

   g_aTimeBin[6]=g_aTimeBin[6]&0xff;  

}





/*************************主函数*************************/

int main(void)

{

//MCUCR=0;

delay2(6000);//PCF8663的晶振启动时间慢

port_init();

twi_init();

uchar g_aTimeBuf[16]={0,0,0x30,0x10,0x08,0x11,0x06,0x11,0x06,0x80,0x80,0x80,0x80,0x00,0x00,0x00};

//写入2006年11月11日,9:20:30,其他功能无效

//uchar *buf1[7]={0xff,0xff,0xff,0xff,0xff,0xff,0xff};//清屏

//displaylcd(buf1);

write_8563(0x00,g_aTimeBuf,16);

while(1)

{



uchar z;

read_8563(0x02,g_aTimeBin,7);

Data_ajust();

displaybuf[0]=0xff;

displaybuf[1]=g_aTimeBin[0]&0x0f;//取秒低四位

displaybuf[2]=(g_aTimeBin[0]>>4)&0x0f;//取秒高四位

displaybuf[3]=g_aTimeBin[1]&0x0f;//取分钟低四位

displaybuf[4]=(g_aTimeBin[1]>>4)&0x0f;//取分钟高四位

displaybuf[5]=g_aTimeBin[2]&0x0f;//取小时低四位

displaybuf[6]=(g_aTimeBin[2]>>4)&0x0f;//取小时高四位

for(z=1;z<7;z++)

displaybuf[z]=lcdbuf[displaybuf[z]];

displaylcd(displaybuf);

delay2(400);

}

}

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

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2006-11-15 11:52:14 | 显示全部楼层
支持共享.



另.最前面那一段宏定义,在avr/twi.h里面已经有了,不用自己再写一遍了.
头像被屏蔽

出0入0汤圆

发表于 2011-8-24 22:29:12 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2012-1-12 17:07:49 | 显示全部楼层
mark

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-6-12 07:45

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

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