STM8L052C6硬件I2C调试:PCF8563/BM856时钟芯片

网上基本都提倡用软件模拟I2C,之前读温湿度传感器也是用模拟的。这次有时间和机会再次用上I2C,固决定用硬件I2C调试下,目前看来没有问题,读写设备都正常。

一、注意事项

     1、I2C硬件上需要外部上拉,单纯软件上拉不行。

     2、如连续读个字节如8563的second~years数据共7 bytes,中间需要delay。否则只能成功读取前两个byte, clock会断掉。具体delay时间没有确切的验证,用如下实例代码测试OK。

     3、查看是否有time定时中断,读写过程最好先关中断。

二、工程下载

https://download.csdn.net/download/xqw19891201/11267260

三、参考代码

     1、IIC初始化

#include "main.h"
#include "bm8563.h"
#include "key.h"


TimeApi TimeTag;
TimeApi* pTimeTag = &TimeTag;

#define IIC_SDA_PORT            GPIOC
#define IIC_SDA_PIN             GPIO_Pin_0
#define IIC_SCL_PORT            GPIOC
#define IIC_SCL_PIN             GPIO_Pin_1
 
#define IIC_FREQ                40000

#define BM8563_ADDR                 0xA2
#define BM8563_REG_CTRL_1           0x00
#define BM8563_REG_CTRL_2           0x01
#define BM8563_REG_WATCH_SEC        0x02
#define BM8563_REG_WATCH_MIN        0x03
#define BM8563_REG_WATCH_HOUR       0x04
#define BM8563_REG_WATCH_DATE       0x05
#define BM8563_REG_WATCH_DAY        0x06
#define BM8563_REG_WATCH_MON        0x07
#define BM8563_REG_WATCH_YEAR       0x08

enum{
    Sec = 0x00,
    Min,      
    Hour,
    Days,
    WeekDays,
    Mon,
    Years,
    MaxIndex,
};

/**********************************************************************/
//Description:	Bm8563Init()															  
//Parameters:                        												  
//Return:   																  
//Date:           
//Author:       quanwu.xu  
/**********************************************************************/
void Bm8563Init(void)
{
    pTimeTag->TimeArray[Sec] = 0;
    pTimeTag->TimeArray[Min] = 0;  
    pTimeTag->TimeArray[Hour] = 0;
    pTimeTag->TimeArray[Days] = 0;
    pTimeTag->TimeArray[WeekDays] = 0;  
    pTimeTag->TimeArray[Mon] = 0;
    pTimeTag->TimeArray[Years] = 0;
    pTimeTag->SetIndex = Years;
    
    GPIO_Init(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_Mode_Out_PP_High_Fast);
    GPIO_Init(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_Mode_Out_PP_High_Fast); 
    I2C_DeInit(I2C1);
    CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);
    I2C_Init(I2C1, IIC_FREQ, BM8563_ADDR, I2C_Mode_I2C, I2C_DutyCycle_2,
                           I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit);
}


          2、时间读取

/**********************************************************************/
//Description:	GetBm8563Data()															  
//Parameters:                        												  
//Return:   																  
//Date:           
//Author:       quanwu.xu  
/**********************************************************************/
void GetBm8563Data(TimeApi* pTime)
{
    uint8_t i = 0;
    uint8_t ReadBuf[BUF_LENGTH] = {0};

    disableInterrupts();
    
    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

    //1、start
    I2C_GenerateSTART(I2C1,ENABLE);    
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));

    //2、write addr
    I2C_Send7bitAddress(I2C1, BM8563_ADDR, I2C_Direction_Transmitter);    
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    //3、write data reg
    I2C_SendData(I2C1, BM8563_REG_WATCH_SEC);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    //4、start
    I2C_GenerateSTART(I2C1,ENABLE);    
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));    

    //5、read addr reg
    I2C_Send7bitAddress(I2C1, BM8563_ADDR, I2C_Direction_Receiver);
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

    //6、read data    
    DelayMs(1);
    for(i=0; i<BUF_LENGTH; i++)
    {            
        if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
        {
            ReadBuf[i]=I2C_ReceiveData(I2C1);
        }
        
        if(i == (BUF_LENGTH-1))
        {
            I2C_AcknowledgeConfig(I2C1,DISABLE);
        }
   
        else
        {
            I2C_AcknowledgeConfig(I2C1,ENABLE);
        }
        Delay(1000);      
    }

    //7、stop
    I2C_GenerateSTOP(I2C1,ENABLE);
    I2C_AcknowledgeConfig(I2C1,ENABLE);
    
    enableInterrupts();
    
    BcdToDecConversion(pTime, ReadBuf);

    printflog("20%d%d-%d-%d\n", pTime->TimeArray[Years]/10, pTime->TimeArray[Years]%10, pTime->TimeArray[Mon], pTime->TimeArray[Days]);    
    printflog("%d:%d:%d\n", pTime->TimeArray[Hour], pTime->TimeArray[Min], pTime->TimeArray[Sec]);    
}

3、时间设定



/**********************************************************************/
//Description:	SetBm8563Data()															  
//Parameters:                        												  
//Return:   																  
//Date:           
//Author:       quanwu.xu  
/**********************************************************************/
void SetBm8563Data(TimeApi* pTime)
{    
    uint8_t i = 0;
    uint8_t WriteBuf[BUF_LENGTH] = {0};
    
    pTime->SetIndex = Years;
    DecToBcdConversion(pTime, WriteBuf);

    disableInterrupts();
    
    while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
    //1、start
    I2C_GenerateSTART(I2C1,ENABLE);    
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));

    //2、write addr
    I2C_Send7bitAddress(I2C1, BM8563_ADDR, I2C_Direction_Transmitter);
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    //3、write data reg
    I2C_SendData(I2C1, BM8563_REG_WATCH_SEC);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    //write data
    DelayMs(1);
    for(i=0; i<BUF_LENGTH; i++)
    { 

        I2C_SendData(I2C1,WriteBuf[i]);

        if(i == BUF_LENGTH-1)
        {
            while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
        }
        else
        {
            while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING));
        }        
    }
    I2C_GenerateSTOP(I2C1,ENABLE);  

    enableInterrupts();   
}

 

 

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值