2018-10-24 15:08:27 qq_18604707 阅读数 1479
  • 单片机有很多种-1.3.第1季第3部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第3个课程,主要讲了单片机的发展史,各种主流单片机的各自特点,STC51单片机的各系列的特点以及项目中如何选型主控单片机。

    2484 人正在学习 去看看 朱有鹏

写此json数据解析库的主要原因,因为最近在看json相关的程序,发现在linux下有完整的json库,而查看了这个json库后发现,这种json-c的库并不适用于单片机系统,尤其是没有OS的单片机系统,里面对内存的开销很大,大量使用了malloc()和free()函数进行内存分配,考虑到在单片机系统内,这写函数都是尽量不使用,同时内存并不多,出于爱好,先写了个基于纯C语言的简单的json解析库。

该库具备的特性:

1.能够解析json字符串内的子json数据。

2.能够解析str类型的json数据

3.能够解析INT型数据

4.能够解析bool型数据

暂不支持的特性:

1.不支持解析json数组类型数据(若去解析json数据中存在数组类型数据,将会返回出错)(json数组在单片机中用得确实少)

2.不支持内存不够的判断(在使用API时需要保证所给的buff能够装得下所解析的数据,这也是单片机中常用的做法)

3.基本库所解析回来的INT,bool等数据类型都是字符串的形式存在,可以通过扩张库转化为数字和bool变量

 

 

eg:例程使用了linux下的json-c生成了一段json字符串,然后调用我编写的json解析获取数据

#include <string.h>
#include <stdlib.h>
#include <stddef.h>

#include "json.h"
#include "hgetjson.h"          //针对于单片机提供的json库头文件



int main(int argc, char *argv[])
{
	json_object *smart_home_protocol = NULL, *hellotest = NULL, *test11 = NULL;
	
	smart_home_protocol = json_object_new_object();
	hellotest = json_object_new_object();
	test11 = json_object_new_object();
	
	
	if(smart_home_protocol == NULL)
	{
		printf("New Json Object Fail!\n");
		exit(1);
	}
	int rc = json_object_object_add(smart_home_protocol, "Smart Home", smart_home_protocol);
	json_object_object_add(smart_home_protocol, "heihei", json_object_new_int(66));
	json_object_object_add(test11, "haha", json_object_new_int(35));
	json_object_object_add(hellotest, "test0", hellotest);
	json_object_object_add(hellotest, "haha",json_object_new_int(36));
	json_object_object_add(hellotest, "heihei", test11);
	json_object_object_add(smart_home_protocol, "test", hellotest);
	//if (rc != -1)
	//{
		//printf("ERROR: able to successfully add object to itself!\n");
		//fflush(stdout);
	//}
	json_object_object_add(smart_home_protocol, "router", json_object_new_string("Normal"));
	json_object_object_add(smart_home_protocol, "temperature", json_object_new_int(36));
	json_object_object_add(smart_home_protocol, "haha",json_object_new_int(37));
	json_object_object_add(smart_home_protocol, "safe", json_object_new_boolean(1));
	
	
	char *jsonstr = json_object_to_json_string(smart_home_protocol);
	
	printf("Json data :%s\n", jsonstr); //linux json-c 生成的json字符串
	
	char buff1[50] = {0};            //用来存放数据的buff
	char buff2[50] = {0};
	
	int ret = get_json_object(buff1, "test", jsonstr);    //从jsonstr中获取名称为test的子json数据
	if(ret)
		printf("ERROR\n");
	else
	{
		printf("\ntest json from jsonstr:%s\n", buff1);
	}
	
	ret = get_json_object(buff2, "heihei", buff1);     //从子testjson中获取名为heihei的子json数据
	if(ret)
		printf("ERROR\n");
	else
	{
		printf("\nheihei json from test:%s\n", buff2);
	}
	
	ret = get_json_object(buff1, "heihei", jsonstr); //直接从jsonstr获取名为heihei的子json数据,直接穿过test 的子json
	if(ret)
		printf("ERROR\n");
	else
	{
		printf("\nheihei json from jsonstr:%s\n", buff1);
	}
	
	const char testname[4][10] = {"heihei", "haha", "router", "safe"};
	
	printf("\n");
	for(int ii = 0; ii < 4; ii++)      //获取不同的数据和数据类型
	{
		ret = get_json_dat(buff2, &testname[ii][0], jsonstr);
	
		if(ret == STRTYPE)
			printf("%s is STR dat from jsonstr, dat is %s\n", &testname[ii][0], buff2);
		else if(ret == INTTYPE)
			printf("%s is INT dat from jsonstr, dat is %s\n", &testname[ii][0], buff2);
		else if(ret == BOOLTYPE)
			printf("%s is BOOL dat from jsonstr, dat is %s\n", &testname[ii][0], buff2);
		else
			printf("Get ERROR\n");
	}
	

	json_object_put(smart_home_protocol);        //释放掉linux json-c的内存
	
	
	return 0;
}

运行结果如图:

 

 

单片机hjson使用说明:

获取json数据中子json API

int get_json_object(char *buff, char *object_name, char *json_dat)

buff:用于保存解析后的数据存储指针

object_name:获取子json数据名称指针

json_dat:原始json数据指针

返回值:0,获取成功,1获取失败

 

获取json内部数据的API:

int get_json_dat(char *buff, char *dat_name, char *json)

buff:用于保存解析后的数据存储指针

dat_name:获取数据的名称指针

json:原始json数据(注意:获取数据只会从根json中获取,不会从内部包含的子json中回去数据,若需要获取子json中的数据,需要先把子json给提取出来)

返回值:#define NONETYPE        0
              #define STRTYPE            1
              #define INTTYPE            2
              #define BOOLTYPE        3

返回-1,者是没有找到该数据

 

源码见:

https://download.csdn.net/download/qq_18604707/10741372

2020-01-13 17:54:01 qq_39653453 阅读数 15
  • 单片机有很多种-1.3.第1季第3部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第3个课程,主要讲了单片机的发展史,各种主流单片机的各自特点,STC51单片机的各系列的特点以及项目中如何选型主控单片机。

    2484 人正在学习 去看看 朱有鹏

向来都是知道了为什么才学习,之前也了解过数据库,觉得就是个数据的柜子,没什么,最近想好好研究一下,有一些感悟:

之前学C学单片机,都没有意识过数据库的方便,应为面向的服务不同。

我单片机,完成几个简单的功能,顶多有一些预定义的数字表,或者是图像的编码文件。

对于C++,我们做一个上位机,也就是需要把数据保存在一个txt文件中便于查找。

那数据库有什么用?这个也曾想过。

仔细想 我们上面的几个应用都可以在单机下完成,如果是物联网,我们也是一个结点只需要把我们的数据传到设备上就好了,但但是对于互联网来说,服务器与客户端的分离,数据库与逻辑代码的分离极大的方便了我们的应用。

 

数据库,首先它是个数据的柜子,这方面和我们当初的数组,文件没什么区别。

其次,它是一个“分立”于逻辑代码的柜子, 也就是说我们的应用设计中,不需要再工程中考虑数据的柜子(比如权限和操作的等级的编写),它已经做好了,我们拿来用就行

在其次,它是一个可供多个主机操作的柜子,这个得益于我们的服务器,我们把数据库放在服务器上,这样我们的数据库可以让多个用户操作,我们做顶层的把控。

 

总结,统一的数据库语言,统一的数据库格式,避免了各个服务方自己定义数据库维护的困难,结合互联网web应用,数据库的使用可以方便的对数据进行管理与操作,加快了开发速度。

 

MySQL数据库  6.0之前是免费开源的,足以应付web应用的开发, 最高支持千万级的并发访问

 

2014-02-28 15:49:42 u013716401 阅读数 3651
  • 单片机有很多种-1.3.第1季第3部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第3个课程,主要讲了单片机的发展史,各种主流单片机的各自特点,STC51单片机的各系列的特点以及项目中如何选型主控单片机。

    2484 人正在学习 去看看 朱有鹏

单片机与PC机之间的通信

51系列单片机内部的串行口具有通信的功能,该串口可以作为通信接口,利用该串行口与PC机的串行口COM1或COM2进行串行通信,将单片机采集的数据传送到PC机中,由PC机的高级语言或数据库语言对数据进行整理及统计等复杂处理,就能满足实际的应用需要。

PC机的COM口,输入输出为RS-232C电平,而51单片机串行口的输入输出均为TTL电平。由于TTL电平和RS-232C电平互不兼容,所以两者接口时,必须进行电平转换。(电平转换最常用的芯片是传送线驱动器MC1489,其作用除了电平转换外,还实现正负逻辑电平转换

 

PC机和单片机在进行通信时,首先分别对各自的串行口进行初始化,确定串行口工作方式,设定波特率(两者应一致),传输数据长度等,然后才开始数据传输,这些工作是由软件来完成的,因此对PC机和单片机均需设计相应的通信软件。

 

1.      DOS环境下,串行通信一般用中断方式来实现,用户对通信端口进行完全控制。而在Windows环境下,系统禁止应用程序直接对硬件进行操作在Windows环境下提供了完备的API应用程序接口函数,程序员通过这些函数与通信硬件接口。

通信函数是中断驱动的:发送数据时,先将数据存入缓存区,串口准备好后,就将其发送出去;传来的数据迅速申请中断,使Windows接收它并将其存入缓冲区,以供读取。

接收方式中以中断方式效率高,接收准确,编程简单。它无需测试串口,一旦有数据传至,CPU终止当前任务,由中断服务完成操作。

 

2.      单片机收发软件设计

设计单片机的通信软件,实际上是对单片机的串行口的设计,通常采用汇编语言来设计。

 


2019-12-23 14:40:17 weixin_42493179 阅读数 5
  • 单片机有很多种-1.3.第1季第3部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第3个课程,主要讲了单片机的发展史,各种主流单片机的各自特点,STC51单片机的各系列的特点以及项目中如何选型主控单片机。

    2484 人正在学习 去看看 朱有鹏

1.我们在软件开发过程中,为了提高数据库的查询效率,通常的做法是给数据库表中的某一个字段构建索引。有时候需要思考一下:数据库的索引是如何构建的呢?它的底层使用了什么数据结构?

2.我们首先确定一下数据库索引的需求:(1)根据某个值查找数据:select * from user where uid = 1234;

(2) 根据某个区间查找数据集合:select * from user where uid>1234 and uid<4567;

除此之外,我们还需要考虑索引的性能问题,因为我们创建索引的目的就是提高查询效率的,性能问题主要从时间和空间考虑。

3.尝试用学过的知识来解决这个问题:

支持快速查询,插入,删除操作的动态数据结构有 散列表,平衡二叉查找树,跳表。那么它们是否适合构建索引呢?

散列表:它查询的性能很好,时间复杂度为O(1),但是由于它内部存储的数据是无序的,所以它不支持区间查找。不可选。

平衡二叉查找树:查询性能也很好,时间复杂度为O(logn),但是它仍然不支持按照区间查找。不可选。

跳表:它是通过在链表的基础上构建索引层,查询的时间复杂度为O(logn),它也支持按照区间进行查找。只需要根据索引在链表中找到区间的首节点,然后遍历链表到区间的尾节点即可。

但是Mysql中的索引并不是使用跳表这种数据结构来解决的,而是使用B+树这种数据结构(个人感觉可能是B+树这种数据结构诞生比跳表早)

4.B+树的演进过程:

4-(1)其实B+树这种数据结构与跳表比较相似,但它是通过二叉查找树演进过来的。为了让二叉查找树可以按照区间查找,我们的做法是:二叉查找树的非叶子节点不存储数据本身,只作为索引使用数据本身都存储在二叉查找树的叶子节点,然后将叶子节点用一个双向链表串联在一起,并且链表中的数据是从小到大有序排列。这样就可以做到利用二叉查找树来加快查找速度,然后利用双向链表来进行数据的区间查找。例图如下:

如果我们需要查找某一个区间的数据集合,那么我们可以根据区间的起始值通过二叉查找树,找到叶子节点。然后再顺序遍历链表,直到节点中的数据值等于区间的终止值为止。

4-(2).二叉查找树产生的瓶颈问题:

利用双向链表的方式,让我们解决了数据库中按照区间查找数据集的问题。那么当我们为几千万条数据甚至上亿条数据构建索引时,为了保证索引的效率,我们就会把构建好的索引树存储到内存中。但是这样的方法对内存的消耗是很大的,例如:我们为一亿条数据构建索引,那么索引树中大约会包含一亿个节点,如果每个节点的大小按照16个字节来结算,那么大约需要占用1G的内存空间,如果有10张这样的数据表,那么就需要10G的内存空间。再实际的软件开发中是不可取的。

为了减少内存的消耗,我们可以通过以时间换空间的方式:将索引树存储到硬盘中。通常情况下,内存的访问速度是纳秒级别的,硬盘的访问速度是毫秒级别的。势必查询性能会产生影响。

将索引树存储到硬盘中以后,那么每个节点的读取或访问,都是一次I/O操作,树的高度就等于每次查询数据时I/O操作的次数。所以为了提高查询的效率,就必须要降低树的高度。

问题:如何将树的高度降低呢:

原始的树是二叉,那么我们可以将它变成m叉的树形结构。高度降低了,I/O次数减少了,查询的效率也就提高了。虽然说树的高度越低(m值越大),查询数据时I/O操作的次数就越来越少了,但是也不是m得值越大越好。因为操作系统每执行一次I/O操作,读取得是一页数据(大小为4k),那么如果二叉查找树中一个节点存储得数据量过大,会引发多次操作。综上所述:我们最好的方法应该是尽可能保证一个节点中保存的数据在一页数据大小(4K左右)。根据索引查找数据示意图:

4-(3) Mysql索引的更新过程:

作为一名软件工程师,我们需要直到,索引对我们有利也有弊。利:可以提高数据的查找效率。弊:会降低数据的写入效率。

原因:当我们插入数据时,索引树会进行更新。mysql使用B+树构建索引树的时候,树的分支m是根据数据页预先计算好的。每个节点的子节点数不能大于M。

当有数据插入时,有可能某一个节点下的子节点数会大于M,为了不大于M,所以就需要把当前节点进行分裂操作。分裂之后,有可能当前节点的父节点的子节点个数就大于M了,同样采取分类操作,分类操作是自上而下的。示意图如下:

当有数据删除时,某个节点的子节点个数就会减少,B+Tree中有一个阈值=m/2,如果某个节点的子节点个数小于m/2,那么就会将当前节点和它的兄弟节点合并。如果合并之后的子节点总数大于了M,那么再进行分裂操作。示意图如下:

4-(4)总结B+TRee:

B+Tree就是通过存储再磁盘上的多叉树,实现时间和空间上的平衡,既保证了查询效率,有节省了内存空间。B+Tree的每个节点的子节点数量不得大于M,也不能小于m/2,但是根节点除外。一般根节点存储在内存中,子节点存储在磁盘中。

5. B-Tree:

其实B-Tree就是B+Tree的降级版本,他与B+Tree的最大区别是:

(1) B-Tree的非叶子节点存储数据,B+Tree的非叶子节点不存储数据。

(2)B-Tree的叶子节点不需要链表串联,所以他只是一个子节点大于M/2,小于M的M叉树。

2019-09-08 12:04:48 attilax 阅读数 68
  • 单片机有很多种-1.3.第1季第3部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第3个课程,主要讲了单片机的发展史,各种主流单片机的各自特点,STC51单片机的各系列的特点以及项目中如何选型主控单片机。

    2484 人正在学习 去看看 朱有鹏

Atitit 单片机与嵌入式系统原理与概念

 

目录

1. 寄存器、数据库,堆栈 2

1.1. 寻址模式 2

1.2. 指令 2

1.3. Watchdog 中断 2

2. 软件是如何影响硬件设计的 2

2.1. 1.4.1谁在设计硬件 2

2.2. 1.4.2软件主导硬件 2

2.3. 1.4.3软硬件的均衡 2

3. 6.3嵌入式系统的事件处理 3

3.1. 6.3.2信号和事件是不是同一回事 3

3.2. 6.3.3什么样的事件是时间敏感的 3

3.3. 6.3.4当侦测到一个异常,微处理器如何处理 3

3.4. 6.3.8中断是如何产生的和服务的 3

4. 6.4中断程序 3

5. 6.2 8051指令集 4

6. .3  管态、异常和陷阱 4

6.1. 3.3.2  异常 4

6.2. 3.3.3  陷阱 4

7. 3.6  CPU的性能 5

7.1.  3.6.1  流水线技术 3.6.2  高速缓存的性能 5

7.2. 5.2  嵌入式程序组件 5.2.1  状态机 5.2.2  循环缓冲区和面向流的程序设计 5.2.3  队列和生产者/消费者系统 5

8. 6.6  进程间通信机制 6.6.1  共享内存通信 6.6.2  消息传递 6.6.3  信号 6.6.4  邮箱 5

9. 7.第11章 存储管理   142(n内存 5

9.1. 11.2  作用域   143 6

9.2. 11.3  生命周期   145 6

9.3. 11.4  自动分配   145 6

9.4. 11.5  静态分配   146 6

9.5. 11.6.1  对象创建   147 6

9.6. 11.9  递归函数和内存分配   152 6

10. 嵌入式服务 7

10.1. Webserver 7

10.2. ftp server 7

11. 参考资料 7

 

 

 

  1. 寄存器、数据库,堆栈
    1. 寻址模式
    2. 指令
    3. Watchdog 中断

指令的时序

反汇编

 

软件移植

实时性

  1. 软件是如何影响硬件设计的
    1. 1.4.1谁在设计硬件
    2. 1.4.2软件主导硬件
    3. 1.4.3软硬件的均衡

1.4.4硬件调试

1.4.5自检

1.4.6小结

 

  1. 6.3嵌入式系统的事件处理

6.3.1事件

    1. 6.3.2信号和事件是不是同一回事
    2. 6.3.3什么样的事件是时间敏感的
    3. 6.3.4当侦测到一个异常,微处理器如何处理

6.3.5所有的异常都一样吗

6.3.6同步异常

6.3.7异步异常

    1. 6.3.8中断是如何产生的和服务的

6.3.9CPU保存的状态是什么

6.3.10机器状态就是线程状态吗

6.3.11异常处理程序应该用汇编语言还是C语言来写

6.3.12怎样避免在异常处理程序上花费时间

  1. 6.4中断程序

6.4.1设置中断

6.4.2中断服务例程

6.4.3中断向量

6.4.4初始化

6.4.5小结

2.4 通信接口
2.4.1 板上通信接口
2.4.2 外部通信接口

  1. 6.2 8051指令集


6.2.1 数据传输指令
6.2.2 算术运算指令
6.2.3 逻辑指令
6.2.4 布尔运算指令
6.2.5 程序控制转移指令

  1. .3  管态、异常和陷阱 

CPU状态分为目态和管态两种,从目态转换到管态的惟一途径是?

3.3.1  管态

    1. 3.3.2  异常
    2. 3.3.3  陷阱


3.5  存储系统机制
3.5.1  高速缓存
3.5.2  存储管理单元和地址转换

 

  1. 3.6  CPU的性能

    1. 3.6.1  流水线技术
      3.6.2  高速缓存的性能

 

    1. 5.2  嵌入式程序组件
      5.2.1  状态机
      5.2.2  循环缓冲区和面向流的程序设计
      5.2.3  队列和生产者/消费者系统

 

  1. 6.6  进程间通信机制
    6.6.1  共享内存通信
    6.6.2  消息传递
    6.6.3  信号
    6.6.4  邮箱
  2. 7.第11章 存储管理   142(n内存

 

11.1  C语言中的对象   142

    1. 11.2  作用域   143

11.2.1  改进局部作用域   143

11.2.2  改进全局作用域   144

    1. 11.3  生命周期   145
    2. 11.4  自动分配   145
    3. 11.5  静态分配   146

11.6  三个程序:区分静态分配和自动分配   147

    1. 11.6.1  对象创建   147

11.6.2  对象初始化   147

11.6.3  对象销毁   148

11.7  动态分配   149

11.7.1  内存碎片   150

11.7.2  内存分配池   150

11.8  具有变量大小的动态分配   150

    1. 11.9  递归函数和内存分配   152

 

  1. 嵌入式服务
    1. Webserver
    2. ftp server
  2. 参考资料

单片机与嵌入式系统图书书目--2006年第1期.doc

《嵌入式软件开发精解(Mentor Graphics公司资深嵌入式软件专家历时多年呕血之作。全景式展现了一幅嵌入式软件开发的路线图)》((美)瓦尔斯 著)【简介_书评_在线阅读】 - 当当图书.html

《嵌入式系统原理、设计及开发(国外计算机科学经典教材)》((美)施部·克·威(V)【简介_书评_在线阅读】 - 当当图书.html

《嵌入式硬件设计(第二版)》((美)卡特索利斯(Catsoulis)【简介_书评_在线阅读】 - 当当图书.html

《嵌入式计算系统设计原理(原书第3版)》((美)沃尔夫 著)【简介_书评_在线阅读】 - 当当图书.html

《嵌入式计算系统设计原理(原书第3版)》((美)沃尔夫 著)【简介_书评_在线阅读】 - 当当图书.html

《嵌入式软件设计基础——基于ARM Cortex-M3(原书第2版)》(_(美)Daniel W. Lewis 著 圣克拉拉大学 陈文智 胡威 等译_)【简介_书评_在线阅读】 - 当当图书.html

《嵌入式系统软件教程(附CD-ROM光盘一张)——计算机科学丛书》((美)西蒙 著)【简介_书评_在线阅读】 - 当当图书.html

《Linux嵌入式实时应用开发实战(原书第3版)》((美)Doug Abbott 著)【简介_书评_在线阅读】 - 当当图书.html

VB/JAVA与单片机通信

阅读数 1016

没有更多推荐了,返回首页