您的位置:首页 > 财经 > 金融 > 广告创意设计论文_陈铭生缉毒警察怎么牺牲的_什么是seo如何进行seo_seo网站优化服务

广告创意设计论文_陈铭生缉毒警察怎么牺牲的_什么是seo如何进行seo_seo网站优化服务

2024/11/17 4:56:35 来源:https://blog.csdn.net/weixin_56905687/article/details/142975148  浏览:    关键词:广告创意设计论文_陈铭生缉毒警察怎么牺牲的_什么是seo如何进行seo_seo网站优化服务
广告创意设计论文_陈铭生缉毒警察怎么牺牲的_什么是seo如何进行seo_seo网站优化服务

一、I2C基础知识

1、I2C 使用两条线在主控制器和从机之间进行数据通信。一条是 SCL(串行时钟线),另外一条是 SDA(串行数据线)。

2、I2C 是支持多从机的,也就是一个 I2C 控制器下可以挂多个 I2C 从设备,这些不同的 I2C从设备有不同的器件地址。

3、I2C时序相关

①起始位:通信起始标志,SCL 为高电平的时候,SDA 出现下降沿就表示为起始位。

②停止位:停止 I2C 通信的标志位,SCL 位高电平的时候,SDA出现上升沿就表示为停止位。

③数据传输:数据传输时,要保证SCL在高电平期间,SDA 上的数据变化只能在 SCL 低电平期间发生。

④应答信号:当 I2C 主机发送完 8 位数据以后会将 SDA 设置为输入状态,等待 I2C 从机应答,也就是等待 I2C 从机告诉主机它接收到数据了。应答信号是由从机发出的,主机需要提供应答信号所
需的时钟,主机发送完 8 位数据以后紧跟着的一个时钟信号就是给应答信号使用的。从机通过将SDA 拉低来表示发出应答信号,表示通信成功,否则表示通信失败。

主机通过 I2C 总线与从机之间进行通信包括两个操作:写和读。

二、I2C设备驱动编写

在ST提供的源码中,内核源码 arch/arm/boot/dts/stm32mp151.dtsi 设备树文件中找到
STM32MP1 的 I2C 控制器节点。已经提供了I2C适配器驱动程序。

1、若不使用设备树

在未使用设备树的时候需要在 BSP 里面使用 i2c_board_info 结构体来描述一个具体的 I2C 设备

struct i2c_board_info {char type[I2C_NAME_SIZE];//设置I2C设备名字unsigned short flags;unsigned short addr; //设置I2C设备地址const char *dev_name;void    *platform_data;struct device_node *of_node;struct fwnode_handle *fwnode;const struct property_entry *properties;const struct resource *resources;unsigned int num_resources;int irq;
};

2、使用设备树

使用设备树的时候 I2C 设备信息通过创建相应的节点就行了

例如,使用I2C5挂载一个传感器

&i2c5 {pinctrl-names = "default", "sleep";pinctrl-0 = <&i2c5_pins_a>;pinctrl-1 = <&i2c5_pins_sleep_a>;status = "okay";ap3216c@1e {compatible = " alientek,xxx";reg = <0x1e>;};};

修改设备树,打开 stm32mp15-pinctrl.dtsi

找到如下内容:

i2c5_pins_a: i2c5-0 {pins {pinmux = <STM32_PINMUX('A', 11, AF4)>, /* I2C5_SCL */<STM32_PINMUX('A', 12, AF4)>; /* I2C5_SDA */bias-disable;drive-open-drain;slew-rate = <0>;};};i2c5_pins_sleep_a: i2c5-1 {pins {pinmux = <STM32_PINMUX('A', 11, ANALOG)>, /* I2C5_SCL */<STM32_PINMUX('A', 12, ANALOG)>; /* I2C5_SDA */};};

定义了 I2C5 接口的两个 pinmux 配置分别为:i2c5_pins_a 和i2c5_pins_sleep_a。第一个默认的状态下使用,第二个是在 sleep 状态下使用。

打开 stm32mp157d-atk.dts 文件,向 i2c5 节点中添加“ap3216c@1e”子节点,

&i2c5 {pinctrl-names = "default", "sleep";pinctrl-0 = <&i2c5_pins_a>;pinctrl-1 = <&i2c5_pins_sleep_a>;status = "okay";ap3216c@1e { //le是ap3216c的器件地址compatible = "alientek,ap3216c";reg = <0x1e>;//reg 属性也是设置 ap3216c 器件地址的,因此 reg 设置为 0x1e。};};

修改完成后,使用make dtbs编译一下,编译完成后,会在/sys/bus/i2c/devices 目录下看到一个名为“0-001e”的子目录,进入0-001e 目录,可以看到“name”文件,name 文件保存着此设备名字。

最后,编写驱动程序。

//①定义结构体,包括设备,设备号,设备节点等
//②从设备读取多个寄存器数据
//③向多个寄存器写入数据
//④读取指定寄存器值,读取一个寄存器
//⑤指定寄存器写入指定的值,写一个寄存器
//⑥读取数据
void ap3216c_readdata(struct ap3216c_dev *dev){unsigned char i =0;unsigned char buf[6];/* 循环读取所有传感器数据 */for(i = 0; i < 6; i++) {buf[i] = ap3216c_read_reg(dev, AP3216C_IRDATALOW + i);}if(buf[0] & 0X80) /* IR_OF 位为 1,则数据无效 */dev->ir = 0;else/* 读取 IR 传感器的数据 */dev->ir = ((unsigned short)buf[1] << 2) | (buf[0] & 0X03);dev->als = ((unsigned short)buf[3] << 8) | buf[2];if(buf[4] & 0x40) /* IR_OF 位为 1,则数据无效 */dev->ps = 0;else/* 读取 PS 传感器的数据 */dev->ps = ((unsigned short)(buf[5] & 0X3F) << 4) | (buf[4] &0X0F);}
//从设备读取数据
static ssize_t ap3216c_read(struct file *filp, char __user *buf,
size_t cnt, loff_t *off){short data[3];long err = 0;struct cdev *cdev = filp->f_path.dentry->d_inode->i_cdev;struct ap3216c_dev *dev = container_of(cdev, struct ap3216c_dev,cdev);ap3216c_readdata(dev);data[0] = dev->ir;data[1] = dev->als;data[2] = dev->ps;err = copy_to_user(buf, data, sizeof(data));return 0;}
//关闭/释放设备
//写i2c 驱动的 probe 函数,当驱动与设备匹配以后此函数就会执行
//i2c 驱动的 remove 函数,移除 i2c 驱动的时候此函数会执行
//驱动入口和出口函数
/* module_i2c_driver(ap3216c_driver) */module_init(ap3216c_init);module_exit(ap3216c_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("ALIENTEK");MODULE_INFO(intree, "Y");

 编写测试程序,

编译出来拷贝到对应的目录中,重启开发板,加载驱动模块,看读取的数据变化。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com