STM32的I2C通信实例pcf8591(AD/DA)原创干货_stm32i2c的例程_别把我的消息带回家乡的博客-程序员宅基地

技术标签: stm32  嵌入式  单片机  

 

 

 

本程序是stm32f103 接pcf8591AD/DA板(YL-PCF8591),I2C通信,I2C通信用的是模拟I2C,不是STM32 自带的硬件I2C外设。实践检验很稳定。SCL接口用PB6,SDA用PB7,与STM32自带的硬件I2C接口针脚是一样的,这是巧合,你也可以随便定义成别Pin针脚。关于GPIO设置,最后有解释。

  1. Pcf8591地址写是0x90,读是0x91,
  2. AIN0地址是0x40 -------AIN3地址是0x43,注意AOUT地址也是0x40

写比较简单看下面程序:下面是DA(数/模转换主程序)主要用写函数。

u8 DACconversion(u8 sla,u8 c,  u8 Val)

{

   Start_I2c();              //启动总线

   SendByte(sla);            //发送器件地址

   ack();                      //8591应答

   SendByte(c);              //发送控制字节

    ack();                  //8591应答

   SendByte(Val);            //发送DAC的数值 

    ack();                       //8591应答

   Stop_I2c();               //结束总线

   return(1);

}

启动:SCL高电平中间SDA高变低,紧接着SCL变低,

停止:SCL低电平变高电平后,SDA低变高,

Ack应答是主机释放SDA后,从机(PCF8591把SDA拉低)。

DA转换的过程是,先开始,发送从机地址90,从机应答后,发送寄存器地址,40代表AIN0(AOUT也是40 ),从机应答后,发送写入的数据,从机应答,结束传输。

是不是很简单?DOUT输出电压范围(0-255对应0-3.3v )输出接口接有蓝色LED,输出电压大于2V,LED 开始亮起了,电压越高,越亮。

----------------------------------------------------------------------------------------------/

下面说明读数据程序,稍微复杂一点。

u8 ADCconversion(u8 sla,u8 c)

{

       u8 d;

   Start_I2c();              //启动总线

   SendByte(sla);            //发送器件地址0x90

   ack();                    //从机接收后应达

   SendByte(c);              //发送控制字节0x43

    ack();                   //从机接收后应达

Stop_I2c();               //停止总线

//------------------------------------------------

Start_I2c();              //启动总线

SendByte(sla+1);           //发送读AIN3指令

ack();                    //从机应对不能少

   d=RcvByte();            //发送DAC的数值 

   Ack_I2c(0);             //主机接收后应答不能少否则不稳定

   Stop_I2c();               //结束总线

   return(d);

}

我们读取第4个AIN口因为接有可变电阻,可以直观看到输入数据变化,AIN3地址是0x43(第一个是光敏)(第二个是热敏)(第三个是直通)

下面分析程序,下面是AD转换,接收第四个AIN的电压信号,0-3.3V对应数字0-255:

AD起始的程序和DA相同,开始-发送从站地址90,从站应答,发送控制字43,从站应答,之后的程序就不一样的,停止

再次开始,发送读指令91,从站应答,主机读8位数据,读到后主机应答0,表示接受到,最后停止传输。(注意没有这个主机接收应答,接收到数据就乱了在数据和255之间乱跳)。

可以看到Ad转换开始停止两次。特别注意,主机接收到数据后,主机回复Ack(0)。不是从机。

///------------------------------------------------------------------------------------------------///

最后说一下关于:IIC的GPIO设置。

void GPIO_init(void)

{

      GPIO_InitTypeDef GPIO_InitStructure;

 

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

     

      GPIO_InitStructure.GPIO_Pin = SCL_Pin | SDA_Pin;     /*初始化IO*/

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      

      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

      GPIO_Init(GPIOB, &GPIO_InitStructure);

 

      SCL_SET(1);

      flash();

      SDA_SET(1);

      flash();

}

这是GPIO初始化程序,可见GPIO设置为推挽输出,这样I2C的波形用示波器观察就是正经的方波,但是推挽输出只能写数据,I2C读数据的时候必须用in_floating,见下面:

void SDA_IO_IN(void)

{

      GPIO_InitTypeDef GPIO_InitStructure;

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

      GPIO_InitStructure.GPIO_Pin = SDA_Pin;  /*初始化IO*/

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;      

      GPIO_Init(GPIOB, &GPIO_InitStructure);

}

 

void SDA_IO_OUT(void)

{

      GPIO_InitTypeDef GPIO_InitStructure;

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

      GPIO_InitStructure.GPIO_Pin = SDA_Pin;  /*初始化IO*/

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      

      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

      GPIO_Init(GPIOB, &GPIO_InitStructure);

}

上面程序可见,SCL(PB6)是主机主导,所以一般设为PP不变(推挽输出),SDA因为读到时候是从机发数据,所以对于SDA(PB7)脚,在写数据时候设置成PP(推挽输出),在读入数据时设置成in_floating。这样的波形很漂亮的方波,用示波器观察很爽,逻辑清晰可见。

也有的程序SCL SDA 都设置成OD(开漏输出)不变,这就不用设置变来变去,也是可以的,就是观察波形的时候,波形底部是方波(因为漏极有场效应管通断),波形上部就是三角锯齿波了,(因为没有上场效应管控制,高电位是靠上拉电阻)。这种设置也是可以用,还简单,就是不利于用示波器观察。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41795958/article/details/113472258

智能推荐

python空格怎么表示_关于Python中空格字符串处理的技巧总结-程序员宅基地

前言大家应该都知道字符串处理,是任何语言最常用到的。 其中就经常会碰到,对字符串中的空格处理,比如:去除前后空格,去除全部空格,或者以空格为分隔符来处理。 好在Python中字符串有很多方法,比如lstrip() , rstrip() , strip()来去除字符串前后空格,借助split()对字符来分隔; 实在不行,还可以借助于re模块的sub函数来替换。下面列举下,各种情况下的处理技巧,通..._python表示任意空格

微信登录:【微信登录】签名不对,请检查签名是否与开发平台签名一致。_签名是否与开放平台上填写的一致-程序员宅基地

第一步:打包程序并查看微信开放平台的应用签名是否正确。微信的签名工具:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319167&token=4fc1340a3f09bb43bfbb34c9e2b..._签名是否与开放平台上填写的一致

一键登陆教务系统_如何编写一个程序能够让电脑自己登录教务系统-程序员宅基地

程序说明通过python实现一键登陆教务系统。涉及的库PyInstallerfrom selenium import webdriver函数体def login(url: str, account: list): # 设置参数的类型检查 input_account = [] global brower # 函数体内设置global让charm保持开启状态..._如何编写一个程序能够让电脑自己登录教务系统

霍纳(Horner)规则的两种实现方法_horner点源分析法-程序员宅基地

霍纳(Horner)规则是采用最少的乘法运算策略,求多项式A(x)=anxn+an-1xn-1+...+a1x+a0在x0处的值。该规则为A(x0)=(...((anx0+an-1)x0+...+a1)x0+a0)。利用霍纳规则,编写C语言程序对多项式进行求值。 // 利用递归法求值int Horner_01(int arr[], int n, int x0){ if(_horner点源分析法

oracle查询多个条件查询,Oracle 条件查询 =、IN、LIKE、BETWEEN...AND_徐邦睿的博客-程序员宅基地

Oracle 条件查询Oracle条件查询时经常使用=、IN、LIKE、BETWEEN...AND来作为条件查询的操作符。在Oracle select 查询中where条件经常使用到这几个操作符。下列案例所需表结构参考:学生系统表结构。=操作符在条件查询语句中“=”表示列值等于一个固定值所查询出的结果。案例1、查询学生成绩表“score”中课程id为“R20180101”,成绩为“85”分的同学信..._oracle多条件查询

在Oracle数据库中复制表结构和表数据_oracle复制表结构及数据-程序员宅基地

1. 复制表结构及其数据:create table new_table as select * from old_table2. 只复制表结构:create table new_tableas select * from old_tablewhere 1=2;或者:create table new_table like old_table3. 只复制表数据:如果两个表结..._oracle复制表结构及数据

随便推点

利用Loadrunner+Fiddler抓包的形式录制APP的性能脚本-程序员宅基地

利用Loadrunner+FIddler抓包的形式录制APP的性能脚本最近公司要求做APP的性能测试,尝试网上所有的方法,整崩溃了还是没有有弄好,手机连接代理,但是录制的时候有些接口就是抓不到,流程接口抓不全,导致数据插入不到数据库。后来直接撇开LoadRunner,只对Fiddler做代理抓包,将抓到的包进行分割处理,就成了我们所需要的性能测试脚本,具体操作如下(在做次操作之前,电脑和手机连接同意WiFi,台式电脑可以用无线网卡):1.Fiddler打开代理,填写代理端口,如图所示:Tools——O

vue-swesome-swiper 轮播图点击无效_swesomeswipper-程序员宅基地

原因是开启了(loop:true) 开启loop, 在DOM结构上,swiper是使用的clone的方式,在首尾各添加一个slide单元。但是并没有将click事件clone过去,所以点击事件不会生效,解决方法,在回调添加点击事件,用dataset.index拿到数据;结构//结构<swiper :options="swiperOption" ref="mySwiper" > ..._swesomeswipper

iOS 解决点击手势和tableview的点击冲突_ios collectionview点击事件和手势冲突-程序员宅基地

在开发的时候会遇到一个页面既有点击手势又有tableview,那么这个时候tableview的点击就会被点击手势取代,那么我们应该怎么处理呢?首先我们先添加一个手势:UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(disMissGrantureADD:)]; [tap setNumberOfTapsRequired:1]; tap...._ios collectionview点击事件和手势冲突

MyEclipse2017-ci-10 配置大全-程序员宅基地

------软件下载与破解,请自行百度------下面说常用配置:jdk、tomcat、maven、以及所遇问题解决1.添加jdk流程:2.添加tomcat流程(添加多个tomcat是一样的操作流程):3.tomcat添加项目流程:4.去掉系统自带的tomcat:5.添加maven流程:------ 所遇到问题的解决方案:...

python 自动生成图像_从图像目录自动生成图库:已更新-程序员宅基地

python 自动生成图像Two years ago Chris Coyier wrote an outstanding tutorial detailing how you can generate a photo gallery based on the images within two directories: a thumbnails directory and an original...

VSCode webpack : 无法将“webpack”项识别为 cmdlet...解决方法_webpack-cli 版本不被识别-程序员宅基地

问题:在VSCode下运行webpack命令无效这个问题搞了我几个小时,找了很多博客,全局安装webpack和webpack-cli npm i webpack webpack-cli -g没有用;把node_global加入到环境变量没有用;在package.json中的script进行配置 “build”: “webpack” 或者是"dev":"webpack"没有用;我甚至重启了电脑..._webpack-cli 版本不被识别

推荐文章

热门文章

相关标签