完全OK.
将ds3231封装成一个字符设备
实现了读写功能,其他的暂时用不到就没写了。初始化的时候写入一个设定值,然后读取年月日时分秒打印出来。
#include "app_ds3231.h"
#define DS3231_I2C_BUS_NAME "i2c1" /* 传感器连接的I2C总线设备名称 */
static struct rt_i2c_bus_device *i2c_bus = RT_NULL; /* I2C总线设备句柄 */
static rt_bool_t initialized = RT_FALSE; /* 传感器初始化状态 */
static uint8_t BCD2HEX(uint8_t val)
{
uint8_t temp;
temp=val&0x0f;
val>>=4;
val&=0x0f;
val*=10;
temp+=val;
return temp;
}
static uint8_t HEX2BCD(uint8_t val)
{
uint8_t i,j,k;
i=val/10;
j=val%10;
k=j+(i<<4);
return k;
}
/**设备结构体 */
struct ds3231_device
{
struct rt_device parent;
struct rt_i2c_bus_device *bus;
};
/* RT-Thread device interface */
static rt_err_t ds3231_init(rt_device_t dev)
{
return RT_EOK;
}
static rt_err_t ds3231_open(rt_device_t dev, rt_uint16_t oflag)
{
return RT_EOK;
}
static rt_err_t ds3231_close(rt_device_t dev)
{
return RT_EOK;
}
static rt_err_t ds3231_control(rt_device_t dev, int cmd, void *args)
{
return RT_EOK;
}
static rt_size_t ds3231_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
rt_err_t ret=RT_EOK;
struct ds3231_device *ds3231;
struct rt_i2c_msg msgs[2];
rt_uint8_t mem_addr[2] = {0,0};
RT_ASSERT(dev != 0);
ds3231 = (struct ds3231_device *) dev;
/*写入寻址地址*/
msgs[0].addr = DS3231_Address;
msgs[0].flags = RT_I2C_WR;
mem_addr[0] = (rt_uint8_t) pos;
msgs[0].buf = (rt_uint8_t *) mem_addr;
msgs[0].len = 1;
msgs[1].addr = DS3231_Address;
msgs[1].flags = RT_I2C_RD;
msgs[1].buf = (rt_uint8_t *)buffer;
msgs[1].len = 1;
/* 调用I2C设备接口传输数据 */
ret=rt_i2c_transfer(ds3231->bus, msgs, 2);
// rt_kprintf("ret=%d.n",ret);
*(uint8_t *)(buffer)=BCD2HEX( *(uint8_t *)(buffer) );
return (ret == 2) ? size : 0;
}
static rt_size_t ds3231_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
rt_err_t ret=RT_EOK;
struct ds3231_device *ds3231;
struct rt_i2c_msg msgs[2];
rt_uint8_t mem_addr[2] = {0,0};
rt_uint8_t value=HEX2BCD(*(uint8_t *)(buffer));
RT_ASSERT(dev != 0);
ds3231 = (struct ds3231_device *) dev;
/*写入寻址地址*/
msgs[0].addr = DS3231_Address;
msgs[0].flags = RT_I2C_WR;
mem_addr[0] = (rt_uint8_t) pos;
msgs[0].buf = (rt_uint8_t *) mem_addr;
msgs[0].len = 1;
msgs[1].addr = DS3231_Address;
msgs[1].flags = RT_I2C_WR | RT_I2C_NO_START;
msgs[1].buf = &value;
msgs[1].len = 1;
/* 调用I2C设备接口传输数据 */
ret=rt_i2c_transfer(ds3231->bus, msgs, 2);
// rt_kprintf("ret=%d.n",ret);
return (ret == 2) ? size : 0;
}
#ifdef RT_USING_DEVICE_OPS
/** at24cxx设备操作ops */
const static struct rt_device_ops ds3231_ops =
{
ds3231_init,
ds3231_open,
ds3231_close,
ds3231_read,
ds3231_write,
ds3231_control
};
#endif
/**
*
@Brief ds3231设备注册
* @param[in] *fm_device_name 设备名称
* @param[in] *i2c_bus i2c总线设备名称
* @param[in] *user_data 用户数据
*
@Return 函数执行结果
* - RT_EOK 执行成功
* - Others 失败
*/
rt_err_t ds3231_register(const char *fm_device_name, const char *i2c_bus/*, void *user_data*/)
{
static struct ds3231_device ds3231_drv;
struct rt_i2c_bus_device *bus;
bus = rt_i2c_bus_device_find(i2c_bus);
if (bus == RT_NULL)
{
return RT_ENOSYS;
}
ds3231_drv.bus = bus;
ds3231_drv.parent.type = RT_Device_Class_Char;
#ifdef RT_USING_DEVICE_OPS
at24cxx_drv.parent.ops = &ds3231_ops;
#else
ds3231_drv.parent.init = ds3231_init;
ds3231_drv.parent.open = ds3231_open;
ds3231_drv.parent.close = ds3231_close;
ds3231_drv.parent.read = ds3231_read;
ds3231_drv.parent.write = ds3231_write;
ds3231_drv.parent.control = ds3231_control;
#endif
// ds3231_drv.parent.user_data = user_data;
return rt_device_register(&ds3231_drv.parent, fm_device_name, RT_DEVICE_FLAG_RDWR);
}
static rt_device_t ds3231_dev;
static void rt_ds3231_init(const char *name)
{
rt_err_t ret;
/* 查找I2C总线设备,获取I2C总线设备句柄 */
i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(name);
ret = ds3231_register("ds3231", "i2c1");
if(RT_EOK!=ret)
{
rt_kprintf("ds3231 regist failed!n", "ds3231");
return;
}
ds3231_dev = rt_device_find("ds3231");
if (ds3231_dev == RT_NULL)
{
rt_kprintf("ds3231 run failed! can't find %s device!n", "ds3231");
return;
}
rt_device_open(ds3231_dev, RT_DEVICE_FLAG_RDWR);
if (i2c_bus == RT_NULL)
{
rt_kprintf("can't find %s device!n", name);
}
else
{
initialized = RT_TRUE;
rt_device_open(ds3231_dev, RT_DEVICE_FLAG_RDWR);
}
}
static void ds3231_sample(int argc, char *argv[])
{
// float humidity, temperature;
char name[RT_NAME_MAX];
uint8_t date[6]={0,0,0,0,0,0};
const uint8_t date_set[6]={20,3,25,11,38,0};//2020年3月25日11时38分0秒
// humidity = 0.0;
// temperature = 0.0;
if (argc == 2)
{
rt_strncpy(name, argv[1], RT_NAME_MAX);
}
else
{
rt_strncpy(name, DS3231_I2C_BUS_NAME, RT_NAME_MAX);
}
if (!initialized)
{
/* 传感器初始化 */
rt_ds3231_init(name);
rt_device_write(ds3231_dev, DS3231_YEAR, date_set, 1);
rt_device_write(ds3231_dev, DS3231_MONTH, date_set+1, 1);
rt_device_write(ds3231_dev, DS3231_DAY, date_set+2, 1);
rt_device_write(ds3231_dev, DS3231_HOUR, date_set+3, 1);
rt_device_write(ds3231_dev, DS3231_MINUTE, date_set+4, 1);
rt_device_write(ds3231_dev, DS3231_SECOND, date_set+5, 1);
}
if (initialized)
{
/* 读取温湿度数据 */
// DS3231ReadTime();
rt_device_read(ds3231_dev, DS3231_YEAR, date, 1);
rt_device_read(ds3231_dev, DS3231_MONTH, date+1, 1);
rt_device_read(ds3231_dev, DS3231_DAY, date+2, 1);
rt_device_read(ds3231_dev, DS3231_HOUR, date+3, 1);
rt_device_read(ds3231_dev, DS3231_MINUTE, date+4, 1);
rt_device_read(ds3231_dev, DS3231_SECOND, date+5, 1);
rt_kprintf("20%d-%d-%d %d:%d:%d.n", (int)date[0],(int)date[1],(int)date[2],(int)date[3],(int)date[4],(int)date[5]);
}
else
{
rt_kprintf("initialize sensor failed!n");
}
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(ds3231_sample, ds3231 sample);
控制台调用结果: