- 博客(63)
- 收藏
- 关注
原创 [OTA-day6A区更新数据]
flash中A区OTA接收数据完成后置位OTA_FLAG;接收完成后复位不仅仅是在RAM中OTA_FLAG=0;通过分片下载的方式下载到W25Q64中;就是比如一个64K的文件,每次下载256字节,分数次下载。服务器告知下载并将OTA_FLAG置位;下载的大小也是通过服务器告知,下载的长度这个变量也需要保存到24C02中。1.谁让OTA_FLAG标志位置位允许OTA升级?根据保存在24C02中的下载长度,拿数据(一次拿1024字节),写到A区。3.OTA时,最新版本的程序文件如何下载?
2023-05-19 15:29:08 305 1
原创 [OTA-day5 FLASH擦写]
主存储块用于存储程序,我们写的程序一般存储在这里。信息块又分成两部分:系统存储器、选项字节,系统存储器存储用于存放在系统存储器自举模式下的启动程序(BootLoader),当使用ISP方式加载程序时,就是由这个程序执行。因为我们是分片写入,一次传不了那么多,我们采用分片传入,每次传输256个字节,如果遇到中途断电,之前写入的数据也是存到24C02中不会丢失。说到STM32的FLSAH,我们的第一反应是用来装程序的(掉电不丢失),实际上,STM32的片内FLASH不仅用来装程序,还用来装。
2023-05-19 15:05:43 280
原创 [OTA-day5 OTA_FLAG]
当不需要OTA远程升级的时候,我们应该正常执行功能,需要OTA远程升级的时候再跳转到B分区开始OTA升级,所以我们就需要一个系统OTA标志位OTA_FLAG,比如OTA_FLAG为0x11223344(随意举例的)则说明需要OTA升级,如果不为0x11223344则跳转到A分区执行正常的功能,我们在flash中将0-19扇区设为B区,20-63(不一定非要是64个区,只是c8t6有64个扇区)设为A分区,B分区在前A分区在后。2.PC程序寄存器(函数怎么执行的呢?那新的问题来了:该怎么实现B->A跳转呢?
2023-05-18 23:41:00 352
原创 关于嵌入式系统内存地址空间的一些疑问(.text、.data、.bass、堆\栈空间)
芯片上电就会进入Reset_Handler中断,打开.s启动文件,我们可以发现在Reset_Handler中断里,调用了SystemInit函数,然后再调用了_main(IAR编译器的话是__iar_program_start)函数,在_main函数会进行RW data的复制,和.bss段的初始化,以及C库函数的初始化(比如malloc函数需要初始化才能使用),进而调用main函数进入我们的代码区域。//加上static的局部变量,只能在本函数内引用,函数结束回时不会消失,有初值,放在.data段中。
2023-05-18 23:18:23 658
原创 [OTA-day3SPI]W25Q64擦写
所以,在从机模式下,应用程序必须确保在数据发送开始前, 数据已经写入发送缓冲区中。SPI开始发送一个数据帧时,首先将这个数据帧从数据缓冲区加载到移位寄存器中,然后开始发送加载的数据。在主机模式下,若想要实现连续发送功能,那么在当前数据帧发送完成前,软件应该将下一个 数据写入SPI_DATA。模式中,为了接收下一个数据帧,硬件需要连续发送时钟信号,而在全 双工主机模式(MFD。SPI协议是一个四线制的协议,是全双工的,具体的解释可以看看这篇文章。)中,当发送缓冲区非空时,硬件只接收下一个数据帧。
2023-05-17 21:30:35 541
原创 [OTA-day2IIC]软件模拟IIC使用24C02
4.读数据:我们可以用到GD32官方库的函数BIT(i)[将0x01左移I位],先判断SDA读到的数据为高电平,就将该位置1,反之则置0,因为我们声明Rxd的时候就是Rxd=0,所以读到0可以不做任何操作,读完一位然后等待应答ACK,如果是8位数据前7位都是应答,最后一位不应答,接受完数据后IIC_Stop();i--) 从第七位开始判断,如果为高电平则SDA输出高,如果为低电平SDA输出低,然后释放总线SCL,开始下一个数据发送。
2023-05-17 16:33:16 367
原创 [OTA-day1] 串口收发及重写printf函数
3.创建一个结构体数组用于存放结构体start和end指针对,创建结构体指针IN,OUT,END,IN每次接收数据完成就向后移一位,然后与OUT判断,如果OUT与IN不相等,就说明有数据接收,就开始处理数据,END是结构体数组的最后一个元素,如果IN和OUT等于END就回卷,防止数组越界。2.分别创建(结构体)start指针和end指针,指向每次接收数据的开头和数据的结尾,指针的偏移量就是(串口)每次接收字节的长度。1.首先确定接收方案:用DMA+空闲中断来接收。2.每次接收大小的确定,严禁数组越界。
2023-05-15 09:28:30 289
原创 [GD32f103x] OTA远程升级 1
工程文件里没有RTE_Components.h这个头文件,必须要自己新建一个,打横线的是灰色的,说明没有声明此函数,我们需要用到哪个外设就去RTE_Components.h里#define一下就可以了。将GD32F10x_standard复制到自己新建的Lib中,source里的放source中,lnclude放linclude的里。这里面的依然是对应着放到自己的CMSS里的source和include。其中这三个.h放自己的CMSS里的include。官方文件的CMSS里的放到自己新建的CMSS里。
2023-05-14 08:39:09 680
原创 [ARM+Linux]智能家居项目
本次智能家居项目采用的是简化main函数代码,便于阅读。所有控制以及外设的设备都做成一个个对象,分别将命令控制的连成一个控制链表,外设设备做成一个外设设备的链表,这样做是为了方便以后功能模块的添加。其中为了能分别做好控制,我们采用多线程来实现。指令工厂:socket、语音控制(由于树莓派只有一个串口,所以我将Wemos D1作为服务器,树莓派作为客户端通过socket连接,实现指令控制)树莓派通过串口连接各语音模块LD2330,检测语音的识别结果,分析语音识别的结果来对家电设备进行控制。
2023-05-12 00:07:05 646
原创 [Ubuntu] 虚拟机没有wifi图标怎么办
sudo service network-manager stopsudo rm /var/lib/NetworkManager/NetworkManager.statesudo service network-manager start
2023-05-09 11:13:39 455
原创 树莓派GPIO驱动编写
编译器优化是指:CPU访问内存的时间比较长,所以CPU优先访问Cache,Cache 中存放了内存中的一部分数据,CPU 在访问内存时要先访问 Cache,若 Cache 中有需要的数据就直接从 Cache 中取出,若没有则需要从内存中读取数据,并同时把这块数据放入 Cache 中。以上程序在驱动的基础框架下,新增了配置寄存器的操作,以及获取用户态write的值,从而进行操作,获取write值的函数是。操作系统运行在保护模式下所使用的地址,也叫逻辑地址,它是基于算法的,处于软件层面。
2023-05-05 10:05:27 318
原创 文件系统大总结
设备(device)文件目录,存放linux系统下的设备文件,访问该目录下某个文件,相当于访问某个设备,存放连接到计算机上的设备(终端、磁盘驱动器、光驱及网卡等)的对应文件 (b 随机访问,c 线性访问):根目录,位于Linux文件系统目录结构的顶层,一般根目录下只存放目录,不要存放文件,/etc、/bin、/dev、/lib、/sbin应该和根目录放置在一个分区中。: 服务启动之后需要访问的数据目录,存放系统上运行的服务用到的数据,如www服务需要访问的网页数据存放在/srv/www内。
2023-05-04 17:27:59 101
原创 Linux内核介绍、编译
内核是一个很厉害的超级逻辑,把硬件底层的东西抽象化,对用户来说只需要调API就好了,根本不需要管寄存器,协议,总线…树莓派开发可以使用厂家自带的wiringPi库开发比较简单,但是在未来的开发不一定厂家会自带这种wiriPi库,但是只要是能运行的Linux就一定有标准的c库, 学会根据。(属于VFS层虚拟文件系统,因为磁盘的分区和引脚分区不一样,为了实现上层统一化),根据你的设备名比如pin4去到内核的驱动链表,根据其主设备号与次设备号找到相关驱动函数。最内层是硬件,最外层是用户应用,比如浏览器等等。
2023-05-04 16:09:12 549
原创 树莓派-内核开发-说明 下载代码 编译 替换内核
启动过程: 电源-》BootLoader(引导操作系统启动)-》Linux内核-》文件系统(根据功能性来组织文件夹,带访问权限)-》KTV点歌机,启动过程: 电源-》 fastBoot/Bootloader/-》linux内核-》文件系统-》虚拟机-》HOME应用程序-》点某图标打开某APP。嵌入式产品: 树莓派,mini2440, mini6410,nanopi,海思,RK(瑞芯微)------人脸识别打卡器,智能家居主控。C51,STM32(裸机)》》》》》》C直接操控底层寄存器实现相关业务。
2023-05-04 09:43:26 142
原创 交叉编译是什么?如何配置?软连接?硬连接?
要进行交叉编译,我们需要在主机平台上安装对应的交叉编译工具链(cross compilation tool chain),然后用这个交叉编译工具链编译我们的源代码,最终生成可在目标平台上运行的代码。比如,我们在 x86 平台上,编写程序并编译成能运行在 ARM 平台的程序,编译得到的程序在 x86 平台上是不能运行的,必须放到 ARM 平台上才能运行。交叉编译可以理解为:在当前编译平台上生成另一个目标平台上的可执行代码,但是编译平台本身却不能运行该程序。一、交叉编译是什么,为什么要交叉编译。
2023-05-01 17:52:18 1449
原创 Linux 共享库 静态库 动态库
动态库和共享函数库是一个东西:(Linux上叫做共享函数库,文件后缀是.so,windows叫做动态函数库,后缀是.dill)在执行时动态加载(临时)有目标程序去调用。-L ./的意思是优先在当前路径去寻找,如果只是-laddfunc,运行时会优先去/usr/local/lib路径下寻找,编译不加-L ./ 会报错。2.静态库的使用(砍头去尾:libaddfunc.a -----> -laddfunc,动态链接的方式使用)ar rcs libxxx.a xxxx.o//生成.a文件(静态库文件)
2023-04-26 12:53:57 609
原创 include “ “ 和include <>的区别
" "是优先在当前路径下寻找头文件,当前路径没有的话再去默认的路径下找头文件。<>默认是在 /usr/local/include 路径下寻找头文件。
2023-04-25 21:55:37 101
原创 数据库sqlite3
轻量化,易用的嵌入式数据库,用于设备端的数据管理,可以理解成单点的数据库。传统服务器型数据库用于管理多端设备,更加复杂SQLite是一个无服务器的数据库,是自包含的。这也称为嵌入式数据库,这意味着数据库引擎作为应用程序的一部分运行。MySQL需要运行服务器,MySQL将需要客户端和服务器架构通过网络进行交互。基于嵌入式的数据库主要有:SQLiteFirebirdeXtremeDBFirebird是关系型数据库,功能强大,支持存储过程,SQL兼容等SQLite。
2023-04-24 18:48:40 7118
原创 为什么编译时选择动态链接库,而不是将库函数写到程序里
如果将所有库写进程序里,那么每个程序都会包含大量重复的代码,导致程序的体积变得庞大,不仅占用程序的加载和运行速度。而使用动态链接库,这些模块只需要加载一次,即可供多个程序共用,大大节省了内存和磁盘空间。此外,动态译程序的情况下更新和护性和可重用性。②生成静态库文件:ar –q lib.a lib.o //将 lib.o 与其他文件打包到 lib.a 中。③使用静态库编译:gcc main.c lib.a –o main.out。编译静态库源码:gcc –c lib.c –o lib.o。
2023-04-23 14:07:34 555
原创 [ARM+Linux] Linux的热拔插UDEV机制/守护进程
udev是一个设备管理工具,udev以守护进程的方式进行,通过侦听内核发出来的uevent来管理 /dev目录下的设备文件,udev在用户空间(也就是应用层)运行,而不是在内核空间运行他能根据系统的硬件设备的状态动态更新设备文件。包括设备文件的创建,删除等,设备文件一般都是放在 /dev目录下。使用udev后在/dev目录下就只包含系统中真正存在的设备。
2023-04-21 16:13:43 1358
原创 LD3320语音模块二次开发
一开始dat == nAsrRes==>0会进入第一个if语句 标志位G0_flag = ENABLE ==> 0,运行完指令后,再进入else if语句,G0_flag = DISABLE ==> 1 然后进入下一个else语句中,执行“请说出一级口令”,所以经过这个操作使得必须每次喊出wang si yu 才可以执行语音口令。以上是口令模式,必须每次喊出 wang si yu 才能进行下一步动作,也可以是普通模式,直接运行语音口令。因为是二次开发,我只关心应用层的事儿,底层代码驱动我就不一一解释了。
2023-04-18 23:58:57 251
原创 [ARM+Linux] 基于全志h616外设开发笔记
修改用户密码配置网络命令扫描周围WIFI热点xxxpassword xxx 命令连接WiFi查看ip地址的指令:ifconfigSSH登录这是企业开发调试必用方式,比串口来说不用接线,前提是接入网络并获得板子IP地址,且系统做了SSH的服务器,本镜像自带SSH服务器,所以通过mobaXterm登陆就行基于官方外设开发1.wiringPi库SDK安装下载源码//进入文件夹sudo//清除编译信息sudobuild//编译通过windows。
2023-04-18 17:02:45 1486 1
原创 Linux常用命令
chmod u+x test.sh:权限范围:u(拥有者)g(郡组)o(其它用户), 权限代号:r(读权限/4)w(写权限/2)x(执行权限/1)#给文件拥有者增加test.sh的执行权限。tar -zcvf test.tar.gz ./test:打包test目录为test.tar.gz文件,-z表示用gzip压缩。mkdir -p /opt/test/img:在/opt/test目录下创建目录img,若无test目录,先创建test目录。vim三种模式:命令模式,插入模式,编辑模式。
2023-04-17 23:55:47 200
原创 [FREERTOS]队列
确实全局变量依然可以传递信息,但是如果全局变量改变的很频繁,某一任务处理数据比较缓慢,某一任务在处理数据的过程中改变了全局变量的值,就可能会导致某一任务获取的数据不正确,消息队列就像一条生产线似的,将数据放入队列中,任务从队列中读取数据,这样的话就算改变了数据的值,任务根据队列中的值来获取数据也能获取到正确的值。队列也称消息队列,是一种常用于任务间通信的数据结构,队列可以在任务之间,中断和任务之间传递信息。队列长度:队列能够存储项目(数据)的最大数量(创建队列时需要指定队列长度和队列项目大小)
2023-04-17 13:25:45 523
原创 [FREERTOS] 任务的创建、删除、调度与状态
抢占式调度用更直白的话来说就是:先执行优先级高的,然后执行优先级略低的,如果正在执行优先级低的,这个时候出现了优先级高的任务,就中断优先级低的任务去执行优先级高的任务,如果优先级最高的任务堵塞(比如使用了延时函数)就执行优先级略低的那个任务,等待优先级最高的任务堵塞结束后重新执行优先级最高的任务。·xTaskCreate()---------------------------动态方式创建任务。·vTaskDeletc()---------------------------删除任务。
2023-04-17 11:13:33 768
原创 基于cubeMX移植FREERTOS
(83条消息) cubemx开启freertos keil mdk选用arm6编译器编译报错_cube 添加freertos 编译报错_摇尾巴的小熊猫的博客-CSDN博客。(83条消息) 最新keil5没有ARM CompilerV5或者安装编译器5.06后编译license报错_keil5编译器_孤岛醉翁的博客-CSDN博客。如果使用 use default compiler version6也可以 (参考以下文章配置以下即可)经过以上配置就可以快速移植freertos到stm32上去了。
2023-04-17 09:55:22 226
原创 [STM32F103C8T6]ADC转换
我的理解是:注入通道是有特权的通道,可以优先转换,而规则通道是没有特权的通道只能按顺序转换(类似于买票排队,注入通道就类似于老弱病残孕军人之类的,享有优先特权,而规则通道就是普通的排队通道必须排队通过)原型:HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)原型:HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)
2023-04-16 12:14:13 6035
原创 [STM32F103C8T6]基于stm32的循迹,跟随,避障智能小车
通过实验我们又发现了bug,如果是全速驱动的话,小车转弯,比如左转就会左边轮子不动右边动,理论上是这样的,但是实际上会出现小车转弯一卡一卡的bug,于是我想到了用PWM调速,转弯的时候左右轮分开调速,左转就左轮速度低于右轮,右转就右轮速度低于左轮。于是循迹的逻辑就是,左右两边各安一个循迹模块,当两个模块都返回红外线输出低电平灯亮的时候,小车向前进,如果左边模块没有返回红外线高电平灯灭,右边模块返回红外线低电平灯亮,那么就说明遇到左转弯道,左转,相反就右转----->哪边高电平往哪边转。
2023-04-14 16:50:17 6361 2
原创 [STM32F103C8T6]基于LCD和DHT11、HC08的温湿度检测系统并上传服务器
GPIO_Mode_IN_FLOATING 浮空输入模式。GPIO_Mode_AF_OD 复用开漏输出模式。GPIO_Mode_AF_PP 复用推挽输出模式。GPIO_Mode_Out_OD 开漏输出模式。GPIO_Mode_Out_PP 推挽输出模式。GPIO_MODE_OUTPUT_PP 推挽输出。GPIO_MODE_OUTPUT_OD 开漏输出。GPIO_Mode_AF_OD 复用开漏输出模式。GPIO_Mode_AF_PP 复用推挽输出模式。GPIO_Mode_IPU 上拉输入模式。
2023-04-13 11:23:55 1061
原创 [STM32F103C8T6]LCD1
LCD1602的硬件时序图可以参考51那一章节的学习笔记,stm32可以不检查忙操作。这个操作可以将一个字节的数据一下子发送给GPIOA的八个管脚)
2023-04-12 18:27:28 191
原创 [STM32F103C8T6] 重做51 基于iic的oled显示实验
STM32不需要我们再去写时序,我们只需要封装写命令,写数据这两个函数。51单片机没有硬件iic,我们是通过io口软件模拟iic时序。而stm32有iic硬件,就不需要我们再软件模拟。,目标器件的地址,七位地址必须左对齐。,目标器件内部寄存器地址数据长度。,目标器件的目标寄存器地址。写模式分为写命令和写数据。
2023-04-12 13:13:43 490
原创 [STM32F103C8T6]DMA
我自己的理解就是:类似于一个多线程的存在,一些简单的比如数据传输的动作可以不通过CPU,DMA直接动作,这样可以释放CPU,让CPU去做些更有意义的事儿。当传输结束时,硬件自动会将传输数据量寄存器进行重装,进行下一轮的数据传输。个请求,它们的软件优先级相同,则较低编号的通道比较高编号的通道有较高。将内存数据搬运到内存(类似于将一个数组的数据复制到另一个数组)从内存到外设搬运数据(用DMA将内存数据发送到串口)节约出来的时间可以处理更重要的事)。存储器(例如:复制某特别大的数据。时钟的外设,而这里的存。
2023-04-11 23:22:38 2209
原创 [STM32F103C8T6]看门狗
在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造 成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会 造成整个系统的陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状态进行实时监测 的考虑,便产生了一种专门用于监测单片机程序运行状态的模块或者芯片,俗称“之前,刷新了计数器的值的话,那么就不会产生复位信号,这个动作就是我们 经常说的喂狗。2.在窗口期内重装载计数器的值,防止复位,也就是所谓的喂狗。4·独立看门狗的时钟由独立的RC。
2023-04-11 20:25:03 1551
原创 [STM32F103C8T6]基于esp8266模块的wifi控制
工作中一般不直接在中断服务函数里处理数据,而是在收到数据后直接丢给队列,再处理数。无论是蓝牙也好,wifi控制也好,本质都是通过串口收发数据。在中断服务函数里尽量减少使用延时函数及打印函数。通过单片机透传AT指令,连接wifi和服务器。UART2用于测试esp8266是否进行,通过cubemx来创建工程。串口中断,重写虚函数。
2023-04-11 16:43:39 2141
原创 [STM32F103C8T6] 串口
很多人在用printf函数进行串口打印的时候,都会被告知需要重定向fputc函数(别的平台可能不是这个函数),让字符串数据输出到指定串口,按照网上的教程也能很快解决。但是却没人告诉你为什么可以被重定向,为什么明明使用的是printf函数,重定向的却是fputc函数?给你,当你需要用的时候添加 即可,但是很多时候,fputc 输出的位置可能需要改变,比如输出到 LCD、串口1、串口2,我们总不可能去修改标准库的源码吧,但也没有源码提供啊,形参 3:要发送的数据大小,以字节为单位。
2023-03-14 15:35:56 2047
原创 [STM32F103C8T6] 超声波测距
波回来的那一下,我们开始停止定时器,计算出中间经过多少时间。Trig ,给 Trig 端口至少 10us 的高电平。距离 = 速度 ( 340m/s ) * 时间 /2。Echo信号,由低电平跳转到高电平,表示开始发送波。Echo,由高电平跳转回低电平,表示波回来了。实验目标:超声波测距:小于5cm,led被点亮,反之熄灭。Echo引脚维持高电平的时间!波发出去的那一下,开始启动定时器。
2023-02-15 21:50:09 1493 1
原创 [STM32F103C8T6]PWM呼吸灯
假设频率为2kHZ 因为Tclk = 72MHZ,所以Prescaler = 71,通过数据手册可知,PB8对应的是TIM4,3通道。
2023-02-15 17:39:53 1582 1
原创 [stm32f103c8t6] 定时器闪烁led
首先,定时器时钟信号送入16位可编程预分配器(Prescaler),该预分配器系数为0~65535之间的任意数值。首先,定时器时钟信号送入16位可编程预分配器(Prescaler),该预分配器系数为0~65535之间的任意数值。:这是一个集成在Cortex M3内核当中的定时器,它并不属于芯片厂商的外设,也就是说使用ARM内核的不同厂商,都拥有基本结构相同的系统定时器。这类定时器最具代表性,使用也最广泛。1.首先找到定时器溢出回调函数,重写回调函数,产生定时器中断后,会进入重写的回调函数内执行此函数。
2023-02-14 23:13:09 516
原创 [IAP15F2K61S2]工厂灯光控制系统
解决方法:由于数码管显示和led亮灭都是使用的P0口,而锁存器转换是需要时间的,所以,定义一个中间变量,先操作中间变量再赋值给P0口(KEY.c和Uart.c中有使用),每次转换完锁存器后都要P2口高三位置0,锁存。解决方法: P0_uart = (P0_uart | 0x0f) & (~(tmp) | 0xf0);解决方法:先初始化蜂鸣器在初始化led,如果先初始化led后初始化蜂鸣器,led会全亮。(与,或操作必须打括号,提高优先级,不然会出bug)2. 初始化led和蜂鸣器后,led任全亮。
2023-02-11 14:49:22 404
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人