历史上的今天
今天是:2024年12月16日(星期一)
2019年12月16日 | STM8L052C6硬件I2C调试:PCF8563/BM856时钟芯片
2019-12-16 来源:eefocus
网上基本都提倡用软件模拟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 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-%dn", pTime->TimeArray[Years]/10, pTime->TimeArray[Years]%10, pTime->TimeArray[Mon], pTime->TimeArray[Days]); printflog("%d:%d:%dn", 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 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(); }
史海拾趣
|
现在访问论坛的人还不到200人:L ,而且还不见上涨。 上来说话的就更少了。 论坛改版之后问题更是凸现衔接不上,没有通过测试就直接使用,至少也应该测下能否兼容吧。:( 影响人的心情。 对于删帖子也有点操作不当,对于不适合的帖子应该移到相应 ...… 查看全部问答> |
|
利用PC104单板机,DOS操作系统,在程序中使用100ms定时中断来处理输入输出等操作,利用串口中断来进行串口数据通讯。在发生串口中断时将所有中断屏蔽。串口设置为最常用的9600,现在遇到一个问题就是串口数据通讯成功率不高,有很多数据丢失的现象 ...… 查看全部问答> |
|
本帖最后由 dontium 于 2015-1-23 11:13 编辑 我的通讯设置为FIFO模式,11个数进一次接收中断(唯一的中断入口),信号是通过一个上位发送的。出现了错误。 现象如下:当上位机程序重起时,我的板子必须掉电重起,否则我的程序的中断根本进不去, ...… 查看全部问答> |
|
单颗LED白灯在老化板上检测出来的数据,与把LED白灯组装成一个灯具老化时检测出来的数据,肯定是有点出入的。 这个差异的大小,取决于LED工作时的电性参数和灯具的设计情况,以及灯具使用的环境。 首先,选择什么样的LED白灯。 这 ...… 查看全部问答> |
|
《Google Android开发技术》,西电出版,作者:张勇,2011.10 内 容 简 介 Android系统是安装在智能移动设备上的嵌入式操作系统,包括Linux内核、系统库与Java运行时、应用程序框架和应用程序层等四部分,具有公开源代码 ...… 查看全部问答> |
|
介绍德州仪器 C2000微控制器系列中的最新 Concerto MCU在许多性能方面特有的优势,解释为什么Concerto 可以帮助您消除以往技术妥协的烦恼。探讨TI MCU 产品系列以及 C2000 Concerto的有机结合,进一步说明Concerto 的特性与构架. 另外还介绍了TI 提 ...… 查看全部问答> |




