本程序是stm32f103 接pcf8591AD/DA板(YL-PCF8591),I2C通信,I2C通信用的是模拟I2C,不是STM32 自带的硬件I2C外设。实践检验很稳定。SCL接口用PB6,SDA用PB7,与STM32自带的硬件I2C接口针脚是一样的,这是巧合,你也可以随便定义成别Pin针脚。关于GPIO设置,最后有解释。
写比较简单看下面程序:下面是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(开漏输出)不变,这就不用设置变来变去,也是可以的,就是观察波形的时候,波形底部是方波(因为漏极有场效应管通断),波形上部就是三角锯齿波了,(因为没有上场效应管控制,高电位是靠上拉电阻)。这种设置也是可以用,还简单,就是不利于用示波器观察。
前言大家应该都知道字符串处理,是任何语言最常用到的。 其中就经常会碰到,对字符串中的空格处理,比如:去除前后空格,去除全部空格,或者以空格为分隔符来处理。 好在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)规则是采用最少的乘法运算策略,求多项式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 select 查询中where条件经常使用到这几个操作符。下列案例所需表结构参考:学生系统表结构。=操作符在条件查询语句中“=”表示列值等于一个固定值所查询出的结果。案例1、查询学生成绩表“score”中课程id为“R20180101”,成绩为“85”分的同学信..._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的性能脚本最近公司要求做APP的性能测试,尝试网上所有的方法,整崩溃了还是没有有弄好,手机连接代理,但是录制的时候有些接口就是抓不到,流程接口抓不全,导致数据插入不到数据库。后来直接撇开LoadRunner,只对Fiddler做代理抓包,将抓到的包进行分割处理,就成了我们所需要的性能测试脚本,具体操作如下(在做次操作之前,电脑和手机连接同意WiFi,台式电脑可以用无线网卡):1.Fiddler打开代理,填写代理端口,如图所示:Tools——O
原因是开启了(loop:true) 开启loop, 在DOM结构上,swiper是使用的clone的方式,在首尾各添加一个slide单元。但是并没有将click事件clone过去,所以点击事件不会生效,解决方法,在回调添加点击事件,用dataset.index拿到数据;结构//结构<swiper :options="swiperOption" ref="mySwiper" > ..._swesomeswipper
在开发的时候会遇到一个页面既有点击手势又有tableview,那么这个时候tableview的点击就会被点击手势取代,那么我们应该怎么处理呢?首先我们先添加一个手势:UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(disMissGrantureADD:)]; [tap setNumberOfTapsRequired:1]; tap...._ios collectionview点击事件和手势冲突
------软件下载与破解,请自行百度------下面说常用配置:jdk、tomcat、maven、以及所遇问题解决1.添加jdk流程:2.添加tomcat流程(添加多个tomcat是一样的操作流程):3.tomcat添加项目流程:4.去掉系统自带的tomcat:5.添加maven流程:------ 所遇到问题的解决方案:...
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和webpack-cli npm i webpack webpack-cli -g没有用;把node_global加入到环境变量没有用;在package.json中的script进行配置 “build”: “webpack” 或者是"dev":"webpack"没有用;我甚至重启了电脑..._webpack-cli 版本不被识别