一、嵌入式系统硬件介绍
cpu + RAM(内存) + FALSH 集成(flash存储设备) = MCU/单片机
AP/ MPU
进化之后可以外接内存和存储设备,跑复杂的操作系统,比如手机
cpu一上电就会执行程序,程序存放在片内的ROM中,帮助运行SPI flash启动程序,变量存放在RAM中
cpu发出的地址到哪里中间会经过一个内存控制器,将cpu的指令发给各种控制器,ROM、ROM
IMX6ULL 点灯
点亮LED
1、看原理图确定控制LED的引脚
2、看主芯片手册确定如何设置/控制引脚
3、写程序
控制芯片的引脚1还是0,来控制输出电压
1、将GPIO模块组使能
2、设置多路选择器IO_mux,设置gpio是连接到那个模块
3、设置GPIO口是输出还是输入
4、设置gpio输出高低电平
对引脚的操作不能影响到其他位,因为一个寄存器有很多位,每一个位都是一个引脚
直接设置寄存器 reg = 1,bit0 = 1、bit1= 0、bit2= 0,后面两个被强制设置为0
使用一个函数set_reg = 1,bit0 = 1、bit1= 0、bit2= 0 ,只有第一位起作用,其他为0的无效
gpio口清零是使用clr_reg 只有1有效
1、使能某一组GPIO
2、选择引脚功能
3、
1、查看芯片看LED原理图,确定要操作的GPIO口
2、使能
寄存器CCGR1里面的CG13控制GPIO1组是否使能
3、设置为GPIO5_3为GPIO
GPIO模式
也就是要使得这个寄存器最后三位变成101
4、设置为输出功能
gpio5_3 设置为输出,就是在将改寄存器的引脚3设置为1(芯片引脚从0开始的)
绝对地址= 基地址 + 偏移地址
5、设置电位为高还是低(低就是点亮,高是熄灭)
o 表示高电位,1表示地电位
LED操作
怎么操作寄存器
定义一个指针,然后让指针指向寄存器,最后给指针赋值就是相当于给寄存器赋值
程序烧写
头部 + bin也就是 imx文件
头部文件负责告诉ROM将程序读到哪里去
运行流程
1、将代码烧写到板子上
2、头文件负责将告诉rom,要将emmc中的代码读到哪里去
3、运行汇编文件,start.s,设置sp,然后从下往上执行
4、运行main函数
程序
//延时函数void delay(volatile int d){while(d--);}int main(void){ volatile unsigned int *pReg;//加上voliate避免编译器优化 /* 使能GPIO5: 默认使能 *//* 把GPIO5_3设置为GPIO功能 */pReg = (volatile unsigned int *)(0x02290000 + 0x14); //将右边强制类型转换为指针类型,初始化*pReg |= (0x5);//修改寄存器,设置为GPIO功能/* 把GPIO5_3设置为输出引脚 */pReg = (volatile unsigned int *)(0x020AC004);//孤僻o基地址是0x020AC000 ,偏移地址是4*pReg |= (1<<3);pReg = (volatile unsigned int *)(0x020AC000);//gpio5的基地址是(0x020AC000while (1){/* 设置GPIO5_3输出1 */*pReg |= (1<<3);//寄存器第四位与1或delay(1000000);//延时/* 设置GPIO5_3输出0 */*pReg &= ~(1<<3);//寄存器第四位与0与delay(1000000);}return 0;}
ARM架构
cpu眼中的地址与控制器眼中的地址是不同的
cpu内部有16个寄存器,R0~R12是通用寄存器,其他三个是有特殊作用的
除这外,还有程序状态寄存器PSR
指令集
第一个程序深度解析
进制
3个二进制位(三个bit)表示一个八进制位
四个二进制位(四个bit)表示一个16进制位
进制转换
八进制转二进制,就是一位八进制使用3位二进制表示
16进制转二进制,就是一位16进制使用四位二进制表示
开头标识
0b 二进制
0开头表示8进制
0x开头表示16进制
汇编_反汇编_机器码
使用按键控制LED
原理图
void delay(volatile int d){while(d--);}int main(void){//当发现按键开关按下就开打 volatile unsigned int *pRegLed;//通过gpio5——3控制灯开关 volatile unsigned int *pRegKey;//通过gpio4-14感知按键开关的状态 /* 使能GPIO5: 默认使能 *//* 使能GPIO4, CCM_CCGR3, b[13:12]=0b11 */pRegKey = (volatile unsigned int *)(0x020C4074);//*pRegKey |= (3<<12);/* 把GPIO5_3设置为GPIO功能 */pRegLed = (volatile unsigned int *)(0x02290000 + 0x14);*pRegLed |= (0x5);/* 把GPIO4_14设置为GPIO功能 * IOMUXC_SW_MUX_CTL_PAD_NAND_CE1_B 地址:20E_0000h base + 1B0h offset = 0x020E01B0 */pRegKey = (volatile unsigned int *)(0x020E01B0);*pRegLed &= ~(0xf);*pRegLed |= (0x5);/* 把GPIO5_3设置为输出引脚 */pRegLed = (volatile unsigned int *)(0x020AC004);*pRegLed |= (1<<3);/* 把GPIO4_14设置为输入引脚 ,因为我们需要读取它的值,要是写的话就是输出引脚 * GPIO4_GDIR地址:0x020A8004*/pRegKey = (volatile unsigned int *)(0x020A8004);*pRegLed &= ~(1<<14);//清零/* GPIO5_DR */pRegLed = (volatile unsigned int *)(0x020AC000);/* GPIO4_DR */pRegKey = (volatile unsigned int *)(0x020A8000);while (1){/* 读取GPIO4_14引脚 */if ((*pRegKey & (1<<14)) == 0) /* 被按下 */{/* 设置GPIO5_3输出0 灯亮*/*pRegLed &= ~(1<<3);}else{/* 设置GPIO5_3输出1 灯灭 */*pRegLed |= (1<<3);}}return 0;}
串口UATR编程
1、UATR硬件介绍
作用
1、打印调试信息
2、外接模块
波特率定义了一位数据传输的时间
1、数据开始传输的标志是电位为低
2、arm将数据一位一位传输,pc机会根据之前设定的波特率确定什么时候传了一位数据,然后读取这个数据