链接:https://pan.baidu.com/s/1E4x2TX_9SYhxM9sWfnehMg?pwd=1688
提取码:1688
上午:中断 吕峰老师
下午:定时器
教学内容:
一、中断
ARM中断分为二级,分为一级中断和二级中断,二级中断为子中断,对于ARM来说有50个中断源,
其中有32+(EINT23-4)23-4+1-2=50
子中断源分为二种,一种是内部子中断,另一种是外部子中断源(EINT4_7,EINT8_23)
内部子中断:一般是串口的读写,视频的中断,AC中断等等,主要是内部硬件设备
外部子中断:一般是EINT4_7,EINT8_23,分别是GPF和GPG的I/O口。
中断的过程:
1)、中断开始申请中断,申请中断标志是在SRCPND寄存器32位寄存器中(1有,0无,清零必须写1;)
2)、中断可以被屏蔽,屏蔽中断时在INTMSK寄存器32位寄存器中(1:屏蔽,0:开放)
3)、上面的32位的中断源可以设置是普通中断(IRQ)还是快速中断(FIQ),INTMOD可以设置中断源的中断方式,但是在同一个时间只能设置一个快速中断(1:FIQ,0:IRQ);对于快速中断是不需要经过INTMSK和PRIORITY(优先级寄存器)的,要手动清0;具体可以看第一个图。(下面默认为IRQ)
4)、对于32位中断源可以有优先级别,优先级由PRIORITY寄存器设置,原理请看的具体PRIORITY。
5)、中断经过申请,没屏蔽,优先级之后,会挑选一个CPU响应的中断,此中断信息是放在INTPND寄存器中(32位),即INTPND(清零必须写1)寄存器中只会有一个1,到此SRCPND,INTMSK,PRIORITY都是32位寄存器,而且它们的位的中断源对应位都一样(表格一样)。
6)、对于这32个位中断而言都是IRQ中断,IRQ中断的地址是0x0000,0018,如果要跳到相应中断就必须使用基址+变址方式来确定中断入口,为此三星提供的start.s文件中把子程序中断地址编程表格,每4字节对齐,通过表格的基址+变址来跳转子中断入口。
程序如下:(在start.s中)
//**************************************
IsrIRQ
sub sp,sp,#4 ;reserved for PC
stmfd sp!,{r8-r9} //保存r8和r9
ldr r9,=INTOFFSET
ldr r9,[r9] //取出编号
ldr r8,=HandleEINT0 //表格首位为HandleEINT0,所以即为首表地址
add r8,r8,r9,lsl #2 //表格是4字节对齐
ldr r8,[r8]
str r8,[sp,#8]
ldmfd sp!,{r8-r9,pc}
//**************************************
内部子中断:
对于内部子中断的判断是由SUBSRCPND寄存器申请的,同时内部子中断也是可以屏蔽的,屏蔽是使用INTSUBMSK寄存器屏蔽的。
SUBSRCPND:(1为中断,0为没中断,在中断服务程序中,需要对其置1的标志位清0)
INTSUBMSK:(表格同上1:屏蔽对应的子中断源,0:开放对应的子中断源)
外部子中断:(外部子中断是EINT4_7,EINT8_23)
外部中断的触发方式由:EXTINT0,EXTINT1,EXTINT2
外部子中断屏蔽由:EINTMAK
外部子中断标志:EINTPEND(必须写1清0)
EXTINT0:
EXTINT1:
EXTINT2:
第3、7、11、15、19、23、27、31位---为FILTEN,各引脚滤波控制位
:0:禁止滤波 1:使能滤波
EINT0~23---中断请求信号触发方式选择
000:低电平触发 001:高电平触发
01x:下降沿触发 10x:上升沿触发
11x:双边沿触发
外部子中断屏蔽寄存器-EINTMAK:
外部子中断标志寄存器-EINTPEND:
0:无中断请求 1:有中断请求 ;注意:对某位写1,则清除相应标志,即清为0.
总结:以外部IO中断为例,
1)、首先把IO口设置为中断功能
2)、 设置EXTINT的触发方式,默认为低电平触发,
3)、使中断入口等于中断函数地址
4)、清中断标志位,防止误中断(SRCPND,INTPND,EINTPEND)
5)、设置允许中断(INTMSK,EINTMASK)
中断子程序如下:
//*****************************************
//清SRCPND和INTPND
void ClearPending(int bit)
{
rSRCPND = bit;
rINTPND = bit;
}
//使能中断
#define EnableIrq(bit) rINTMSK &= ~(bit)
//如果是子中断就还要操作EINTPEND和EINTMASK
rEINTPEND |= (0x01<<4); //清除子中断,防止误中断
rEINTMASK &= ~(0x01<<4); //设置允许中断
//*****************************************
二、定时器
S3C2440有5个16位的定时器
1)定时器0-3具有PWM(脉宽调制)功能:它们都有一个输出引脚,可以通过定时器来控制引脚周期性的高低变化(即占空比不同的PWM波)
2)定时器4是内部定时器,没有输出引脚,供内部使用
定时器0-3的TOUT是对应的GPB0-GPB3的复用功能
定时器的基准时钟是经过PCLK的二次分频而来,(因为PCLK的频率较高所以必须分频)
第一次分频由TCFG0寄存器(32位)预分频,然后经过TCFG1再分频一次,作为计数器的基准时钟,预分频只能分1-256倍,第二次分频只能分1/2,1/4,1/8,1/16或者直接用TCLK时钟。
频率计算公式为:
fTclk = [fpclk∕(Prescaler+1)] ×分频值
Prescaler:预分频值,0---255;
分频值: 1/2、1/4、1/8、1/16
如图,比较寄存器:为了调制PWM的脉宽,比较寄存器/初值寄存器=占空比(注:定时器4没有比较寄存器)
初值寄存器:计数的初值,计数器为减法计数器
观察寄存器:可以读出当前的计数值
TOUT:必须设置相应的GPBn口为TOUT功能,而且要设置比较寄存器
相关的寄存器:
定时器为16位,所以TCNTBn,TCMPBn和TCNTOn都为16位寄存器。
TCFG0---预分频器配置寄存器:
Prescaler1---timer2、3、4的预分频值
其值N为: 0~255
输出频率为:PCLK ÷(N+1)
Prescaler0--- timer0、1的预分频值
其值N为: 0~255
输出频率为:PCLK ÷(N+1)
TCFG1---分频选择寄存器:
MUX4~ MUX0---timer4~timer0分频值选择
0000:1/2 0001:1/4
0010:1/8 0011:1/16
01XX:选择外部TCLK0、1
可选择外部时钟为记数信号
(对timer0、1是选TCLK0,对timer4、3、2是选TCLK1)
TCON---定时器控制寄存器:
TL4~TL0---计数初值自动重装控制位
0:单次计数
1:计数器值减到0时,自动重新装入初值连续计数
TO3~TO0--- TIMER3~TIMER0输出控制位
0:正相输出 1:反相输出
TUP4~TUP0---计数初值手动装载控制位
0:不操作
1:立即将TCNTBn中的计数初值装载到计数寄存器TCNTn中
说明:如果没有执行手动装载初值,则计数器启动时无初值
(第一次启动先得手动装载一次置1后清0,装载初值)
TR4~TR0---TIMER4~TIMER0运行控制位
0:停止 1:启动对应的TIMER
三、看门狗
WATDOG定时器可以像一般16位定时器一样产生周期性的中断,当程序出现崩溃或者跑飞的时候,看门狗可以使得系统重启。
WATDOG定时器经过一次预分频,被再次分频可以得到4种频率的一种,同样WATDOG是减数计数器,当到达0时候,而WTCNT又没有自动装载WATDAT的数,那么就会产生中断,从而复位。如果程序没有跑飞,当计数器计到0的时候WTCNT会自动装载WATDAT的值。
WTCON(16位):控制着预分频,再分频,启动看门狗,使能中断功能
WATDAT(16位):下次装数的寄存器,在第一次启动,把WATDAT里面的值赋值给WTCNT寄存器
WTCNT(16位):当前要计的数值,为0时,使能中断,则复位系统。
WTCON:
[15:8]:预分频数值;[5]:启动/停止;[4:3]:分频系数;[2]:使能中断;[0]:为0时,是否输入复位信息