搜索
bottom↓
回复: 13

用GCC写的PCF8563和FM24C256程序,已经在MEGA8L调试通过,欢迎大家使用

[复制链接]

出0入0汤圆

发表于 2005-8-3 13:05:40 | 显示全部楼层 |阅读模式
#include <avr/io.h>

#include <avr/twi.h>

#include <avr/signal.h>

#define                fosc                7372800

#define     sla                        0xa0

#define     slav        0xa2

#define                TW_WRITE        0

#define                TW_READ                1

#define     max                        3

#define     uchar                unsigned    char

#define         uint                unsigned    int

#define         ulong                unsigned    long



void Twi_Init( void )

{

        TWBR = 0x20;//设置波特率

        TWSR &= 0xfc;//设置预分频因子,则SCL频率为92160Hz

}



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

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

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

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

void Datajust(void)

{        

        trdata[0]=trdata[0]&0x7f;

        trdata[1]=trdata[1]&0x7f;

        trdata[2]=trdata[2]&0x3f;

        trdata[3]=trdata[3]&0x3f;

        trdata[4]=trdata[4]&0x07;

        trdata[5]=trdata[5]&0x1f;

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

}



uchar FM24C256_Write( uint address,uchar write_data )

{

        uchar twst,n=0x0,rv=0x1;

        restart:

                if(n++>=max)

                        goto error;

        begin:

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

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

                switch((twst = TW_STATUS))

                {

                        case   TW_REP_START://有可能出现

                        case        TW_START:

                                        break;

                        case        TW_MT_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

                TWDR = sla | TW_WRITE;//发送SLA+W

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

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

                switch((twst = TW_STATUS))

                {

                        case        TW_MT_SLA_ACK:

                                        break;

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

                                        goto        restart;

                        case        TW_MT_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

                TWDR = address>>8;//传输地址高8位

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

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

                switch((twst = TW_STATUS))

                {

                        case        TW_MT_DATA_ACK:

                                        break;

                        case        TW_MT_DATA_NACK:

                                        goto        quit;

                        case        TW_MT_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

                TWDR = address;//传输地址低8位

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

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

                switch((twst = TW_STATUS))

                {

                        case        TW_MT_DATA_ACK:

                                        break;

                        case        TW_MT_DATA_NACK:

                                        goto        quit;

                        case        TW_MT_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

                TWDR = write_data;

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

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

                switch((twst = TW_STATUS))

                {

                        case        TW_MT_DATA_ACK:

                                        break;

                        default:

                                        goto        error;

                }

        quit:

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

                return        rv;

        error:

                rv=0x0;

        goto        quit;

               

}



uchar FM24C256_Read( uint address  )

{

        uchar twst,n=0x0,rv=0x1;

        restart:

                if(n++>=max)

                        goto error;

        begin:

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

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

                switch((twst = TW_STATUS))

                {

                        case   TW_REP_START://有可能出现

                        case        TW_START:

                                        break;

                        case        TW_MT_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

                TWDR = sla | TW_WRITE;//发送SLA+W

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

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

                switch((twst = TW_STATUS))

                {

                        case        TW_MT_SLA_ACK:

                                        break;

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

                                        goto        restart;

                        case        TW_MT_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

                TWDR = address>>8;//传输地址高8位

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

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

                switch((twst = TW_STATUS))

                {

                        case        TW_MT_DATA_ACK:

                                        break;

                        case        TW_MT_DATA_NACK:

                                        goto        quit;

                        case        TW_MT_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

                TWDR = address;//传输地址低8位

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

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

                switch((twst = TW_STATUS))

                {

                        case        TW_MT_DATA_ACK:

                                        break;

                        case        TW_MT_DATA_NACK:

                                        goto        quit;

                        case        TW_MT_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

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

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

                switch((twst = TW_STATUS))

                {

                        case        TW_REP_START://正确的状态

                                        break;

                        case        TW_MT_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

                TWDR = sla | TW_READ;//发送SLA+R

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

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

                switch((twst = TW_STATUS))

                {

                        case        TW_MR_SLA_ACK:

                                        break;

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

                                        goto        restart;

                        case        TW_MR_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

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

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

                switch((twst = TW_STATUS))

                {

                        case        TW_MR_DATA_NACK:

                                        rv = TWDR;

                                        break;

                        default:

                                        goto        error;

                }

        quit:

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

                return        rv;

        error:

                rv=0x0;

        goto        quit;

}



uchar SetHym8563(uchar suba,uchar *s,uchar no )

{

        uchar twst,i,n=0x0,rv=0x1;

        restart:

                if(n++>=max)

                        goto error;

        begin:

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

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

                switch((twst = TW_STATUS))

                {

                        case   TW_REP_START://有可能出现

                        case        TW_START:

                                        break;

                        case        TW_MT_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

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

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

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

               

                switch((twst = TW_STATUS))

                {

                        case        TW_MT_SLA_ACK:

                                        break;

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

                                        goto        restart;

                        case        TW_MT_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

                TWDR = suba | TW_WRITE;//发送SUBA+W

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

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

               

                switch((twst = TW_STATUS))

                {

                        case        TW_MT_DATA_ACK:

                                        break;

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

                                        goto        restart;

                        case        TW_MT_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

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

                {

                        TWDR = *s | TW_WRITE;

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

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

                        switch((twst = TW_STATUS))

                        {

                                case        TW_MT_DATA_ACK:

                                                break;

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

                                                goto        restart;

                                case        TW_MT_ARB_LOST:

                                                goto        begin;

                                default:

                                                goto        error;

                        }

                        s++;

                }

        quit:       

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

                return        rv;

        error:

                rv=0x0;

        goto        quit;       

}



uchar GetHym8563(uchar suba,uchar *s,uchar no)

{

        uchar twst,i,n=0x0,rv=0x1;

        restart:

                if(n++>=max)

                        goto error;

        begin:

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

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

                switch((twst = TW_STATUS))

                {

                        case   TW_REP_START://有可能出现

                        case        TW_START:

                                        break;

                        case        TW_MT_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

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

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

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

               

                switch((twst = TW_STATUS))

                {

                        case        TW_MT_SLA_ACK:

                                        break;

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

                                        goto        restart;

                        case        TW_MT_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

                TWDR = suba | TW_WRITE;//发送SUBA+W

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

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

               

                switch((twst = TW_STATUS))

                {

                        case        TW_MT_DATA_ACK:

                                        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))==0x0);//等待发送完毕

               

                switch((twst = TW_STATUS))

                {

                        case        TW_REP_START://正确的状态

                                        break;

                        case        TW_MT_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

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

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

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

               

                switch((twst = TW_STATUS))

                {

                        case        TW_MR_SLA_ACK:

                                        break;

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

                                        goto        restart;

                        case        TW_MR_ARB_LOST:

                                        goto        begin;

                        default:

                                        goto        error;

                }

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

                {

                        if(i==(no-1))

                        {

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

                        }

                        else

                        {

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

                        }

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

                        switch((twst = TW_STATUS))

                        {

                                case        TW_MR_DATA_NACK:

                                case        TW_MR_DATA_ACK:

                                                *s = TWDR;

                                                s++;

                                                break;

                                default:

                                                goto        error;

                        }

                }

        quit:       

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

                return        rv;

        error:

                rv=0x0;

        goto        quit;       

}

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

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

出0入0汤圆

发表于 2005-8-4 15:31:28 | 显示全部楼层
好贴,学习之!!

出0入0汤圆

发表于 2005-8-4 18:02:12 | 显示全部楼层
楼主的.H库文件我是没有的,请给个附件吧

出0入0汤圆

发表于 2006-3-8 20:23:23 | 显示全部楼层
装一个winavr就有了

出0入0汤圆

发表于 2006-3-9 08:24:04 | 显示全部楼层
I2C接收口的铁电还没用过!SPI的用过了。

收下看看。谢谢!

出0入0汤圆

发表于 2006-5-27 01:06:20 | 显示全部楼层
为什么按照楼主的程序,在我的工程里,是非常规律的40s正确,20s错误呢?

错误现象为:小时的十位和月份的十位周期性错误,经查是读出的数据错误。



为什么啊?

谢谢

出0入0汤圆

发表于 2006-5-27 18:08:37 | 显示全部楼层
我找到原因了,没有用楼主提供的void Datajust(void);

出0入0汤圆

发表于 2006-11-17 22:46:57 | 显示全部楼层
先不看程序,顶一下,楼主和我的硬件用法应是一样的,我的是M64+at2408+8563,哈哈,程序都不用编了

出0入0汤圆

发表于 2007-1-26 10:55:32 | 显示全部楼层
谢谢楼主的程序!但我用你的程序,我用的是MEGA128,晶振7.3728M,TWI设置我用的

DDRA  = 0xff;

DDRD  = 0x00;

PORTD = 0xff;

TWBR = 0x73;//设置波特率

在执行uchar SetHym8563(uchar suba,uchar *s,uchar no )函数,

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

while((TWCR & _BV(TWINT))==0x0)dis_str(2,1,"error\0\0");//等待发送完毕

执行到WHILE就死在那了!不往下执行了,小弟刚学AVR,希望有人能够解答一下!谢谢!是不是设置有问题??

出0入0汤圆

发表于 2007-2-2 18:01:22 | 显示全部楼层
GOTO ,不喜欢用

出0入0汤圆

发表于 2009-4-14 10:59:21 | 显示全部楼层
不得不说 这段代码 不怎么地 乱就一个字

出0入0汤圆

发表于 2011-11-1 00:05:02 | 显示全部楼层
看看

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-3-29 20:49

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

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