打印
[PIC®/AVR®/dsPIC®产品]

IIC总线+PCF8563芯片

[复制链接]
724|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tfqi|  楼主 | 2022-10-10 16:00 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
1  PCF8563芯片







可以看出,PCF8563芯片一共有16个寄存器。也就是该芯片的内部地址最大为0x0f。上述的16个寄存器除了作为普通的存储功能外,还具备授时功能。

2 实现过程
2.1 电路图


2.2 源代码


/*---------------------函数功能:
                IIC总线 + PCF8563(内部只有16个地址空间
PCF8563芯片一共有16个寄存器。也就是该芯片的内部地址最大为0x0f。
上述的16个寄存器除了作为普通的存储功能外,还具备授时功能。
-----------------------------------------*/


#include<pic.h>// 调用PIC16f87XA单片机的头文件
#include"delay.h"//调用延时子函数的头文件



__CONFIG(0xFF32);//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关
//__CONFIG(HS&WDTDIS&LVPDIS);



/*-----------宏定义--------------*/
#define  uint  unsigned int
#define  uchar unsigned char
#define  SDA     RC6                        // IIC的数据线
#define  SCL     RC5                        // IIC的时钟线



/*-----------子函数声明--------------*/
void IIC_start(void);                // IIC启动信号函数
void IIC_end(void);                        // IIC终止信号函数

void write_1Byte(uchar buf);//向IIC总线写一个字节的函数
char read_1Byte();                        //从IIC总线读一个字节的函数

void write_PCF8563(char address,char databuf);        //向AT24C02芯片的指定地址写一个字节的数据
char read_PCF8563(char address);                                //从AT24C02芯片的指定地址读一个字节的数据



/*-----------主函数--------------*/
void main()
{
        char bufdata;

        // data direction register is TRISA.
        // Setting  a TRISA bit (= 1) will make the corresponding PORTA pi an input.
        // Clearing a TRISA bit (= 0) will make the corresponding PORTA pin an output.
        TRISD=0x00;                        //RD作为输出口,作为LED灯的显示
        //TRISC=0B10011111;

        PORTD=0x00;                        //LED的初值为0
        //PORTC=0X00;

        delay_xms(100);

        while(1)
        {
                bufdata=read_PCF8563(0x00);// 从PCF8563中地址0x00读出数据
                PORTD=bufdata;
                delay_xms(100);


                bufdata=bufdata+1+0xaa;
                PORTD=bufdata;
                delay_xms(100);


                write_PCF8563(0x00,bufdata);//将+1的数据保存在0x00中
        }
       
}






/*************IIC启动信号函数***************/
void IIC_start(void)
{
        //为什么这样写,见IIC的时序图
        SDA=1;
        SCL=1;
        asm("NOP");
        asm("NOP");

        SDA=0;
        asm("NOP");
        asm("NOP");

        SCL=0;
        asm("NOP");
        asm("NOP");

}




/*************IIC终止信号函数***************/
void IIC_end(void)
{
        SDA=0;
        SCL=0;
        asm("NOP");
        asm("NOP");

        SCL=1;
        asm("NOP");
        asm("NOP");

        SDA=1;
        asm("NOP");
        asm("NOP");

        SCL=0;//拉低
        asm("NOP");
        asm("NOP");

}




/*************向IIC总线写一个字节(8 bit)的函数***************/
void write_1Byte(uchar buf)
{
        int k=0;
        for(k=0;k<8;k++)
        {
                //将最高位写到SDA总线上去
                //SDA=buf&0x80;                // 等价于下面的if语句
                if(buf&0x80)                // 提取buf的最高位数据
                        SDA=1;                        //如果buf的最高位为1,就写1
                else
                        SDA=0;                        //如果buf的最高位为0,就写0
                asm("NOP");
                asm("NOP");
               
                SCL=1;
                asm("NOP");

                SCL=0;                                //时钟信号归零
                asm("NOP");

                buf=buf<<1;                        //左移一位,准备提取下一个待写的数据
        }


        // 每接收到一个字节的数据后,从机必须产生一个应答信号给主机。
        // 应答器件在第9个时钟周期将SDA线拉低,表示已经接收了一个八位数据
        TRISC4=1;                                //RC4作为输入,SDA引脚接的是RC4口   开始读数据,读SDA的值
        asm("NOP");

        SCL=1;       
        asm("NOP");
        asm("NOP");
        //if(RC4=0)                         //说明SDA=0,即成功接收
        SCL=0;
        TRISC4=0;
}




/*************向IIC总线读一个字节(8 bit)的函数***************/
char read_1Byte()
{
        int k=0;
        char t_byte=0x00;

        TRISC4=1;                                        //RC4作为输入,SDA引脚接的是RC4口     开始读数据,读SDA的值

        for(k=0;k<8;k++)
        {
                t_byte=t_byte<<1;                //左移一位
                SCL=1;
                asm("NOP");
                asm("NOP");

                //读 SDA的值
                if(SDA=1)
                        t_byte=t_byte|0x01;//写1 只对最低位有影响
                else
                        t_byte=t_byte&0xfe;//写0

                SCL=0;
                asm("NOP");
                asm("NOP");
        }

        TRISC4=0;

        return t_byte;                // 返回的是一个字节 eg:0x3f
}





/*************向PCF8563芯片的指定地址写一个字节的数据***************/
void write_PCF8563(char address,char databuf)
{
        IIC_start();                        //发送起始信号

        //PCF8563芯片寄存器: 1010 A2 A1 A0 R/W_n  AT24C02芯片的高四位固定为1010
        // A2A1A0:从机选择,一共可以接八个AT24C02芯片。  A2A1A0=000,选择第一个芯片。  R/W_n:读/写

        // I2C-bus slave address: read A3h and write A2h
        write_1Byte(0xa2);                //表示写
        //指定该器件内部的某一个地址(确定芯片内部地址)
        write_1Byte(address);        //指定该芯片内部的某一个地址(一共有16个地址)
        //向该芯片的指定地址里面写数据
        write_1Byte(databuf);        //向指定地址发送数据

        IIC_end();                                //发送结束信号
}




/*************从PCF8563芯片的指定地址读一个字节的数据***************/
char read_PCF8563(char address)
{
        char buf;

        // PCF8563芯片寄存器: 1010 A2 A1 A0 R/W_n  PCF8563芯片的高四位固定为1010
        // A2A1A0:从机选择,一共可以接八个PCF8563芯片。  A2A1A0=000,选择第一个芯片。  R/W_n:读/写
       

        IIC_start();                        //发送起始信号
        // I2C-bus slave address: read A3h and write A2h
        write_1Byte(0xa2);                //表示写
        //指定该器件内部的某一个地址(确定芯片内部地址)
        write_1Byte(address);        //指定该芯片内部的某一个地址(一共有256个地址)




        //在传输过程中,当需要改变传送方向时(写<->读),起始信号IIC_start()和从机地址write_1Byte(0xa1)都被重复产生一次
        //由于写变成读,所以需要下面两条指令
        IIC_start();                        //再次启动
        // I2C-bus slave address: read A3h and write A2h
        write_1Byte(0xa3);                //表示读
        //读出该芯片指定地址的数据
        buf=read_1Byte();               


        IIC_end();                                //发送结束信号



        return buf;                                // 返回的是一个字节 eg:0x3f
}


使用特权

评论回复
沙发
chenqianqian| | 2022-10-10 18:57 | 只看该作者
这个是protues仿真的嘛?

使用特权

评论回复
板凳
软核硬核| | 2022-10-12 21:11 | 只看该作者
Microchip居然有芯片能在Proteus仿真?

使用特权

评论回复
地板
AdaMaYun| | 2022-10-13 08:27 | 只看该作者
NB,Microchip 可以在Proteus仿真,现在用的Proteus哪个版本,方便发一下安装包嘛,谢谢!

使用特权

评论回复
5
天天向善| | 2022-10-13 13:12 | 只看该作者
PIC16F877A是Proteus自带的元器件?哪个版本的才有?

使用特权

评论回复
6
tpgf| | 2022-11-1 11:44 | 只看该作者
汇编语言里边的nop的延时时间一般和什么参数有关系呢

使用特权

评论回复
7
qcliu| | 2022-11-1 12:15 | 只看该作者
看楼主的代码  感觉应该是使用的普通的io口进行的模拟吧

使用特权

评论回复
8
drer| | 2022-11-1 13:14 | 只看该作者
在传输过程中,当需要改变传送方向时(写<->读),会引起传输的混乱吗

使用特权

评论回复
9
coshi| | 2022-11-1 13:47 | 只看该作者
如何确定我需要读取的数据在PCF8563芯片的哪个地址呢

使用特权

评论回复
10
kxsi| | 2022-11-1 14:14 | 只看该作者
在读写转换的过程中,需要对数据现场进行保护吧

使用特权

评论回复
11
wiba| | 2022-11-1 14:32 | 只看该作者
iic的通讯连接一旦发生错误,如何自动纠正或者说重新建立这种连接呢

使用特权

评论回复
12
Bowclad| | 2022-11-2 20:10 | 只看该作者
使用的普通的io口进行的模拟的吗?

使用特权

评论回复
13
Jacquetry| | 2022-11-4 20:19 | 只看该作者
需要对数据现场进行保护吗?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

56

主题

3316

帖子

4

粉丝