stm32 hal i2c 库读写sd3088时钟
2016-03-06 19:57
453 查看
前一版本的修正。
sd3008在每次通信开始0.5s做一次总线复位,不必考虑stm32的i2c Bug问题。
而且HAL库,是不是也应考虑到软件上补充这个Bug?
使用HAL_I2C_Mem_Read/Write,使得代码非常好看。模拟I2C方式,一字长蛇阵模样。
使用Freertos,读取时间、保存数据到用户SRAM,需要考虑Mutex对RTC时钟资源进行保护。
sd3008在每次通信开始0.5s做一次总线复位,不必考虑stm32的i2c Bug问题。
而且HAL库,是不是也应考虑到软件上补充这个Bug?
使用HAL_I2C_Mem_Read/Write,使得代码非常好看。模拟I2C方式,一字长蛇阵模样。
使用Freertos,读取时间、保存数据到用户SRAM,需要考虑Mutex对RTC时钟资源进行保护。
* SD3088时钟芯片 读写 * 文件 sd3088.h * http://git.oschina.net/maizhi/small-pellet-sove-control-system *作者 于 *版本 v1.1 */ #include "sd3088.h" #if DEBUG #include "stdio.h" #endif extern I2C_HandleTypeDef hi2c1; RTC_Time Time_sd3088 = {0x55, 0x59, 0x14, 0x01, 0x12, 0x11, 0x14}; //初始化时间结构体变量(设置时间:2014年11月12日 14:59:55 星期一) uint8_t rtc_data[7]; //通用数据缓存器 /* 读取时间 */ uint8_t read_rtc(void) { uint8_t battery[2]; if(HAL_I2C_Mem_Read(&hi2c1, RTC_ADDR_READ, 0x0, 1, &rtc_data[0], 7, 1) == HAL_OK) { Time_sd3088.second = BCD2DEC(rtc_data[0] & 0x7f); Time_sd3088.minute = BCD2DEC(rtc_data[1] & 0x7f); Time_sd3088.hour = BCD2DEC(rtc_data[2] & 0x1f); Time_sd3088.week = BCD2DEC(rtc_data[3] & 0x07); Time_sd3088.day = BCD2DEC(rtc_data[4] & 0x3f); Time_sd3088.month = BCD2DEC(rtc_data[5] & 0x1f); Time_sd3088.year = BCD2DEC(rtc_data[6]); } // 电量 0x1a 0x1b if(HAL_I2C_Mem_Read(&hi2c1, RTC_ADDR_READ, 0x1a, 1, battery, 2, 1) == HAL_OK) { Time_sd3088.quantity = (battery[0] >> 7) * 255 + battery[1]; printf("quality:%x\r\n",Time_sd3088.quantity); } return 0; } /* 允许写 */ bool enable_write(void) { bool result = false; uint8_t wcr = 0x80; // 写 0x10 if(HAL_I2C_Mem_Write(&hi2c1, RTC_ADDR_WRITE, 0x10, 1, &wcr, 1, 1) == HAL_OK) { // 写 0x0f wcr = 0xff; if(HAL_I2C_Mem_Write(&hi2c1, RTC_ADDR_WRITE, 0x0f, 1, &wcr, 1, 1) == HAL_OK) result = true; } return result; } /* 禁止写 */ bool disable_write(void) { bool result = false; uint8_t wcr = 0x7b; // 写 0x0f if(HAL_I2C_Mem_Write(&hi2c1, RTC_ADDR_WRITE, 0x0f, 1, &wcr, 1, 1) == HAL_OK) { // 写 0x10 wcr = 0x0; if(HAL_I2C_Mem_Write(&hi2c1, RTC_ADDR_WRITE, 0x10, 1, &wcr, 1, 1) == HAL_OK) result = true; } return result; } /* 保存时间 */ void write_rtc(RTC_Time *t) { // 计算星期 uint8_t y, m , d; y = t->year + 2000; m = t->month; d = t->day; if (m ==1 || m ==2) { m += 12; //把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算 y--; } // 使用基姆拉尔森公式计算星期 uint8_t week = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7; uint8_t data[7]; data[0] = 0; data[1] = DEC2BCD(t->minute); data[2] = DEC2BCD(t->hour); data[3] = week; data[4] = DEC2BCD(t->day); data[5] = DEC2BCD(t->month); data[6] = DEC2BCD(t->year); if (enable_write()) { // 写时间数据 if(HAL_I2C_Mem_Write(&hi2c1, RTC_ADDR_WRITE, 0x0, 1, &data[0], 7, 1) == HAL_OK) { printf("saved time successful.\r\n"); } else printf("saved time failure.\r\n"); disable_write(); } } /* 保存数据到RTC */ bool save_to_rtc(uint16_t address, uint8_t *data, uint16_t len) { bool result = false; if (address < 0x2c || address > 0x71 || len > 70) return false; if (enable_write()) { if (HAL_I2C_Mem_Write(&hi2c1, RTC_ADDR_WRITE, address, 1, data, len, 1) == HAL_OK) { result = true; } disable_write(); } // 读回做检验? return result; } /* 读取数据从RTC */ bool read_from_rtc(uint16_t address, uint8_t *data, uint16_t len) { bool result = false; if (address < 0x2c || address > 0x71 || len > 70) return false; // 读回 if(HAL_I2C_Mem_Write(&hi2c1, RTC_ADDR_WRITE, address, 1, data, len, 1) == HAL_OK) { } return result; }
相关文章推荐
- 软件测试 homework2
- 多分类问题中,实现不同分类区域颜色填充的MATLAB代码(demo:Random Forest)
- hbase 读写过程
- asp.net 通过web.config 文件设置网站的mime类型
- 买了个新键盘,雷柏V56,也没有个说明书,只好自己写个了。
- bash特性
- BZOJ3038上帝造题的七分钟2
- 关于网络请求返回数据是nil的情况
- web前端—沉静、务实
- 查找算法7
- 雪花飘落 - 定时器(NSTimer/CADisplayLink)
- Linux内核分析实验二:mykernel实验指导(操作系统是如何工作的)
- 抓取网页数据C#文件
- ant学习-使用ant生成jar包
- 构建之法阅读问题
- 九度-简单题 题目1065:输出梯形
- HUST 1603 Deadly Disease
- 设计模式之装饰模式
- TableView的cell返回nil问题
- 选择排序