个人成就
- 发布了50篇内容
- 获得了4次赞同
- 获得了3次收藏
个人简介
擅长领域
暂时没有设置哦~
-
红外遥控原来这么简单!
大家好!我是张飞实战电子蔡琰老师!今天给大家分享红外遥控接收。
平时我们经常会用到遥控器,那么现在遥控器也分很多种类,有使用红外通信的,也有使用蓝牙,无线的等,今天我们来一起解码一下红外的工作原理。
大家看现在图中的是2个红外对管,左边是发射端,右边是接收端,
遥控器上有一个红外发射二极管,发射红外数据信息,电视机上有一个红外接收管,接收红外信息,那么到底是怎么把数据从二极管中发送出去的呢?
如上图,遥控器发送之前要先进行编码调制,然后进行信号放大发射,接收设备需要先对这个信号进行解调,解调之后的信号送给单片机,单片机进行解码(分析是什么数据)。
调制过程就是需要加上载波信号,中间加载了一个载波信号,发送的数据就是通过载波信号送出去的,对应的接收信号就需要对收到的载波信号进行解调处理了,即信号还原。
一般情况下接收头,只能解调固定的一种载波频率信号,那遥控器的发送信号的载波频率要与接收头所用的频率一致,否则是没办法正确接收的。自然界中存在红外光,进行调制主要是为了避免一些干扰,以防止传输出错。下面我们一起来看看遥控器传输的协议编码规则。
遥控器信号开始的地方有一段特殊长度的信号,这个我们叫它是引导码,引导码是9ms高电平+4.5ms的低电平,单片机只有结束到了正确的引导码,才可以开始接收后续的数据。
我们知道有效数据要么是0,要么是1,0或者1都是由一个固定的高电平+低电平组成,数据1: 0.56ms高电平+1.69ms低电平组成,数据0: 0.56ms高电平+0.56ms低电平组成,也就是说收到这样的一个高电平+低电平的数据就是认为收到有效数据了,再根据判断时间来区分是0还是1。通过分析出来0 1,再把这些0 1组合成一个有用的数据,然后进行处理执行动作,比如切换频道,关机、开机等。这样就是一个完成的遥控器发送,接收原理了。
上图是我们实测的一个遥控器解调后的波形中,你能分析出图中传输的数据吗?
-
你知道I2C为什么要接上拉吗?
实际工程项目中,有很多地方都会用到I2C总线通信,比如说24C02存储、传感器接口等,能使用I2C这项技能,就成为了我们工程师日常必备的武器,那么我们就来详细的说说I2C。
I2C是一种简单的双向二线制同步串行总线。只需要两根线即可在连接于总线上的器件之间传送信息,一根SCL时钟线,一根就是SDA数据。需要注意的是SDA它是一个双向传输的线,主机向从机发送信号通过SDA把数据送出去,从机向主机发送信号也是从SDA线把数据送出来。
I2C也可以一个一,也可以一对多,每个连接到总线的外围设备都有一个独立的地址,主机可以通过该地址来访问不同设备。主机可通过SDA线发送设备地址查找从机。
因为I2C 通信IO口输出结构都是配置为漏极开路或集电极开路输出。所以时钟线和数据线必须外部都接上拉电阻,当一对多输出的时候,很多GPIO口会连接在同一根线上,可能会存在某个GPIO输出高电平,另一个GPIO输出低电平的情况。如果使用推挽输出,你会发现这个GPIO的VCC和另一个GPIO的GND接在了一起,也就是短路了。如果换成开漏输出VCC和GND之间多了个电阻,这样电路就是安全的。上拉电阻一般取值在1K-10K之间,上拉电阻的取值和通信速率会有一定的关系,如果上拉电阻的取值太大,那么信号的上升沿、下降沿就会很缓,会影响通信速率,这个具体的看应用的通信速率去测试波形,如果取的太小了,功耗很大,取的太大了,信号的上升沿就会慢,影响通信速率(如下图的1 2表示)。
一般情况下I2C标准模式最高传输速率100Kbit/s,高速模式最高传输速率400Kbit,当然也有用软件模拟I2C的时序来进行通信的,这个速率就需要自己去掌控测试了,说白了就是我们对着时序图,抄一个同样的波形出来。只要遵守同样的约定,按照时序图对应管脚拉高拉低就可以读写数据了。
在标准协议中区分启动、停止、应答、等动作,下面我们来一起学习一下I2C的标准协议。
当检测到SDA线上为下降沿,SLC线上为高电平,就表示收到了启动信号,当检测到SDA线上为上升沿,SLC线上为高电平,就表示收到了停止信号。
收到启动信号之后就可以开始数据传输,收到停止信号表示帧数据传输完毕。在传输过程中,时钟线SCL为高电平的时候,数据线SDA必须保持稳定,不能改变电平状态,这样才能有效传输,在时钟线SCL为低电平的时候,数据线SDA可以改变状态,即:在SCL为高电平的时候,数据线SDA如果为高,那么传送的就是1,如果SDA为低,那么传送的就是0,在SCL为低电平的时候,你可以改变数据可以把数据变为0/1(图中红框交叉就表示数据的改变,从1变为0 从0变为1所以有了一个上升沿或者一个下降沿)。
在SCL的第9个时钟位,对应的SDA数据为应答数据,应答数据是有方向的,可以是主设备应答,可以是从设备应答,应答不是固定的,可以是低电平为应答,也可以是高电平应答,高应答或者低应答是由通信协议决定的,只要约定一个信号作为应答就可以了,主机给从机发送数据,从机接到了应答主机,从机给主机发送数据,主机接到了,主机就要应答,这样就形成了一个闭环。以上就是一个标准的IIC通信标准规范,你清楚了吗?
-
MDK中Buil/ReBuild背后你不知道的故事
在程序开发过程中,大家都会去点击编译按钮,直接开始仿真调试,基本上不怎么关注编译和链接的过程,因为我们使用的工具一般都是厂家做好的集成开发环境(IDE),比如MDK、IAR等。IDE通常将编译和链接合并到一起,虽然 IDE 提供的默认配置、编译和链接参数对于大部分应用程序来说已经足够使用了,但是作为学习,我们可以弄清楚从源代码生成可执行文件的原理。
事实上,从源代码生成可执行文件可以分为四个步骤,分别是预处理(Preprocessing)、编译(Compilation)、汇编(Assembly)和链接(Linking)。下图是生成可执行文件的过程:预处理(Preprocessing)过程主要是处理程序中以#开头的命令,比如 #include、#define等。预处理的规则一般如下:
1.将程序中所有的#define宏定义进行替换。
2.处理程序中所有条件编译命令,比如 #if、#ifdef、#elif、#else、#endif 等。
3.处理#include命令,会将被包含的头文件的内容插入到该预处理命令所在的位置,需要注意的是,这个过程是递归进行的,也就是说被包含的头文件中还可能会包含其他的头文件。
4.删除程序中的注释。
5.添加行号和文件名标识,便于在调试和出错时给出具体的代码位置。
6.保留程序中的#pragma命令,因为编译器需要使用它们。
预处理的结果是生成.i文件。.i文件也包含C语言代码的源文件,只不过所有的宏已经被展开,所有包含的文件已经被插入到当前文件中。当你无法判断宏定义是否正确,或者文件包含是否有效时,可以查看.i文件来确定问题。
编译(Compilation)就是把预处理完的文件进行一些列的词法分析、语法分析、语义分析以及优化后生成相应的汇编代码文件(.txt文件)。编译是整个程序构建的核心部分,也是最复杂的部分之一,涉及到的算法较多。在MDK中可以按照以下步骤生产预处理文件和编译文件。勾选之后,再重新Build或者ReBuild就可以了。
汇编(Assembly)的过程就是将上一步生成的汇编指令转换成可以执行的机器指令。汇编过程相对于编译来说比较简单,只是根据汇编语句和机器指令的对照表翻译就可以了。汇编的结果是产生目标文件,即为.o文件。
目标文件已经是二进制文件,与可执行文件的形式类似,只是有些函数和全局变量都是分散的,地址还没有找到,程序不能执行。链接(Linking)的作用就是找到这些目标地址,将所有的目标文件组织成一个可以执行的二进制文件。
以上就是你点击了MDK中的Buil/ReBuild之后,被雪藏的背后的过程,你清楚了吗? -
常见的内存错误及对策
对于用C或C++除了考虑上层应用,还需要考虑底层的内存管理,或者说内存泄漏的问题。
1、指针没有指向一块合法的内存
定义了指针变量,但是没有为指针分配内存,即指针没有指向一块合法的内存。
①结构体成员指针未初始化
定义一个结构体变量,但是结构体内部定义了指针成员,往往应用结构体变量的时候如果不给这 个成员指向一个合法的地址只是给成员分配了字节数,应用的时候对应内存的区域指针成员是无权 访问的,所以需要对结构体分配内存,结构体成员中指针变量也要分配内存,否则访问不到有效地 址。
②没有为结构体指针分配足够的内存
分配内存的时候,分配的内存大小不合适,比如开辟内存空间时sizeof(struct stu)误写为sizeof(struct stu *),书写错误会导致开辟空间不正确。
③函数的入口校验
不管什么时候,我们使用指针之前一定要确保指针是有效的。一般在函数入口处使用 assert (NULL !=p)对参数进行校验。在非参数的地方使用if(NULL != p)来校验。但这都有一个要求,也就 是p在定义的同时被初始化为NULL,如果没有被初始化为NULL,那么校验也起不了作用,没有被 初始化的指针变量,内部是一个非NULL的乱码
assert是一个宏,而不是函数,包含在assert.h头文件中。如果其后面括号里的值为假,则程序终 止运行,并提示出错;如果后面括号里的值为真,则继续运行后面的代码。
2、为指针分配的内存太小或内存访问越界
为指针分配了内存,但是内存大小不够,导致出现越界错误。
通常这种问题都会出现在我们容易忽略的字符串常量中,往往会忘记结束标志“