ARM 笔记(1009)-- STM32部分--07 中断法编程 系统时钟树 滴答时钟
中断法编程:
什么是中断?:#
中断是一种突发的异常行为,中断程序和主程序是相互独立
中断的触发条件?:#
中断的触发条件一定是一个变化的状态,而不能是一个稳定的状态,想利用中断必须在初始化时设定它的触发条件
中断如何执行?:#
中断触发条件成立时,主程序暂停,进入现场保护,执行中断程序后,再返回主程序
中断程序到底去哪执行?:#
去中断程序的入口处执行,也就是说中断程序的函数名字是不能随意写的必须是固定的向量,
去哪找这个文件?#
怎么样编写一个中断程序?#
第一步:在初始化函数中配置中断的触发条件#
开启中断:对于单片机来说,中断想使用的话必须先开启,每种中断资源对应一个中断向量,
开启中断的函数属于NVIC模块,而NVIC模块的各个函数在cortex.c中查找.
设定中断分组:注意只设定一次
函数在cortex.c里面找,我们写到hal.c中,设定中断优先级--函数在cortex.c中查找
第二步:编写中断入口函数——————.S#
中断入口代表中断程序去哪执行,这个函数是不能随意命名的
{
第一种:入口函数我们不利用库函数的处理流程,自己写,想做什么
第二种:利用库函数的处理流程:绕弯,处理复杂程序容易
}
第一种:自己写,完整的过程:进入到中断程序以后首先关闭中断,防止在中断进程中,中断程序再次来临,清除中断标志位,然后进行中断处理,处理结束后再打开中断,
第二种:利用系统的hal库通用处理函数,我们只需要在中断入口中调用这个函数
第一步写初始化函数#
{
开启时钟
I/O口配置 工作模式 需要配置成上升沿触发---根据硬件电路
设置中断分组------cortex.c--------hal.c
设置中断优先级-----cortex.c---------
开启中断---------cortex.c
}
编写中断入口#
函数名-----.S
{
(注意区分是哪来的中断)
关闭中断----
清除中断标志位
编写中断程序
开启中断
}
利用系统中断通用处理函数
编写中断入口#
函数名-----.S
{
调用系统的中断通用处理函数----相应的资源.C
}
重定义回调函数#
{
(注意区分哪来的)
中断程序
}
课后作业:解读外部中断的通用处理函数
ARM内核RCC#
单片机占用多长时间是由指令占用的机器周期决定的,机器周期又是由系统时钟决定的
指令分为
单周期指令,
双周期指令,
四周期指令
一个机器周期的长度:在51系类的单片机里面一个机器周期是12个系统时钟,一个系统时钟就是一个晶振周期
ST系类:宏晶半导体的单片机是51内核的,它属于51的升级版或者说顶配版,
有1T模式和12T模式,
12T模式就是兼容的51的模式,
一个机器周期就是12个系统时钟,
而1T模式指的是1个机器周期占用一个系统时钟
ARM的一个机器周期就是一个系统时钟,系统时钟就是晶振
ARM有好多个晶振,那他的系统时钟到底是哪个晶振,如果我们不进行特殊配置,他的系统时钟就是内部高速晶振(默认的),
那我们的内部高速晶振需要在参考手册RCC(系统时钟树)里查看,可以简单计算1/16MS = 0.0625us
系统时钟树
Rcc是什么?#
系统时钟树
arm的外设工作时都是有时钟去控制。
为什么学习RCC#
锁相环输出:#
HSI/HSE 先M分频,再N倍频,再P分频最终形成系统时钟,最大可以是180M由内核的性能决定
25M----->180M /M(25) *N(360) /P(2) 成立
/M(5) *N(72) 成立
/M(1) *N(360/25) 不是整数
AHB 180 一分频
APB1 45 四分频
APB2 90 二分频
如何配置总线时钟#
什么是总线时钟:不同的外设通讯速率是不同的,如果都使用高速的信号作为外设时钟是不允许的,如果都使用低速的时钟,某些外设功能不能很好的体现
配置总线时钟编程步骤:#
第一:#
几乎所有的外设都需要时钟控制,所以我们配置完ARM的时钟体系之后,这个函数几乎每个程序都要用到
目前为止,我们必须在初始化里写入的两个函数就是HAL_init(); 还有系统时钟配置函
数
第二:#
系统时钟配置分两步,第一步设定系统时钟,第二步设定总线时钟
1、设定系统时钟
开启时钟
开启调压级别
开启over-drvier(180)
设定系统时钟频率----配置系统时钟,先调用函数,再考虑回参和实参
定义结构体变量(写前头儿)----RCC_OsclnitypeDef RCC_sysclock; -----------HAL_RCC_OscConfig(&sysclock)
考虑对结构体变量的成员赋值
2、设定总线时钟
滴答时钟
滴答时钟是一个倒计数定时器 98 95 4-------滴答的计数时钟,多长时间记一个数
HCLK 180M 1/180<<1us
HCLK/8
在Systick
X=SYSTICK->VAL
查询法做精准延时的核心思想#
不停的问滴答时钟的计数值,然后把每次询问的时间累加起来,判断是否达到我们想要的延时,如果达到了就跳出,没达到就继续
Static int
void delay_us(u32 n)
{
u32 x1; //读取滴答时钟计数器的值
u32 x2;
u32 time;
u32 cnt;
u32 load=SysTick->LOAD;L
u32 sum=0;
cnt=count*factor //count=(x1-x2)*1/180M cnt代表是(x1-x2)us
x1=SysTick->VAL; //n代表nus
while(count<n*factor)
{
x2=SysTick->VAL;
If(x1>x2)
count=x1-x2 ;
else
count= load-(x2-x1); //count 的值是if (count == n*180)
Sum+=count
X1-x2
{
}
count*180==n;
If(count==n*180)
time=(x2-x1) 1/180M
cnt=(x2-x1)*1/M
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步