![](https://img-blog.csdnimg.cn/20201014180756913.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
嵌入式软件设计
文章平均质量分 79
偏执灬
原创博客虽有所摘录,但都是从零开始的自学笔记,有事请联系邮箱,824229769@qq.com
展开
-
蓝牙无线测试相关参数与方法
原文链接:https://www.21ic.com/app/test/201808/788512.htm蓝牙无线测试配置包括一台测试仪和被测设备(EUT, Equipment Under Test),其中测试仪作为主单元,EUT作为从单元。两者之间可以通过射频电缆相连也可以通过天线经空中传输相连。测试仪发送LMP指令,激活EUT进入测试模式,并对测试仪与EUT之间的蓝牙链路的一些参数进行配置。如测试方式是环回还是发送方式,是否需要进行跳频,分组是单时隙分组还是多时隙分组,分组的净菏是PN9,还是0000转载 2020-06-10 15:20:04 · 2962 阅读 · 0 评论 -
关于MCU低功耗的调试注意事项
第一条:掐断外设命脉——关闭外设时钟 先说最直观的,也是工程师都比较注意的方面,就是关闭MCU的外设时钟,对于现在市面上出现的大多数的MCU,其外设模块都对应着一个时钟开关。只需要打开这个外设的时钟,就可以正常的使用这个外设了,当然,此外设也就会产生相应的功耗;反之,如果想要让这个外设不产生功耗,只需关闭它的时钟即可。 第二条:让工作节奏慢下来——时钟不要倍频 除了外转载 2017-10-10 11:14:57 · 5385 阅读 · 1 评论 -
嵌入式系统编程风格的建立与学习
1.1 文件组织 一般在设计时就确定了系统的模块,并注重确定每个模块的接口部分,每个模块 我们用两个文件编写:.H和.C。 .H是模块的接口部分,只允许放置: 1)本模块公开的函数声明; 2)本模块公开的全局变量声明; 3)本模块公开的数据结构定义(即别的模块可能用到的struct); 4)本模块公开的宏定义;在其他模块中可能要引用的宏,如CHANNLE_原创 2016-12-30 18:27:03 · 586 阅读 · 0 评论 -
小小的void蕴藏着很丰富的设计哲学
void的含义void即“无类型”,void *则为“无类型指针”,可以指向任何数据类型。void指针使用规范①void指针可以指向任意类型的数据,亦即可用任意数据类型的指针对void指针赋值。例如:int * pint;void *pvoid;pvoid = pint; /* 不过不能 pint= pvoid; */如果要将pvoid赋给其他类型指针,转载 2017-08-04 22:18:23 · 373 阅读 · 0 评论 -
状态机思路在嵌入式程序设计中的应用
状态机的概念状态机是软件编程中的一个重要概念。比这个概念更重要的是对它的灵活应用。在一个思路清晰而且高效的程序中,必然有状态机的身影浮现。比如说一个按键命令解析程序,就可以被看做状态机:本来在A状态下,触发一个按键后切换到了B状态;再触发另一个键后切换到C状态,或者返回到A状态。这就是最简单的按键状态机例子。实际的按键解析程序会比这更复杂些,但这不影响我们对状态机的认识。转载 2017-08-17 23:16:44 · 1898 阅读 · 1 评论 -
STM32学习笔记之-串口中断接收不定数据buff
今天说一下STM32单片机的接收不定长度字节数据的方法。由于STM32单片机带IDLE中断,所以利用这个中断,可以接收不定长字节的数据,由于STM32属于ARM单片机,所以这篇文章的方法也适合其他的ARM单片机。IDLE中断什么时候发生?IDLE就是串口收到一帧数据后,发生的中断。什么是一帧数据呢?比如说给单片机一次发来1个字节,或者一次发来8个字节,这些一次发来的数据,就称为一帧数据,也转载 2017-08-02 22:16:20 · 11069 阅读 · 3 评论 -
关于如何写一个数据协议(草稿)
//定义协议结构体/******************* Macro defination *************************************/#define L1_HEADER_MAGIC (0xAB) /*header magic number */#define L1_HEADER_SIZE (3) /*L1 header le原创 2017-07-30 12:13:00 · 937 阅读 · 0 评论 -
NXP QN902X蓝牙QPPS 流程的理解
首先烧录程序,完成后用light blue查看服务。在profile中只有一个服务,UUID为128位的UUID,但是可以转换为16位UUID:FEE9,在这个服务下包含有8个特征,其中第一个特征UUID为9600结尾的一个128位UUID,是用于接收APP发送的数据的特征,在APP端显示为可写的一个特征值。后面是7个用于发送数据到APP的特征值,特征值UUID后四位由9601递增至960转载 2017-07-07 09:20:36 · 2074 阅读 · 0 评论 -
NXP 蓝牙QN902X 协议profile的理解
建立一个新的profile必须要先熟悉和理解好qpps的profile的实现方式。就是大概理解好qpps.c/qpps_task.c/app_qpps.c/app_qpps_task.c实现的函数基本作用是什么。qpps.c/qpps_task.cqpps.c 主要是初始化服务、特征,把任务注册进系统内核,开启或者关闭qppsqpps_task.c qpps任务状态机的具体内容,包转载 2017-07-07 09:23:45 · 1575 阅读 · 0 评论 -
嵌入式c语言高级编程技巧 之 结构体的对象思维。
基于对象思想的结构体运用对于c语言来说好像没有对象这个概率,但是结构体的出现可以完全模拟对象情况举个简单的例子,就好像c++教程里关于求矩形的面积的问题,先定义一个对象类。class 矩形 { ... public: ... void set_lenght(){}; void set_width{}; void get_area(){};}; 但原创 2017-11-12 15:24:13 · 2919 阅读 · 1 评论 -
嵌入式C语言高级编程技巧 之 温故知新的指针
有什么不对的地方,多多指正。原创 2017-11-15 15:50:00 · 764 阅读 · 0 评论 -
C语言如何检测json格式的数据合法性
在http://www.json.org/JSON_checker/上有一个开源的工具,仅一个C文件、一个H文件,还附带UTF8转UTF16的转换工具。将main函数修改了一下,便可作为工程的一个小模块使用,检查JSON字符串的合法性,以便于进行报文解析。1234/* Read input string and check. if not json string retur...转载 2018-06-25 11:24:40 · 3988 阅读 · 0 评论 -
对于常用字符编码格式(ASCII/Unicode/UTF-8)简介
1. ASCII码我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串。每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从0000000到11111111。上个世纪60年代,美国制定了一套字符编码,对英语字符与转载 2017-12-02 14:51:25 · 1132 阅读 · 0 评论 -
基于动物标签识别的基础知识以及FDX-B协议与结构介绍。
在此之前,要先了解一下动物识别标准。1 国际动物识别标准介绍 ISO 11784:动物的射频识别——代码结构。 ISO 11785:动物的射频识别——技术标准。 ISO 11784和11785分别规定了动物识别的代码结构和技术准则。标准中没有对应答器样式尺寸加以规定,因此可以设计成适合于所涉及动物的各种形式,如玻璃管状、耳标或项圈等。 1.1 代码结构原创 2017-11-20 23:00:02 · 5172 阅读 · 0 评论 -
单片机加解密原理
单片机加解密可划分为两大类,一类是硬件加解密,一类是软件加解密。硬件加密,对于单片机来说,一般是单片机厂商将加密熔丝固化在IC内,熔丝有加密状态及不加密状态,如果处于加密状态,一般的工具是读取不了IC里面的程序内容的,要读取其内容,这就涉及到硬件解密,必须有专业的硬件解密工具及专业的工程师。现在重点谈谈软件方面的加解密。软件加解密的前提是要有软件,即转载 2017-06-09 16:31:12 · 3101 阅读 · 0 评论 -
CRC校验算法原理分析
CRC校验码的基本思想是利用线性编码理论, 在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的监督码(既CRC码)r位,并附在信息后边,构成一个新的二进制码序列数共(k+r)位,最后发送出去。在接收端,则根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错,在数据存储和数据通讯领域常用。 生成多项式的选择是 CRC 算法实现中最重要的部原创 2017-06-21 14:54:40 · 16777 阅读 · 2 评论 -
关于嵌入式编程函数指针的运用
当一个工程中,要调用性质相同的函数时,可以利用函数指针让代码结构更清晰。fun();int fun(int p);void fun(void);void *fun();void (*fun)();定义一个指针,该指针指向函数的的入口地址(void *)fun();定义一个函数,返回值为指针void (*fun)(void *);定原创 2017-06-20 12:18:50 · 1600 阅读 · 0 评论 -
APP空中升级原理
升级介绍蓝牙固件升级是使用手机给固件进行更新,以达到修复bug,完善功能的作用。升级的大概流程是:首先,当手环的固件需要升级时,由嵌入式开发人员提供新的固件,由服务器管理人员将固件放到服务器上,此时,用户打开手机APP的时候会检测到服务器有更新,请求更新手环固件,确认更新后,手机会从服务器下载固件。下载完毕后,APP会读取固件内容,并根据升级协议将内容传到手环里,完成升级。转载 2016-06-08 14:41:24 · 4358 阅读 · 0 评论 -
Lis3dh
Lis3dh有两种工作方式,一种是其内置了多种算法来处理常见的应用场景(如静止检测、运动检测、屏幕翻转、失重、位置识别、单击和双击等等),用户只需简单配置算法对应的寄存器即可开始检测,一旦检测到目标事件,Lis3dh的外围引脚INT1会产生中断。另一种是支持用户通过SPI/I2C来读取底层加速度数据,并自行通过软件算法来做进一步复杂的处理,如计步等等。 本文以Lis3dh为讲转载 2016-06-08 14:25:24 · 28069 阅读 · 2 评论 -
准备学习微信蓝牙
笔者决定在嵌入式企鹅圈2016年的首篇文章中,发表微信硬件物联领域极具实践价值的文章,它将能指引和帮助任何有兴趣于物联网开发的童鞋们快速掌握微信硬件开发流程,只需一个小时,而再不需要通过揣摩微信硬件浩瀚的文档资料来完成艰难构建。 笔者之前曾经撰写过一篇文章《基于微信硬件公众平台的智能控制开发流程》介绍微信硬件开发的流程,但该篇文章是理论性的描述。而本篇文章是完全可操作实践的,转载 2016-06-08 14:18:17 · 638 阅读 · 0 评论 -
HEX文件和BIN文件区别
HEX文件和BIN文件大小有区别 HEX文件是用ASCII来表示二进制的数值。例如一般8-BIT的二进制数值0x3F,用ASCII来表示就需要分别表示字符'3' 和字符'F',每个字符需要一个BYTE,所以HEX文件需要 > 2倍的空间。 对一个BIN文件而言,你查看文件的大小就可以知道文件包括的数据的实际大小。而对HEX文件而言,你看到的文件 大小转载 2016-05-30 17:26:58 · 722 阅读 · 0 评论 -
KEIL MDK 查看代码量、RAM使用情况--RO-data、RW-data、ZI-data的解释(转)
KEIL MDK 查看代码量、RAM使用情况--RO-data、RW-data、ZI-data的解释(转)时间:2015-09-16 12:13:44 阅读:382 评论:0 收藏:0 [点我收藏+]标签:源:KEIL MDK 查看代码量、RAM使用情况--RO-data、RW-data、ZI-data的解释 KEIL转载 2016-05-28 17:30:13 · 2680 阅读 · 0 评论 -
数组首地址给赋给 指针的问题
#include #include void sort(int* in, int len, int** out);void sort(int* in, int len, int** out){ *out = in; //把数组首地址给out指针,在此时,是正确的! //也就是in, out 指向的是同一内存区域!原创 2016-05-15 16:36:40 · 8035 阅读 · 1 评论 -
嵌入式系统使用宏定义
使用宏定义在 C 语言中,宏是产生内嵌代码的唯一方法。对于嵌入式系统而言,为了能达到性能要求,宏是一种很好的代替函数的方法。写一个"标准"宏 MIN ,这个宏输入两个参数并返回较小的一个:错误做法:#define MIN(A,B) ( A 正确做法:#define MIN(A,B) ( (A)对于宏,我们需要知道三点:(1)宏定义"像"函原创 2015-12-31 14:00:04 · 2835 阅读 · 0 评论 -
嵌入式开发过程中透彻数据符号的解析
在单片机开发中,c语言编程如果不指定变量是否有符合时,默认的基础数据类型均为signed(有符号的数据)现在我们以char为例,说明(signed) r与unsigned 之间的区别 首先单片机数据在内存中,char与unsigned char都是一个占用字节,但是区别就是,char的最高位为符号位,因此char能表示-128(0x80)~127(0x7F), unsigned c原创 2016-09-13 20:36:26 · 867 阅读 · 0 评论 -
嵌入式算法之查表法的应用
今天就说一说查表法,如果在程序中运用查表法,不论多么复杂的程序,只要符合一张表,那都可以实现,非常简单,体力活而已,接下来看看下面这个程序,对上面这个进行操作吧。#include #include //这里的行可以自由写,这样就不受限制,想做出什么样的效果都可以。int array[][10] = { 0x03,0x00,0x00,0x00,0x00,//第一列 0x00,0转载 2016-10-22 12:21:05 · 3300 阅读 · 0 评论 -
嵌入式软件分层设计思想
一、遇到的问题 通过这一段时间业务代码编写实践,体会到了之前的代码结构的缺陷: (1)开发效率低:每次使用片内的某一资源(例如定时器等),笔者都要去查询CC2430中文手册,比较eggache~ (2)代码重复较多:每个实验源码中,诸如 xtal_init ,led_init 等初始化函数每次都要编写 (3)不易修改:代码中的业务逻辑与SFR的操作混在一起,转载 2017-06-06 18:26:05 · 11972 阅读 · 0 评论 -
IAR编译cstack错误及解决办法
IAR编译cstack错误:Error[e16]: Segment CSTACK (size: 0x20 align: 0x1) is too long for segment definition. At least 0x6 more bytes needed. The problem occurred while processing the segment placement com原创 2017-05-25 15:51:37 · 5227 阅读 · 0 评论 -
嵌入式系统中各种变量存储位置分析
局部变量,局部静态变量,全局变量,全局静态变量区别:局部变量: 栈区局部静态变量:静态区全局变量: 静态区的常量区全局静态变量:静态区在进行C/C++编程时,需要程序员对内存的了解比较精准。经常需要操作的内存可分为以下几个类别: 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈原创 2016-12-30 10:07:49 · 4305 阅读 · 0 评论 -
如何对一个大的项目进行模块化编程。
转载于:http://blog.csdn.net/zhzht19861011/article/details/5974945当你在一个项目小组做一个相对较复杂的工程时,意味着你不再独自单干。你需要和你的小组成员分工合作,一起完成项目,这就要求小组成员各自负责一部分工程。比如你可能只是负责通讯或者显示这一块。这个时候,你就应该将自己的这一块程序写成一个模块,单独调试,留出接口供其它模块调转载 2017-04-20 12:24:31 · 24970 阅读 · 1 评论 -
基于matlab程序对PID控制算法的理解
%设一被控对象G(s)=50/(0.125s^2+7s),%用增量式PID控制算法编写仿真程序%(输入分别为单位阶跃、正弦信号,采样时间为1ms,控制器输出限幅:[-5,5],% 仿真曲线包括系统输出及误差曲线,并加上注释、图例)。clear all;close all; ts=0.001; %采样时间sys=tf(50,[0.125,7, 0])原创 2016-12-23 11:57:23 · 79042 阅读 · 15 评论 -
嵌入式软件设计中关键字:const/volatile/static
最近调试51822遇到一个被编译器优化的坑,发现关键字的重要性,平时定义变量的时候,还是必要加上关键字,避免不必要的麻烦。这里整理一份关键字的用法。关键字 volatileC 语言编译器会对用户书写的代码进行优化,譬如如下代码:int a,b,c;a = inWord(0x100); /*读取 I/O 空间 0x100 端口的内容存入 a 变量*/b = a;原创 2015-12-31 13:57:17 · 1186 阅读 · 0 评论 -
嵌入式系统中结构体+冒号+数字的意义
在最近嵌入式开发过程中经常遇到如下结构体形式:/**@brief GATT Characteristic Properties. */typedef struct{ /* Standard properties */ uint8_t broadcast :1; /**< Broadcasting of the value permitted. */ uint8_t原创 2016-12-28 17:25:36 · 1845 阅读 · 0 评论 -
嵌入式基础之中断处理用法
今天利用中断打印出现错误:打印不到一会 串口打印就乱了 最后找到问题。。中断不能用来打印,否则会出错。。。中断(Interrupts)11. 中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断。具代表事实是,产生了一个新的关键字 __interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程原创 2016-12-13 17:55:42 · 973 阅读 · 0 评论 -
嵌入式 模块划分程序设计注意事项
C语言模块化程序设计需理解如下概念:(1) 模块即是一个.c文件和一个.h文件的结合, 头文件(.h)中是对于该模块接口的声明;(2) 某模块提供给其它模块调用的外部函数及数据需在.h中文件中冠以extern关键字声明;(3) 模块内的函数和全局变量需在.c文件开头冠以static关键字声明;(4) 永远不要在.h文件中定义变量!定义变量和声明变量的区别在于定义会产生内存分原创 2015-12-31 09:47:42 · 1064 阅读 · 0 评论