- 博客(38)
- 收藏
- 关注
原创 ARM裸机开发-PWM
本文介绍了基于I.MX6UL开发板的LCD背光亮度控制方法,利用PWM(脉宽调制)技术通过调节占空比实现背光亮度调节。通过配置PWM外设寄存器,设置时钟源、分频系数和周期值,结合FIFO中断机制动态更新采样值,实现占空比可调的PWM信号输出。代码中通过中断服务函数实时更新占空比,确保背光亮度平滑调节,有效提升显示体验并节省功耗。
2026-10-06 13:39:55
601
原创 ARM裸机开发-LCD
本文介绍了基于imx6ull的RGB LCD显示屏(ATK4384,800×480)的显示原理与初始化实现。通过分析分辨率、屏幕尺寸、像素颜色深度及同步信号(PCLK、HSYNC、VSYNC、DE),计算得出60Hz刷新率下像素时钟约为31MHz。硬件初始化包括设置引脚复用功能和电气属性,确保各信号线正确配置,为后续图像显示奠定基础。
2026-10-05 22:50:38
186
原创 ARM裸机开发-SPI
SPI(串行外设接口)是Motorola定义的高速、全双工、同步串行通信协议,仅需四根线(SCLK、MOSI、MISO、CS),广泛用于EEPROM、传感器等设备。其通信模式由CPOL和CPHA决定,共四种工作模式。本文以IMX6ULL平台为例,介绍了SPI3通道的引脚复用配置、寄存器设置及初始化流程,并实现ADXL345传感器的读写操作,通过发送寄存器地址与占位字节完成数据交互,验证了SPI在嵌入式系统中的高效应用。
2026-10-04 00:30:35
333
原创 ARM裸机开发-ADC
本文介绍了IMX6ULL芯片中ADC外设的工作原理与配置方法,包括采样、量化及分辨率概念,重点阐述了基于逐次逼近法的12位ADC实现。通过寄存器配置(如时钟分频、基准电压选择、通道设置等)完成引脚复用与电气属性设置,并实现校准、单次转换读取及模拟值转换。代码示例展示了初始化、校准、读取原始数据及转换为实际电压的过程,最终输出0~3.3V范围内的精确模拟信号值。
2026-09-29 01:21:43
422
原创 ARM裸机开发-I2C-LM75
本文基于i.MX6ULL平台,实现LM75温度传感器的I2C通信读取。通过改进寄存器地址与长度的定义(使用unsigned short和int),提升代码通用性。采用Linux I2C核心层架构,封装i2c_transfer接口,通过master_xfer函数统一调用底层适配器驱动,实现跨芯片兼容。最终通过读取2字节温度数据并右移7位,计算得温度值,精度达0.5℃,验证了驱动分层设计的高效性与可移植性。
2026-09-28 15:26:24
389
原创 ARM裸机开发-I2C-E2PROM
本文介绍了I2C通信协议的基本原理与AT24C02 EEPROM的使用,涵盖I2C时序、设备地址与寄存器地址区别、硬件配置(引脚复用、上拉电阻)及基于IMX6ULL的I2C读写实现。通过配置I2C1时钟分频、电气属性,并编写初始化与读写函数,实现了对AT24C02的读写操作,重点说明了起始/停止信号、应答机制及重发设备地址的读时序流程。
2026-09-27 23:45:35
411
原创 ARM裸机开发-UART
本文介绍基于IMX6ULL平台配置CH340C串口通信的实现过程。通过设置IOMUXC引脚复用与电气属性,启用UART1收发功能;利用UCR2、UCR3、UFCR寄存器及UBMR/UBIR计算115200波特率;编写putc、puts、getc函数实现字符发送与接收;最终导入stdio库,通过scanf与printf实现数据交互,结合VOFA软件完成串口通信调试。
2026-09-27 00:58:17
444
原创 ARM裸机开发-EPIT与GPT
和 t3 这三个时刻会触发按键中断,每次进入中断处理函数我们都重新开器定时器中断,所以会在 t1、t2和 t3 这三个时刻开器定时器中断。接下来我们学习如何使用定时器来实现按键消抖,使用定时器既可以实现按键消抖,而且也不会浪费CPU 性能,这个也是 Linux 驱动里面按键消抖的做法。中间为计数器,装入初值,每减一次与比较寄存器比较,若比较成功,ITIF置1(中断标记位),(最后记得清零),此时若ITIE为1(中断使能位),则通过与门为真,发出中断,同时,Load加载寄存器,给初值寄存器重新赋值。
2026-09-26 18:03:23
473
原创 ARM裸机开发-时钟
先采用step_clk路,通过选通门选择osc_clk或者下面的时钟频率,先将ARM的工作频率切换为24MHZ,再配置PLL,设置二分频率,待稳定后切换为pll1_main_clk传给ARM.PLL1为内核配置时钟,PLL2为外设配置时钟,PLL3为USB设备配置时钟,一共7个PLL,8个PFD。可见,只需修改FRAC域配置PFD倍频因子,CLKGATE打开cg门。PLL2锁倍频,所以参考手册没有,只需修改PLL2下的4个PFD。选中PLL2,设置AHB倍频因子,IPG倍频因子。下图为该芯片的时钟配置。
2026-09-25 22:09:11
498
原创 ARM裸机开发-中断
可以读出GIC的基地址,不过可以通过Cortex-A7的固件库实现,即初始化GIC函数inline:内联函数,本质是函数,调用内联函数前,必须有该函数的定义,编译时,内联函数会在函数调用位置被展开,类似宏,就地展开,不用跳转函数,提高函数执行效率,可在头文件中定义函数。
2026-09-24 06:37:20
466
原创 ARM裸机开发-蜂鸣器与按键
显然底层源码通过宏定义,指定了对应的GPIOx的基地址,将GPIOx的基地址强转为GPIO_Type *的指针,而GPIO_Type则为定义了GPIO里的8个寄存器的结构体,如此即可通过GPIOx指针访问对应结构体成员的寄存器进行赋值。先是引脚的名字,再是引脚的具体复用功能,不同引脚具有不同的复用功能,如下图所示,上篇点亮LED灯对应的GPIO1_IO03引脚具有多个复用功能,而SNVS_TAMPER1则只有GPIO5_IO01的功能。显然CCM_Type结构体同GPIO一样,内部定义了对应的寄存器。
2026-09-22 12:56:01
505
原创 ARM裸机开发-点亮LED灯
本文开始在VScode上使用IMX6ULL以真机进行学习,芯片原理图参考如下。:这是整块板子的“大脑”。NXP(恩智浦)的 IMX6ULL 基于架构,主频通常在 528MHz 或 800MHz。:相当于电脑的。它是掉电丢失的。当 Linux 系统启动时,,它负责临时存放程序运行时产生的大量数据。:相当于电脑的。它是掉电不丢失的。用来永久存放系统镜像(uboot、kernel、设备树、rootfs文件系统)和用户程序。
2026-09-19 23:59:25
494
原创 ARM裸机开发-汇编基础
4位旋转位若直接表示位移0-15位,则立即数最大只能位移15位,无法覆盖32位寄存器的所有角落,故×2,最终 32 位立即数 = imm8 循环右移 2×rotate 位(移位步数永远是偶数:0、2、4 …30 位,硬件无法实现移位奇数位,易知,能表示的最大立即数为0xFF00 0000,即0xFF循环右移8位,rotate=4,12位则为0x4FF)最高位1至最低位1之间的二进制数序列:0011 1110 1010 1101 从第一个1开始到最后一个1之间超过8位,不满足条件1,所以这个数不是立即数。
2026-09-18 00:59:30
430
原创 Linux网络编程-sqlite数据库
create table 表名(列名1 数据类型1, 列名2 数据类型2, 列名3 数据类型3);CREATE TABLE 表名(列名1 数据类型1, 列名2 数据类型2, 列名3 数据类型3);select * from class1 where name like "马__";select * from class1 where name like "马%";insert into 表名 values(值1, 值2, 值3);select 列名1, 列名2 from 表名;
2026-09-10 00:02:05
386
原创 Linux网络编程-TCP并发服务器
单循环服务器:只能处理一个客户端任务的服务器。并发服务器:可以同时处理多个客户端任务的服务器(一对多)。UDP服务端:具备并发性能TCP服务端:建立连接,单循环服务器。进程资源开销大,在有限平台下,并发量比较小。资源开销小,在相同平台下,并发量比多进程大。多线程模型在客户端建立连接时,创建线程和销毁线程有时间消耗。生产者-消费者设计模式主线程:生产任务线程池:执行任务任务队列在不创建新进程/线程的前提下,使用一个进程同时检测多路IO。IO:对文件读写sockfd。
2026-09-07 00:18:54
501
原创 Liunx网络编程-应用层
keep-alive: 长连接:HTTP通信结束,保持一定时间的连接再断开。GET / HTTP/1.1\r\n (/表示主页)close:短连接:HTTP通信结束,立马断开连接。基于传输层TCP协议,端口80。HTTPS :SSL加密方式。1. HTTP协议工作流程。
2026-09-05 16:09:56
542
原创 Liunx多任务-IPC机制
无名管道:只能用在具有亲缘关系的进程间通信(父子进程)操作流程:1.创建并打开管道:pipe();2.读管道:read();3.写管道:write();4.关闭管道:close();参数:pipefd:管道读端和写端的文件描述符pipefd[0] 读端pipefd[1] 写端返回值:成功:0失败:-1管道的特点:管道本质是内核中的一段缓冲区,默认64K字节,遵循队列存储方式(FIFO),
2026-08-28 22:50:02
472
原创 Linux多任务-线程篇
线程最直接的理解就是轻量级进程,它是一个基本的CPU执行单元,也是程序执行流的最小单元,由线程ID、程序计数器、寄存器集合和堆栈组成。线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但。。由于线程之间相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。
2026-08-28 09:59:19
500
原创 Linux多任务-进程篇
进程:正在执行的程序实例,需要消耗内存和CPU,是系统进行资源调度和资源分配的独立单位。进程是由多道程序的并发执行而引出的,它和程序是两个截然不同的概念。程序是静态的,进程是动态的,进程的基本特征是对比单个程序的顺序执行提出的。1)动态性。进程是程序的一次执行,它有着创建、活动、暂停、终止等过程,具有一定的生命周期,是动态地产生、变化和消亡的。动态性是进程最基本的特征。2)并发性。指多个进程同存于内存中,能在一段时间内同时运行。引入进程的目的就是使进程能和其他进程并发执行。
2026-08-25 17:21:30
511
原创 Linux C语言文件操作:从标准IO到文件IO的全面解析
在Linux系统编程中,文件操作是核心技能之一。内存(变量、数组、数据结构)读写数据速度快程序执行结束、掉电后数据丢失空间小,价格昂贵文件(外存/硬盘)读写速度比内存慢掉电后数据不丢失空间大,相对内存价格便宜文件的主要作用有两个:一是长期保存掉电不丢失的数据;二是作为Linux提供给应用层的硬件操作接口,体现了“一切皆文件”的设计哲学。
2026-08-20 19:30:29
627
原创 朝花夕拾 · 数据结构 | 哈希表篇
在构造散列函数时,必须注意以下几点:1)散列函数的定义域必须包含全部关键字,而值域的范围则依赖于散列表的大小。2)散列函数计算出的地址应尽可能均匀地分布在整个地址空间,尽可能地减少冲突。3)散列函数应尽量简单,能在较短的时间内计算出任意一个关键字对应的散列地址。下面介绍常用的散列函数。代码实现:哈希表的定义。
2026-08-19 16:58:29
480
原创 朝花夕拾 · 数据结构 | 二叉树篇
非空二叉树上的叶结点数等于度为2的结点数加1,即。证明:设度为0,1和2的结点个数分别为n0,n1和n2,结点总数n=n0+n1+n2。再看二叉树中的分支数,除根结点外,其余结点都有一个分支进入,设B为分支总数,则n=B+1。这些分支是由度为1或2的结点射出的,因此又有B=n1+2n2。于是得n0+n1+n2=n1+2n2+1,则n0=n2+1。非空二叉树的(k≥1)。第1层最多有2^(1-1)=1个结点(根),第2层最多有2^(2-1)=2个结点,以此类推,可以证明。
2026-08-18 19:51:10
429
原创 朝花夕拾 · 数据结构 | 队列与栈篇
1.队列的定义队列(Qucue)简称队,也是一种操作受限的线性表,只允许在表的一端进行插入,而在表的另一端进行删除。向队列中插入元素称为入队或进队;删除元素称为出队或离队。这和我们日常生活中的排队是一致的,最早排队的也是最早离队的,其操作的特性是先进先出(FirstInFirst Out,FIFO),如图所示。队头(Front):允许删除的一端,也称队首。队尾(Rear):允许插入的一端。空队列:不含任何元素的空表。顺序队列的两种定义:1.2.以第一种定义为例,以下为相关CRUD功能实现。
2026-08-17 17:48:36
454
原创 朝花夕拾 · 数据结构 | 链表篇
线性表的链式存储也称单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素。为了建立数据元素之间的线性关系,对每个链表结点,除存放元素自身的信息外,还需要存放一个指向其后继的指针。单链表结点结构如图2.3所示,其中data为数据域,存放数据元素;next为指针域,存放其后继结点的地址。typedef struct Node //定义结点结构int data;}Node;typedef struct //定义链表结构int len;}Link;
2026-08-13 18:47:47
684
原创 朝花夕拾 · C语言 | 多文件篇
4.在对应的头文件中加extern关键字声明,头文件中全局变量只能声明不能初始化,定义应在.c文件。Makefile:管理代码工程的编译和链接,由make工具进行解释,实现一键化工程的编译和链接。依赖文件(生成目标文件所依赖的源文件):main.c sum.c sub.c ......编译规则:gcc main.c sub.c sum.c ( -o a.out)在头文件的声明里,函数默认为extern,编译器会自动加上。2.如果只是在定义该全局变量的文件中使用该全局变量,可以不声明;
2026-08-11 14:27:59
393
原创 朝花夕拾 · C语言 | 调试篇
l 列出原代码。q 退出gdb。r 运行程序。S 跟进函数。1.编译程序:-g选项:允许使用gdb进行调试。gnu提供的Linux下的代码调试工具。b+行号 在指定行打断点。p+变量名 查看变量值。where 定位段错误的位置。1.使用gdb调试逻辑错误;2.使用gdb调试段错误。gdb./可执行程序。
2026-08-10 18:20:15
156
原创 朝花夕拾 · C语言 | 位运算篇
<按位左移 按位左移,低位补0 num << n <===> num *2^n。>>按位右移 按位右移动,有符号数高位补符号位:无符号数高位补0。| 按位或 有1则1,全0为0。~按位取反 1取反为0,0取反为1。1010 0010 //低四位置0。& 按位与 全1为1,有0则0。^ 按位异或 相同为0,相异为1。3.两数交换(不使用中间变量)
2026-08-10 11:53:02
299
原创 朝花夕拾 · C语言 | 预处理命令篇
预处理:展开和#相关的代码:展开头文件、展开宏、处理预处理命令编译:将c语言程序转换成汇编指令。汇编:将汇编指令转换成二进制可执行程序链接:负责链接系统的函数/库函数的实现(链接函数)
2026-08-03 17:35:30
384
原创 朝花夕拾 · C语言 | 指针篇
基类型 *变量名;基类型:该指针指向的空间存储的数据的数据类型:int、char、float 、double 、void、构造数据类型* : 类型说明符,说明后面的变量是一个指针变量名:遵循标识符的命名规则p开头指针变量中保存的地址,是该数据类型的首地址。
2026-08-03 16:04:40
408
原创 朝花夕拾 · C语言 | 数组篇
数组一般形式:类型说明符 数组名 [常量或常量表达式];类型说明符:基本数据类型、构造数据类型(不能是void类型)。说明数组中保存的数据的数据类型。数组名:遵循标识符的命名规则。常量或常量表达式:数组中可以保存的元素的个数。int a[10];sizeof (a);//40字节//32字节//20字节注意:常量表达式中可以包括常量和符号常量,不能包含变量。也就是说,C语言不允许对数组的大小作动态定义,即数组的大小不依赖于程序运行过程中变量的值。例如,下面这样定义数组是不行的。
2026-07-28 17:05:55
714
原创 朝花夕拾 · C语言 | 函数篇
此外 ,%f 不能接收double型,且双引号里写了什么,在输入时也要相同,所以除了格式控制符之外尽可能少写其他数据。八进制与十六进制也可指定输出域宽,如%8o表示输出八位八进制数,%8x表示输出八位十六进制数;此外,%lo与%lx则可表示以八和十六进制输出long型。在输入整型时,可以使用空格,Tab与Enter隔开两数,除此之外用其他字符则会直接中断输入,舍弃后续读入的数字。域宽输出: 7. %nd 以n位域宽输出,若数据大于n位则以实际位数输出,否则左侧补空。
2026-07-24 17:52:16
347
原创 朝花夕拾 · C语言 | 基础篇
你是否曾与C语言初次相遇,许多概念一知半解。如今带你重走来时路,从头梳理语法、指针、内存、结构体等,陪你扫清底层盲区,为嵌入式开发筑牢根基。以此系列博客,记录复盘全过程。
2026-07-22 18:56:31
388
原创 基于 Ubuntu 的 linux操作系统基础入门
du -h --max-depth=1 /home/linux - 查看家目录下磁盘占用情况,根目录没有权限查看。ESC进入命令行,nyy从光标开始位置复制n行,p粘贴,u撤回,Ctrl+Shift+v将外面代码复制。mkdir - 创建文件夹,rmdir - 移除文件夹(必须为空),rm -r - 什么都能删。cp 可将文件拷贝到文件或文件夹,cp -r 可将文件夹拷贝。ls -a - 显示所有文件,包括隐藏文件(.开头的文件)du -h --max-depth=1 + 文件夹名称。
2026-07-21 18:11:07
316
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅