- 博客(64)
- 收藏
- 关注
原创 串口控制小车(二次开发)
在串口中断程序中需要注意memset()函数的书写位置,应该把memset()函数写在switch语句之中,而不是switch语句之后。否则会出现如下BUG:一个相同的指令需要发送两遍,单片机才会响应,只发送一遍指令是没有反应的。:在小车不同方向的控制中,我们的有效指令的关键字眼的第一个字符都是'M',所以我们这里使用了switch语句来进行判断。:我们用现成的APP,按键设置如下图所示。L9110S电机驱动模块。L9110S电机驱动模块。》一节中的连接方式一致。
2023-06-14 17:04:16
1879
1
原创 L9110S电机驱动模块demo
一个L9110S驱动可以控制一个电机,图中左右两个黑色芯片就是L9110S驱动。当然如果会硬件也可以直接把它们设计到单片机开发板上。一个电机由两个针脚控制,我们用杜邦线让L9110S和单片机连接,两个针脚的电平高低会决定电机正转还是反转。:注意一开始把电池电源切断,防止接线的时候出错烧毁L9110S模块。
2023-06-07 17:14:56
11162
2
原创 IIC协议
半双工:IIC协议是两线式串行总线,两根信号线分别是数据线SDA和时钟线SCL。所有用IIC通讯的设备都需要遵循相同的通讯时序。5、:IIC总线在传输数据的过程中一共有三种类型信号,分别为:开始信号、结束信号和应答信号。6、:回顾DHT11模块的时序分析,我们做的还不好,正确的分析逻辑应该如下。
2023-05-28 22:19:39
7089
原创 分文件实现温湿度数据管理系统项目
目标:0、要点:1、函数声明的注意点:2、函数跨文件声明不成熟方法1:头文件间接声明 3、函数跨文件声明不成熟方法2:分函数(在.h文件中) 4、函数跨文件声明不成熟方法3:分函数(在.c文件中) 5、函数的分文件原理:将上述三种方法(主要是方法1和方法3)的优势进行结合,可以总结出自定义函数的分文件方法。如图示例: 1、变量的三特性:我们之前学过变量的四要素,现在看看变量具有哪三个特性。2、内存的分区:这个内存我们一般认为是虚拟内存(32位平台下的虚拟内存有4G大小,gcc编译器就是64位平台),对其划分
2023-05-25 22:08:40
1245
原创 DHT11温湿度传感器
超出建议的工作范围可能导致高达3%RH的临时性漂移信号。返回正常工作条后,传感器会缓慢地向校准状态恢复,加速恢复进程的方法是:置于极限工作条件下或化学蒸汽中的传感器,通过如下处理程序,可使其恢复到校准时的状态。在50-60℃和< 10%RH的湿度条件下保持2 小时(烘干);随后在20-30℃和>70%RH的湿度条件下保持5小时以上。在非正常工作条件下长时间使用会加速产品的老化过程。:DHT11模块的串行接口是单线双向的,一次通讯时间在4ms左右。
2023-05-21 13:40:56
11945
2
原创 LCD1602液晶显示模块
翻阅LCD1602说明书数据线占8根,有点像串口的SBUF(8位数据缓冲寄存器),单片机和LCD之间的数据交互也需要类似于SBUF的东西,但是不幸的是LCD1602没有串口,所以我们用一组I/O口(D0~D7)表示。:翻阅LCD1602说明书。
2023-05-17 21:07:16
13127
原创 串口与wifi模块
所以需要我们在另一个串口助手(COM3端口:51单片机和PC的串口)中手动模拟wifi模块本来应该响应给51单片机的数据。:指令是:AT+CIPSTART="TCP","192.168.1.7",8880 (这里的IPV4地址是PC的IP地址,在PC的命令提示符中通过config指令查询):像这个服务器我们以后也能自己写,基于Linux的或者基于Windows的,通过Scoket编程,用java或者C语言编程。:蓝牙,ESP-01s,Zigbee, NB-Iot等通信模块都是基于AT指令的设计。
2023-05-12 22:53:50
4546
1
原创 串口全双工通信与串口中断
这种处理方法对于上述指令够用了,但是处理复杂指令时可能会出错。想要完美的解决这一问题需要比较厉害的C语言功底,写出来的代码量也会比较大。
2023-05-12 22:29:56
3076
原创 感应开关盖垃圾桶项目实现.md
首先对初始化定时器这部分代码进行整合:我们让超声波用定时器1,让舵机用定时器0。根据定时器编程的思路,针对之前的代码修改以下东西,更改完后测试代码: 对超声波和舵机测试后的代码进行整合,经过学习,我整理出如下代码(用到的硬件是超声波传感器和舵机),接下来我们对如下代码进行优化,二次开发即可:思路:代码:模式2(查询法按键控制舵机)初步思路:这个程序中,是否需要给按键额外一个软件消抖?答:不需要,因为distance > 10是大概率事件,所以一般情况下程
2023-04-24 16:18:26
970
1
原创 初始单片机.md
单片机(Single-Chip Microcomputer)是一种集成电路芯片。把具有数据处理能力的中央处理器CPU、随机存储器RAM(也叫做数据存储器)、只读存储器ROM(也叫做程序存储器)多种I/O口和中断系统定时器计数器等功能可能还包括显示驱动电路脉宽调制电路(PWM)模拟多路转换器A/D转换器等电路集成到一块硅片上构成的一个小而完善的微型计算机系统,在工业控制领域广泛应用。
2023-04-15 13:25:05
1454
1
原创 typora和C51开发环境
Keil前完成:项目文件夹:Templatemain.c:先在项目文件夹中新建,再添加到工程目录中Keil中完成:工程文件moban.uvproj:在项目文件夹中建立工程目录:新建工程后自动提示你去选芯片moban.hex:在项目文件夹中,编译Rebuld后生成,最后我们要用烧录工具给这个hex文件下载到单片机中。
2023-04-13 18:21:46
664
原创 贪吃蛇小项目
贪吃蛇死亡有两种情况,除了我们一开始讲的碰壁,还有一种情况是咬到自己,也就是链表尾碰到了贪吃蛇身子的其他节点,那么我们不妨将这两种情况写在一起,一同作为moveSnake()函数中是否重新调用initSnakeHead()函数的判据。,贪吃蛇在进行四方位走位时(准确来说是三方位,因为我们不允许蛇掉头走,掉头走属于不合理的走位),也遵循的是在链表尾添加新节点,删除链表头的原理,但是新节点的行列坐标要根据贪吃蛇的移动方向来确定。:判断现阶段我们要添加哪些函数,修改哪些函数。
2023-04-11 14:14:22
745
原创 动态链表创建及操作(对静态的补充)
tip1:这两个程序很相近,我们都可以分为两个函数,第一个就是头插法或尾插法的API1,它们只负责:①建立新节点new和原先链表head的联系,②注明节点序号。tip2:第二个是批量初始化动态节点的API2,它们负责:①循环开辟新节点new,②键盘输入初始化新节点new中的数据idata,③把head和new打包给API1。
2023-04-08 16:38:56
818
原创 C的实用笔记44——枚举类型
1、知识点:定义的方式和结构体和共用体很像,都有三种,考虑到我们不关心枚举变量,用哪种都无所谓。枚举类型声明和枚举变量定义分开写。//w就是enum WeekDay类型的枚举变量//4,因为编译器会把枚举变量当做一个整型变量。//4,因为sizeof最终处理的就是数据的类型,sun是整型常量return 0;声明枚举类型,同时定义枚举变量:后面照样可以定义其他枚举变量声明枚举类型时不写类型名,同时可以不定义枚举变量:以下两种写法都是可以的,因为我们不关系枚举变量,只关心里面的枚举元素。
2023-04-03 19:59:38
1723
原创 C的实用笔记43——共用体/联合体
1、知识点:定义的方式也和结构体一样,有标准的一种,不推荐的两种。同时,共用体变量的占用空间大小是成员变量里占用空间最大的确定的。int idata;//t1就是union Test类型的共用体变量printf("共用体占用内存大小:%d\n", sizeOfTest);//8,因为最大的成员占8个字节return 0;2、两种不推荐的定义方式声明共用体,同时定义共用体变量:后面照样可以定义其他共用体变量,但这个方法尽量少用union Test。
2023-04-02 22:21:45
1719
原创 C的实用笔记38——结构体的引入和定义
1、标准的定义方式:结构体声明和结构体变量定义分开写。由于结构体是自定义的构造类型,所以需要先声明结构体,然后拿它来定义结构体变量。int num;char sex;int age;//stu1就是struct Student类型的结构体变量2、见怪不怪的定义方式声明结构体,同时定义结构体变量:后面照样可以定义其他结构体变量,但这个方法尽量少用int num;char sex;int age;//尽量少用。
2023-04-01 12:59:25
1601
原创 C的实用笔记37——几种常用的字符串处理API(二)
内存污染(存储字符串的目的内存不够用时,后面的内存会被污染,也就是被修改,类似于下标越界):复习以下知识点后,练习习题5,自己实现strncat()函数:复习以下知识点后,练习习题6,自己实现strncat()函数。
2023-03-31 18:45:48
265
原创 C的实用笔记36——几种常用的字符串处理API(一)
0、const关键字0、const关键字1、知识点const是与存储相关的关键字,用作常量声明,修饰普通变量和指针变量,表示只读。const修饰普通变量。
2023-03-29 23:34:40
1086
原创 C的实用笔记35——为字符串开辟动态内存
1、知识点堆区的字符串可以修改字符串里的字符。堆区的字符串不能通过指针偏移来给字符串遍历赋值。2、两种方式通过scanf函数初始化:int len;char *str;printf("请输入字符串长度\n");puts("请输入字符串");return 0;通过strcpy函数初始化:int len;char *str;printf("请输入字符串长度\n");return 0;
2023-03-28 21:57:45
1409
原创 C的实用笔记34——sizeof和strlen的区别
1.sizeof是运算符,strlen是函数strlen需要包含头文件<string.h>,而sizeof不需要。2.操作数的区别sizeof的操作数可以是变量、常量、指针、表达式、类型名、函数名、数组名、函数返回值......。最后操作系统会统一将操作数变成类型来处理,计算这个类型的数据占用多少内存。举例: 操作数是字符数组名:计算的是数粗占用的内存空间大小 char cdata[] = {'h','e','l','l','o'};char str[] = "hello"
2023-03-28 21:53:56
201
原创 C的实用笔记33——字符串与字符数组、字符指针
1、知识点:根据数组名就是数组首地址的规定,我们完全可以定义一个一级字符指针,来指向用字符数组保存的字符串。2、使用方法通过指针偏移间接读取字符串里的内容://用字符数组存储字符串int i;//用字符指针指向字符串for(i=0;i<len;i++){//用指针偏移的方式读取字符串里的字符return 0;通过指针还可以间接打印字符串://%s打印字符串puts(pstr);//puts函数打印字符串return 0;
2023-03-26 22:28:42
133
原创 C的实用笔记30——指针数组(函数指针数组)
1、:指针数组本身是一个数组,是若干个相同类型的指针变量顺序存储构成的集合。因此,定义指针数组的就是为了存放多个地址编号。举个简单的例子:2、:数组有三要素,但数组并不关心它的第一维长度,它关心从第二维开始的长度以及数组元素的类型,一般来说,指针数组都是一维的,所以我们仅仅关注数组元素的类型就行了,对于指针数组来说,我们格外关注指针数组里到底存放的是什么类型的指针(普通指针、数组指针、还是函数指针)。3、4、:看起来没啥用,我们做个简单练习。
2023-03-26 22:11:32
1259
原创 C的实用笔记29——函数指针(通过指针引用函数)
1、函数指针的概念:2、正确的定义方式函数指针也讲究指针的类型。这里的类型是返回值的类型,也就是要函数的类型和函数指针的类型一致,这里的类型关注两点:①函数的返回值类型和函数指针前面类型是否一致、②函数的形参列表的参数类型和函数指针的形参列表参数类型是否一致。见怪不怪:见到了不要怕,因为关心的是操作数的类型,而不是操作数的名字,所以可以不写操作数名字3、函数指针为啥这样写?(通用的类型判别方法)函数指针首先它得是一个指针,所以用小括号把*p括起来是为了先让修饰符*和p结合,确保p是一个指针;
2023-03-26 22:08:18
653
原创 C的实用笔记28——通过数组指针引用二维数组
封装获取二维数组第i行第j列元素值的API。:封装初始化和打印二维数组的API。在用二维数组作为函数的参数的时候。4.二维数组(父数组与子数组):数组指针偏移取星花。
2023-03-24 23:57:18
1929
原创 C的实用笔记27——数组指针(指针引用二维数组的桥梁)
1.如何通过普通指针间接访问二维数组的每个元素?合理吗?1.如何通过普通指针间接访问二维数组的每个元素?合理吗?1、正确的做法:将二维数组第0行第0列的元素的地址赋值给指针。背后的逻辑:&a[0][0] 、 a[0] 、 *a 三者在逻辑上是等价的,这些“指针”的类型都是int *型的。
2023-03-24 23:52:33
115
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人