- 博客(48)
- 收藏
- 关注
原创 Myplater项目
基于Mplayer的视频播放器1.需求分析:1.该程序能够加载指定路径下所有的音视频文件2.能够通过界面操作视频播放器支持:上键下键回车ESC支持:焦点定位1.一级页面功能如下:| 视频播放器 ||1.查看播放列表 ||2.开始/暂停 ||3.停止 ||4.上一个 ||5.下一个 |
2025-02-14 17:12:25
1121
原创 GD32F470Z外部晶振不起振
接下来就是测试,将示波器来查看晶振的波形,就是将示波器的夹子连接晶振旁边的数字地,如果连的是模拟或者电源进来的地也能出来结果就是不太平稳。跳转到__SYSTEM_CLOCK_240M_PLL_25M_HXTAL对应的系统时钟配置函数:system_clock_240m_25m_hxtal(void)这里我的外部晶振使用的是25M,就用25M来举例,如果使用别的,找到对应的晶振,操作相同。是25M,没问题,如果不是你所用的晶振的值,修改为你所用的晶振的值。系统的时钟使用的是内部晶振。然后跳进去所对应的晶振。
2025-01-14 13:55:31
692
原创 **JLink Warning: CPU did not halt after bootloader.
J-LINK下载的时候出现以下的问题,就是下载成功了,但是debug,设置断点的时候发现程序并没有跑起来,是因为boot0设置有问题,在板子上把boot0接低电平,问题就解决了。就可以下载并且debug代码也跑起来了。Load "E:\\气体检测\\代码\\20250106\\gas_detection\\Objects\\test.axf"0 1 相当于是一个存储器里面装了一个程序,叫bootloader,他有一个功能,就是帮你把程序烧写到 主flash里面。遇到这个问题,亲测解决了,解决的方法如下。
2025-01-11 19:36:14
569
原创 驱动-----platform
注册一个adc的设备,也就是给platform的设备列表里面加adc,platform识别后遍历左边的驱动列表是否有adc,有的话就开始注册完整的设备驱动程序,没有的话就结束了。其实没什么关系,输出高低电平和引脚没多大关系,所以这俩个分开注册,方法只管操作方法,不管你用的什么,资源只管你用的什么不管你用什么操作方法,也就是设备的资源和设备的操作方法能分开。这样一个完整的驱动就有俩部分,一个是设备的,一个是驱动的。没有安装j-link的驱动的时候,把j-link插到电脑上,有资源,但是没有操作方法。
2024-11-12 14:56:50
264
原创 驱动-----中断底半部
从打印的这里也可以看出来中断调用底半部中断之后返回,然后才执行底半部中断,没有等底半部中断结束然后返回。中断源调用中断程序后,中断程序再去调度中断底半部,不等调度的程序执行完毕,继续执行原来的程序。之前处理中断在中断服务程序里面,就是我们自己注册了一个中断服务程序,一产生中断就自动调动这个程序。异步调用:就是不等调用的函数执行完毕,回到原来的位置继续向下执行(线程执行)中断调用底半部tasklet,然后就返回,这时候底半部自己运行。中断上下文:中断相关操作,中断服务程序、软中断、tasklet。
2024-11-07 20:55:45
414
原创 驱动-----dht11温湿度传感器
复位信号:设置为输出模式,低电平20ms,然后再拉高30us。然后设置为输入模式,dht11会先拉低80us,然后拉高80us表示对接成功。数据0:开始先拉低50us,然后拉高26~28us表示0。数据1:开始拉低50us,然后拉高70us表示1。每传输一位的数据都要间隔一个拉低50us。单总线:只用一根线。
2024-11-06 21:27:57
239
原创 驱动-----adc多通道
我们前面使用adc的时候,单通道,使用的是AIN0通道,那要想使用1、2、3通道该怎么去修改呢?那再修该上面的adccon的值然后重新写一个几乎一样的adc驱动也不适合。在write里不太合适,write写进来没有流向,比如说led流向硬件,设置通道口就类似于设置波特率,所以要实现一个新的接口。. . . : 参数,比如说设置波特率,数据位,检验位,来选择设置的东西。那么我们怎么在原有的驱动上面修改,来多采集几个通道的值。打印这个ret的返回值,并且看看出错的原因。int fd:文件描述符。
2024-10-31 18:21:16
330
原创 驱动-----GPIO子系统
前面init里面request申请了一个资源,要释放掉,封装一个释放的函数。子系统:就是linux封装了很多函数,操作gpio,iic等。int level就是输出高低电平,所以前面定义一个宏。所以在使用的时候引脚可以调用系统的接口。最后在注销的时候调用这个函数。
2024-10-31 15:12:59
234
原创 驱动-----混杂设备驱动(misc)
混杂设备驱动:键盘鼠标是输入,显示是输出,灯按键等不太好分叫做混杂设备,这样主设备号就可以用一个(10),用次设备号来区分。这样其实就不用手动创建设备节点了。这里用的是系统的主设备号。混杂设备驱动注册的时候,用miscdevice。注册的时候,注册一个misc_register。
2024-10-31 14:55:23
248
原创 驱动-----adc
上面的裸机代码,是读启动,先读一下,然后启动转换,判断是否转换结束,结束后跳出循环,返回读取的数据,在驱动里面就不能这样了,万一转换不结束,就会一直在等,这次就不要读启动了,用手动的启动。还有就是内核想修改,省电低功耗,默认把所有的时钟都关闭,在使用的时候要去打开时钟。这里我们使用ENABLE_START,然后a/d转换启动,转换完成后adc会有一个中断,然后进入中断服务程序里面。按键和adc的区别是什么,按键只需要按一下就触发了,并且不需要返回一个值出来,这里申请的终端需要修改一下,申请的adc的中断。
2024-10-30 23:20:47
509
原创 驱动-----按键中断
就是要和应用层联系起来,设置一个condition的判断条件,read的时候设置为0,这样在wait_event()里面就会加入等待队列等待处理,当使用wake_up()唤醒的时候,就是要去执行schedule()调度,来处理中断,所以要在wake_up()之前把condition置1,这样就会在wait_event()里面跳出for循环去执行schedule()。没有按下就会一直阻塞在这里,学习一个阻塞模型,这样的话cpu一直浪费在这里,所以好的方式就是cpu干其他的事情,啥时候被按下了啥时候唤醒。
2024-10-30 03:24:57
956
原创 驱动-----动态加载
这里有个细节需要注意,就是之前我们编译生成的uImage里面有demo1的静态模块,所以,我们先要去掉这个静态模块,怎么去除呢?就是重新选择,去掉demo1的模块,然后进行编译生成uImage,这样就没有demo1了,然后把这个生成的uImgae复制到tftp的服务目录下,然后板子下载。这个就是所有被设置成M的都会被编成模块,链接生成动态的.ko文件。当我们需要改动这个模块重新加载的时候,那就需要把原来旧的卸载掉。这句话的意思就是别人有权使用和修改,遵循一种协议,就是可以开源。这样就成功加载了动态模块。
2024-10-29 15:44:28
203
原创 驱动-----LED
第三个参数:传递数据的长度,如果写sizeof(data),假如传递过来的数据大于data的大小,那么会发生越界,如果写sizeof(buf),那也不合适,那么就需要去比较传递过来的数据的大小和我们定义的data的大小,选择小的那个。我们忽略了一个问题,那就是自创建设备节点的时候没注意,其实254已经被占用了,所以,有俩个254,那么先出现的就会被执行,后面的led都来不及去执行,所以要换个节点。前面我们学习了demo1的驱动的编写,在写LED的时候,我们可以在demo1的基础上修改。
2024-10-28 18:14:18
542
原创 驱动----字符设备驱动
APP中open(/dev/led) ------->kernel中sys_open(led)------->去找到文件中记录的led 1------>找到内核中的LED_DRI驱动(有自己的open,read,write,close来控制引脚等)------>控制硬件中的LED设备。用的时候要注意,有多个文件的时候,tages要在顶端目录去创建,那么我们在后续写这个驱动程序的时候,不是cd到这个文件的目录去编辑这个程序文件,要在顶端目录去打开这个程序文件来编写。接着我们就要去实现这几个函数。
2024-10-25 19:14:50
747
原创 驱动-----向内核新加文件
Kconfig来定义make menuconfig的配置,make menuconfig的配置保存在.config里面,makefile编译的时候用的是.config保存的配置。makefile添加新的编译对象------Kconfig来定义这个宏-------make menuconfig来配置-----.config保存这个配置。那么如果在A目录下的Kconfig想要使用B目录下的Kconfig中的宏的定义,我们需要把BKconfig的路径加到A 中的Kconfig中。
2024-10-25 01:00:40
495
原创 驱动-----内核编译
只有短跳转的时候,程序加载到任何的地方都可以,但是有了长跳转,就有限制了,程序必须放在对应的位置上去,这里因为程序给pc赋值就是0x30008000,所以要把程序放在0x30008000的位置,我们下载的时候就下载到了0x30008000的位置了,那为什么还是运行不了程序呢?当有100个.c文件的时候,会生成100个.o文件,这样数量太多,我们在做产品的时候,不可能把.c文件给出去,给的是.o文件,但是.o给的太多也不方便,那就是把所有的.o文件组成一个文件,这个过程叫做归并。这里的a.out就没有变过。
2024-10-23 00:23:55
652
原创 驱动-----内核启动
存放在Nandflash中,当运行内核的时候内核被拷贝在内存中运行,起始的地址是0x30008000 (PC指向该位置) ,也可以放在ubuntu上 。主机的输入是键盘,输出是显示器,这里用的是一个主机A通过串口连接另一个主机B,主机B是输入和显示,这种交互模式,上面这张图里面的内容就相当于主机B。
2024-10-20 21:12:15
898
原创 嵌入式-----汇编语言
那我们就来解决这个问题(1)传参的问题:写一个c语言,调用c语言的函数来计算这里调用c语言的函数的时候要用import来声明一下,使用外部函数。这里还存在一个问题,就是c语言中的a是多少,b是多少,和寄存器r0和r1又有什么样的关系呢,让我们来研究一下最后的结果是a, b , c, d, 是1 2 3 4 而 e f 的值就不是 5 60xE3A00001就相当于mov r0 #1 意思就是个r0 赋值1。
2024-09-08 23:13:59
1445
原创 ARM----时钟
时钟频率可以是由晶振提供的,我们需要高频率,但是外部接高的晶振会不稳定,所有使用PLL(锁相环)来放大频率。其实在配置的时候我们要先配置HCLK .PCLK,因为先配置FCLK的时候,频率太高,会烧坏后面的电路,所以先配置好分频,在区配置主频。外部晶振提供12M频率,由MPLL来进行放大,具有放大多少怎么配置,由PDIV、MDIV、SDIV,来决定。6.由FCLK的大小来查手册看MDIV ,PDIV, SDIV的值(用来配置FCLK的大小)这是手册上面,通过OM2和OM3的引脚的电位来设置时钟源。
2024-09-06 21:22:28
1118
原创 linux------数据结构
数据量增长与程序运行时间的比例关系以函数描述称为时间渐进复杂度函数,简称时间复杂度。数据量增长与程序所占用空间的比例关系称为空间复杂度。3.链表空间不连续,使得理论上长度是无限的。2.链表需要更大的空间存放数据和节点地址。1.空间可以不连续,访问元素不方便。程序 = 数据结构 + 算法。4.链表的插入和删除效率很高。
2024-08-27 18:59:31
452
原创 Linux网络编程-----协议、UDP和TCP编程、Http
8位,所以最多是2的8次方,范围就是 0~255,最大255,由于0,和1 特殊,所以最多可以用253个。子网掩码展开成二进制,1对应的部分就是IP地址的网络位,0对应的部分就是IP地址的主机位。2.将发送端套接字与IP地址和端口号绑定-------bind。3.为目的地址赋值-------htons,inet_addr。B---->A : ACK 收到信号,若是信号不完整,发剩下的信号。B---->A : ACK+SYN 回复应答,并且请求应答。
2024-08-15 20:39:11
906
原创 linux软件编程-----进程
2.这里有俩个hello word,其中第一个hello world是子线程的,这里是因为在父进程创建子进程之前的时候,打印hello world的时候只是放在了缓冲区,并没有满足刷新缓存区的条件,而子进程在创建的时候会同样复制缓冲区的东西,所以在满足缓冲区刷新的条件的时候被打印出来,所以第一个hello world是子进程缓存区所存的数据被打印出来,第二个是父进程所打印出的。这里的ptmp的地址是一样的,因为子进程和父进程公用同一个虚拟空间,只是在不用的时刻而已,但是实际的物理地址是不同的。
2024-08-06 20:49:34
829
原创 linux软件编程---makefile
3.makefile维护文件时间戳,需要编译的重新编译,不需要重新的编译则省略编译的时间。1.Makefile是一个文件,工程代码编译规则写在makefile文件中。文件名:makefile Makefile(文件名和文件名之间用空格隔开)= 之前没被赋值则赋值,之前被赋值不再重复赋值。$@ :目标文件(你所要操作的文件)5.在终端输入指令make + 指令可以使用。要生成的文件:所有依赖的文件。$< :第一个依赖文件。$^ :所有依赖文件。= 赋值。:= 覆盖。
2024-08-05 17:17:26
163
原创 Linux软件编程----文件IO,目录文件,链接文件,文件详细信息获取
文件IO:1.打开文件 open2.读写文件 read write3.关闭文件 close。
2024-08-01 19:49:07
728
原创 Linux软件编程----标准IO
操作对象:文件Linux系统一切皆是文件:文件分类:1.block b 块设备文件 按块扫描设备信息的文件2.char c 字符设备文件 按字符扫描设备信息的文件3.directory d 目录文件 保存或管理文件4. - 普通文件 保存数据信息的文件(代码、图片、音视频、压缩包等)
2024-07-30 18:42:04
805
原创 嵌入式-----linux系统及其配置
Linux内核:Linux操作系统的核心代码,包括对CPU管理、硬件设备管理、内存管理、文件系统管理、进程调度管理等。tar -jcvf 文件名.tar.bz2 文件名/*tar -zcvf 文件名.tar.gz 文件名/*在文件名对应的文件中查找字符串相关的行。tar -jxvf 文件名.tar.bz2。tar -zxvf 文件名.tar.gz。查找文件名对应的文件所在的路径。在路径下查找文件名对应的文件。[a-z]:匹配a-z之间的任意字符。[1-9]:匹配1-9之间的任意字符。
2024-07-30 17:56:26
568
原创 嵌入式-----c语言(9)堆空间的使用和链表(练习)
1.函数体内部的局部变量会随函数结束被回收,可以考虑存放到堆区空间中避免随函数结束回收。当使用strcat、strcpy、strcmp函数时可能会产生内存越界。注意:操作指针时,注意指针指向的空间是否存在?2.C语言中可变长数组可以通过malloc实现。如果成功,返回指向申请空间的指针。字符串缺少\0导致的越界访问。申请size个字节的堆区空间。size:申请空间的大小。ptr:堆区空间首地址。1.数组是有限个元素的集合。3.数组的插入和删除效率低。申请的堆区空间没有被释放。2.数组的空间必须连续。
2024-07-29 08:35:07
415
原创 嵌入式-----c语言(8)结构体
1.存放结构体成员变量,必须保证前面的长度为成员变量所占空间大小的整数倍。2、找出有两门以上课程不及格的学生,输出他们的学号和全部课程成绩及平均分。1.枚举常量第一个值默认为0,后面的枚举常量为前一个枚举常量的值+1。括号 > 单目 > 双目 > 三目 > 赋值 > 逗号。2.结构体整体的大小必须为最大类型长度的整数倍。算数 > 移位 > 关系 > 位运算 > 逻辑。2.枚举类型对应的变量的值应该为枚举常量中的值之一。1.小端:内存低地址存放低数据位称为内存小端。不改变其余位的前提下,让第n位置1。
2024-07-29 08:33:45
346
原创 嵌入式-----c语言(7)函数指针和指针函数(补)
1.char *、int *、double * 转换为void *时需要强制类型转换。2.void *转换为char *、int *、double *时不需要强制类型转换。2.指针数组的数组名是指向数组第一个元素的指针即二级指针。结构体访问成员变量最终的类型由成员变量的类型决定。void *只表示类型地址,没有指向空间大小的含义。-> :结构体指针类型访问成员变量。数据类型1 成员变量1;数据类型2 成员变量2;数据类型3 成员变量3;指针函数是函数,函数的返回值是指针。函数指针是指针,指针指向一个函数。
2024-07-29 08:32:08
389
原创 嵌入式-----c语言学习(6)数组指针和指针数组(补)
指针数组是数组,数组的每个元素是指针数组指针是指针,指针指向一个数组int *a[5];//指针数组定义数组a,占40个字节空间,共有5个元素,每个元素为int*型指针//数组指针定义一个指针变量p,占8个字节空间, 指向一个int类型5个元素的数组的指针,指向20个字节空间。
2024-07-24 18:35:57
381
原创 嵌入式-----c语言学习(5)指针和数组的关系
1.字符串在函数中传参时,只想让函数体内使用字符串,而不允许通过指针改变字符串的值使用const。const修饰p和*p, 指针变量p的值不能变,也不能利用*p改变指向空间中的值, 一定要对指针初始化。const修饰p, 指针变量p的值不能变, 但可以利用指针修改指向空间中的值, 一定要对指针初始化。const修饰*p, 指针变量p可以修改指向的空间,但不能利用该指针修改指向空间中的值。练习:从终端接收一个字符串,编写一个函数统计该字符串中大写、小写、数字和空格的个数。指针[n] == *(指针 + n)
2024-07-23 20:36:56
442
原创 嵌入式-----c语言学习(3)函数
函数类型 函数名(数据类型1 形参1, 数据类型2 形参2, ...)函数体;return 返回值;函数名:和变量名要求保持一致函数类型:函数运行结果的类型(如果返回值类型与函数类型不一致,会将返回值强制类型 转换成函数类型返回)不写函数类型默认为int类型如果没有返回值,函数类型应该为void类型返回值:函数的运行结果形参:形式参数(做个样子)注意:函数没有返回值,return后面什么都不写。
2024-07-21 22:23:38
686
原创 嵌入式-----C语言学习(2)数组(随机数)
数组是相同类型有限个元素的集合数据类型 数组名[元素个数];int a[5];float f[5];注意:1.元素个数必须为常量或常量表达式,不允许是变量或变量表达式数据类型 数组名[第一维数组的元素个数][第二维数组的元素个数];数据类型 数组名[行数][列数];数据类型 数组名[元素个数];注意:1.字符型数组存放字符串,必须能够存放下末尾的\0字符2.元素个数必须为常量数据类型 数组名[第一维元素个数][第二维元素个数];
2024-07-21 22:01:37
673
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人