1、3.用swi指令验证异常处理流程(四大步三小步)
2、串口中断实验
1、3.用swi指令验证异常处理流程(四大步三小步)
.text @文本段
.globl _start @声明一个_start全局函数
_start: @_start标签入口
@1.构建异常向量表
b reset
b undefine
b software_interrupt
b prefetch_abort
b data_abort
b .
b irq
b firq
reset:
@2.异常源---->标签
@3.系统一上电处于SVC模式
ldr sp,=0x40000800
@4.从SVC模式切换到user模式
msr cpsr,#0xD0
@5.user模式实现如下内容
@1>初始化栈指针
ldr sp,=0x40000700
@2>分别对r0,r1寄存器赋值
mov r0,#0x1
mov r1,#0x2
@3>执行软中断指令----->四大步三小步
swi 2
add r0,r0,r1 @ r0 = 0x1 + 0x2 = 0x3
b stop
undefine:
software_interrupt:
@6.SVC模式下执行内容
@1>压栈保存现场
stmfd sp!,{r0-r12,lr}
@2>分别对r0,r1寄存器赋值
mov r0,#0x2
mov r1,#0x3
add r0,r0,r1
@3>恢复现场
ldmfd sp!,{r0-r12,pc}^
@^:代表将SPSR_<mode>寄存器中的值,恢复给CPSR
prefetch_abort:
data_abort:
irq:
firq:
stop: @stop标签入口
b stop
.end
2、串口中断
头文件:
#ifndef __KEY_IT_H__
#define __KEY_IT_H__
#include "stm32mp1xx_gic.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
//EXIT控制器初始化
void hal_exti_init();
//GICD控制器初始化
void hal_gicd_init();
//GICC控制器初始化
void hal_gicc_init();
//GPIO控制器的初始化
void hall_gpio_init();
void delay_ms(int ms);
#endif
源文件1:
#include "../include/key_it.h"
//EXIT控制器初始化
void hal_exti_init()
{
//将GPIO控制器与EXTI控制器相连接
//PF9
EXTI->EXTICR3 &= (~(0xff<<8));
EXTI->EXTICR3 |= (0x05<<8);
//PF7
EXTI->EXTICR2 &= (~(0xff<<24));
EXTI->EXTICR2 |= (0x05<<24);
//PF8
EXTI->EXTICR3 &= (~(0xff<<0));
EXTI->EXTICR3 |= (0x05<<0);
//输入事件使能
EXTI->FTSR1 |= (0x7<<7);
//设置中断不屏蔽
EXTI->C1IMR1 |= (0x7<<7);
}
//GICD控制器初始化
void hal_gicd_init()
{
//GICD使能
GICD->CTRL |= (0x1<<0);
//中断设置使能寄存器
//GICD->ISENABLER[3] |= (0x7<<1);
GICD->ISENABLER[3] &= (~(0xf));
GICD->ISENABLER[3] |= (0xe);
//中断优先级寄存器
GICD->IPRIORITYR[24] &= (~(0xff<<24));
GICD->IPRIORITYR[24] |= (0x1<<27);
GICD->IPRIORITYR[24] &= (~(0xff<<8));
GICD->IPRIORITYR[24] |= (0x1<<11);
GICD->IPRIORITYR[24] &= (~(0xff<<16));
GICD->IPRIORITYR[24] |= (0x1<<19);
//中断处理器目标寄存器
GICD->ITARGETSR[24] |= (0b01<<24);
GICD->ITARGETSR[24] |= (0b01<<8);
GICD->ITARGETSR[24] |= (0b01<<16);
}
//GICC控制器初始化
void hal_gicc_init()
{
//组0使能
GICC->CTRL |= (0x1<<0);
//设置中断优先级
GICC->PMR &= (~(0x1f<<3));
GICC->PMR |= (0x3<<3);
}
//GPIO控制器的初始化
void hall_gpio_init()
{
//开启AHB4时钟
RCC->MP_AHB4ENSETR |= (0x1<<5);
//GPIOF设置为输入模式
GPIOF->MODER &= (~(0x3<<18)); //PF9
GPIOF->MODER &= (~(0x3<<14)); //PF7
GPIOF->MODER &= (~(0x3<<16)); //PF8
}
void delay_ms(int ms)
{
int i,j;
for(i = 0; i < ms;i++)
for (j = 0; j < 1800; j++);
}
源文件2:
#include "../include/key_it.h"
extern void printf(const char *fmt, ...);
void do_irq(void)
{
unsigned int i = 0;
delay_ms(5);
i = GICC->IAR;
printf("i = %d\n",i);
//获取中断号
if(i == 99)
{
printf("KEY1被按下\n");
//清除中断号
//GICC->EOIR &= (~(0x3ff));
//GICC->EOIR |= (0x63);
EXTI->FPR1 |= (0x1<<9);
GICD->ICPENDR[3] |= (0x1<<3);
}
else if(i == 97)
{
printf("KEY2被按下\n");
//清除中断号
//GICC->EOIR &= (~(0x3ff));
//GICC->EOIR |= (0x61);
EXTI->FPR1 |= (0x1<<7);
GICD->ICPENDR[3] |= (0x1<<1);
}
else if(i == 98)
{
printf("KEY3被按下\n");
//清除中断号
//GICC->EOIR &= (~(0x3ff));
//GICC->EOIR |= (0x62);
EXTI->FPR1 |= (0x1<<8);
GICD->ICPENDR[3] |= (0x1<<2);
}
//清除中断号
GICC->EOIR &= (~(0x3ff));
GICC->EOIR |= (i);
//i = 0;
}
头文件:
#include "uart4.h"
#include "./include/key_it.h"
extern void printf(const char *fmt, ...);
int main()
{
hall_gpio_init();
hal_exti_init();
hal_gicd_init();
hal_gicc_init();
while(1)
{
}
return 0;
}