嵌入式体系结构复习笔记

Posted MangataTS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了嵌入式体系结构复习笔记相关的知识,希望对你有一定的参考价值。

寄存器表示C语言的对应关系

  • R14 : 存储C的函数返回地址
  • R15 : 当前执行程序的代码地址
  • R0: 存储C语言函数返回值

ARM的常用指令

  • 将数据加载到寄存器:MOV/LDR
  • 子程序调用指令: BL
  • 软中断调用指令: SWI

从系统0x0地址上取出来的值赋值给SP,做为C语言的栈地址

从系统0x4地址上取出来的值赋值给PC,做为复位异常的入口地址

RS232通信标准的电气规范

逻辑0、逻辑1的表示方式

TxDRxD上:

逻辑1(MARK)=-3V~-15V

逻辑0(SPACE)=+3~+15V

常见ARM模块的名称

  • RCC : 系统复位时钟控制器
  • GPIO:通用功能输入输出控制器
  • EXTI: 外部中断控制器
  • USART: 通用异步/同步收发器

零散知识点

  • ATPCS中,栈的操作方式是满递减方式

  • stm32中断优先级设置为第2组的话,抢占优先级可以配置为0,1,2,3

  • 驱动无速度要求的外设时,如发光二极管,GPIO推荐配置速度为2MHZ即可

  • systick时钟控制模块,采用了24bit的计数器

  • 用来将NVIC寄存器设置为缺省函数名的函数是:NVIC_Deinit

  • 用来设置NVIC寄存器为特定值的函数是:NVIC_Init

  • stm32f103有4种输出模式:开漏输出、开漏复用输出、推挽式输出、推挽式复用输出

  • RS232中,TXD和RXD相连,RXD和TXD相连

  • ADC转换的步骤是 采样、量化、编码

  • CortexM体系结构编程模型支持2种工作模式空间

  • CortexM体系结构支持thumb2指令集

  • ARM公司规定用R15表示程序运行的地址寄存器

  • 在stm32F103中GPIO控制器挂载在APB2时钟总线

  • 中断处理函数和普通函数的执行方式是不一样

  • 输入浮空模式下,外部引脚的电压是不确定的

  • stm32F103的内部SRAM基地址是0x20000000

  • CMSIS是ARM公司推出的库接口标准

有效立即数的判断

立即寻址

在立即寻址中,操作数由操作指令本身给出,这个操作数也就是我们说的立即数,举例:

ADD R0, R1, #5      ;R0=R1+5
MOV R0, #0x55       ;R0=0x55 

这里的50x55就是这两条指令的立即数

立即数的形式

  • 0x 或 & 表示十六进制数
  • 0b 表示二进制数
  • 0d 或缺省表示十进制数

立即寻址指令

格式

32为的立即寻址指令的格式如图

但是我们只用关心后面的rotateimmediate部分即可,因为这才是立即数的组成元素

立即数构成

rotate+immediate,前者是移位操作的移位数,后者是立即数的部分(完整的要通过移位之后构成)

一个立即数是由32位构成的所以我们计算立即数的时候要把前置0补齐

合法立即数

如果一个立即数存在一个rotate使得immediate循环右移2*roate次(roate>0)和当前的立即数相等,那么就表示这个立即数是合法的

一个判断立即数的小trick:

看一个指令的从最低位到第一个为1的位数(不包含),如果有奇数个0那么就不是立即数,如果有偶数个0那么就是立即数(其实也就是利用了这里的2倍的性质,感兴趣可以证明一下)

eg:

0000 0000 0000 0000 0000 0011 1111 0010 //不是立即数,因为有一个0
0000 0000 0000 0000 0000 0011 1111 0100 //是立即数,有两个0
0000 0000 0000 0000 0000 0011 1111 1010 //不是是立即数,因为只有一个0

立即数计算

  • step1:

我们先对当前的immediate进行一个填充前置0使得总共的二进制位数为32位

  • step2:

对当前的这个immediate做一个循环右移(想想成一个环形,如果最低位右移,这个位置的值会移动到最高位去)

eg:

immediate:0000 0000 0000 0000 0000 0000 1111 0011
rotate   :0010
我们将immediate循环右移4次:
该立即数为:0011 0000 0000 0000 0000 0000 0000 1111  (和上面对比就是将低位的四位移动到高位的前四位去了)

CPU中断处理过程

  • 中断请求发生后,CPU判断该中断请求是否屏蔽,若未屏蔽则进入中断响应状态;
  • 中断响应状态进入中断服务处理部分,此部分需要完成保护现场的功能。
  • 中断处理部分执行完成后,进入中断返回,此部分需要恢复现场。

NVIC的特征

  • 支持嵌套和向量中断
  • 自动保存和恢复处理器状态
  • 动态改变优先级

编程题

Q1:

假设发光二极管使用的是GPIOE口的4,5,6引脚,给定延时函数为 Delay_ms()
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
使用方法,循环点亮LED代码

void led_init(void) 
    GPIO_InitTypeDef GPIO_InitStructure;
    // 第5引脚,配置为推挽输出功能,工作频率为2MHz
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    // 对GPIO_B.5和GPIO_E.5进行上述配置
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_Init(GPIOE, &GPIO_InitStructure);
    // 初始化LED为灭
    GPIO_SetBits(GPIOB, GPIO_Pin_5);
    GPIO_SetBits(GPIOE, GPIO_Pin_5);


void set_led(LED_ID_TypeDef led_id, LED_TypeDef status) 
    void (*GPIO_status[2])(GPIO_TypeDef*, uint16_t) = GPIO_SetBits, GPIO_ResetBits;
    if (led_id == DS0)
        GPIO_status[status](GPIOB, GPIO_Pin_5);
    if (led_id == DS1)
        GPIO_status[status](GPIOE, GPIO_Pin_5);


void slove()
    NVIC_SetPriorityGrouping(NVIC_PriorityGroup_2);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOE, ENABLE);
    led_init();
    while (1) 
        set_led(DS1, OFF);
        delay_ms(1000);
        set_led(DS1, ON);
        delay_ms(1000);
    

串口初始化

void uart_init(u32 bound) 
    GPIO_InitTypeDef GPIO_InitStruct;
    USART_InitTypeDef USART_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;
    // 0. 开启时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);

    // 1.1 配置PA9为TX功能
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    // 1.2 配置PA10为RX功能
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    // 2. 初始化串口工作模式
    USART_InitStruct.USART_BaudRate = bound;
    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStruct.USART_Parity = USART_Parity_No;
    USART_InitStruct.USART_StopBits = USART_StopBits_1;
    USART_InitStruct.USART_WordLength = USART_WordLength_8b;
    USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStruct);

    NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x2;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x2;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);

    USART_ITConfig(USART1,USART_IT_RXNE, ENABLE);
    USART_Cmd(USART1, ENABLE);


二进制处理

后续更新吧

以上是关于嵌入式体系结构复习笔记的主要内容,如果未能解决你的问题,请参考以下文章

爆肝手写整理数据结构笔记,包含案例代码,适合用于及时复习,良心干货,建议收藏!

爆肝手写整理数据结构笔记,包含案例代码,适合用于及时复习,良心干货,建议收藏!

爆肝手写整理数据结构笔记,包含案例代码,适合用于及时复习,良心干货,建议收藏!

分享几个实用的代码片段(第二弹)

分享几个实用的代码片段(第二弹)

《32位嵌入式微控制器及应用》复习笔记大全(最终版)