看了开发板配套光盘中的非操作系统示例代码,试着进行简化,只留下最核心的启动代码,然后自己编写makefile进行编译,烧录到开发板中进行实验,总算成功了。第一个程序运行后只是简单地让4个LED轮流开启关闭,虽然没有看懂是怎么做到控制LED的,但看懂了系统启动部分,而且把有点乱的代码整理得整齐了些;第二个程序运行后可以从串口输出文本,这对以后的进一步学习很重要,因为串口输出是很重要的调试手段(从显示屏输出文本太复杂,不是初学者可以容易搞定的)。此外,看了《基于ARM的嵌入式系统开发与实例》,虽然第4章,第5章看得很晕,因为存储器控制器比较复杂,书中讲了好多硬件连接以及操作时序的问题,以前完全没接触过,基础不够,看不懂。但第6章和第7章讲的中断控制器和PWM定时器,看门狗定时器还是比较好懂的,然后结合S3C2440A用户手册,了解了S3C2440A与书中讲的S3C44B0X的区别。把书中的例子改成可以在自己的开发板上运行的程序,烧录进去,运行得与预期效果一致。 0 说明
本文引用地址:https://www.eepw.com.cn/article/201611/318885.htm 我用的开发板是mini2440,它采用的处理器是基于ARM920T的S3C2440A;而看的教材《基于ARM的嵌入式系统开发与实例》是以基于ARM7TDMI的S3C44B0X为例进行讲解的。
1 中断控制器
S3C2440A可以接受60个来自内部外设或者外部中断引脚的中断请求,多个中断请求经过仲裁判优后向ARM920T核心发出IRQ或者FIQ请求。S3C2440A与S3C44B0X有几处不同:
(1) 有些中断请求是带子寄存器的。这些请求先对子源中断请求寄存器(SUBSRCPND)相应位置1,再通过子中断屏蔽寄存器(INTSUBMASK),然后才能进入到源中断寄存器(SRCPND)中,最后通过中断屏蔽寄存器(INTMASK),再进行模式(INTMOD)和优先级(PRIORITY)判断。在处理通过子中断寄存器的中断时,要记得清除SUBSRCPND的相应位。
(2)从用户手册上看,S3C2440A是没有像S3C44B0X那样的中断控制寄存器的,不能选择是使用向量中断还是非向量中断。书中讲的IRQ向量模式寄存器应该是对应S3C2440A的中断优先级寄存器,S3C2440A的优先级轮转也比较好理解;至于中断请求清除寄存器,S3C2440A好像是没有对应的寄存器的。在这上面,S3C44B0X似乎复杂一些。
下面是来自S3C2440A用户手册的中断处理过程图:
2 PWM定时器
这方面S3C2440A与S3C44B0X没有太大的不同,书中讲的基本原理与定时器特性适用于S3C2440A。
3 看门狗定时器
除主时钟输入频率不同外,S3C2440A与S3C44B0X没有大的差别。
4 源代码
(1)PWM定时器处理代码
static int int_count;
static __irq void Timer0_Int(void)
{
Uart_Printf("nTimer 0 interrupt %d times",++int_count);
rSRCPND = BIT_TIMER0;
rINTPND = BIT_TIMER0;
}
void Timer0_Start(void)
{
int i;
rTCFG0 = 0xFF;// 定时器0,1的预分频值为255
rTCFG1 = 0x2; // 定时器0的时钟分割器采用1/8分频
rTCNTB0 = 25600;
rTCON = 0x06;
for(i=0;i<1000;i++);
rTCON = 0x09;
pISR_TIMER0 = (unsigned int)Timer0_Int;
rINTMSK &= (~BIT_TIMER0);
}
(2)看门狗定时器处理代码
static int int_count;
#define SUB_BIT_WDT (0x01 << 13)
static __irq void Watchdog_Int(void)
{
Uart_Printf("nWatchdog interrupt %d times",++int_count);
rSUBSRCPND = SUB_BIT_WDT;
rSRCPND = BIT_WDT_AC97;
rINTPND = BIT_WDT_AC97;
}
void Watchdog_Start(void)
{
rWTCNT = 16000;
rWTDAT = 16000;
pISR_WDT_AC97 = (unsigned int)Watchdog_Int;
rINTMSK &= (~BIT_WDT_AC97);
rINTSUBMSK &= (~SUB_BIT_WDT);
// 0xFF3C=不产生复位信号 0xFF3D=产生复位信号,约10秒后系统复位
rWTCON = 0xFF3C;
}
(3)说明
主函数中执行下列代码:
Timer0_Start();
Watchdog_Start();
while(1);
会看到串口约1秒输出一次定时器中断处理消息,约10秒输出一次看门狗中断处理消息。如果设置看门狗定时器控制寄存器的值为0xFF3D,则看门狗定时器超时时,会发出复位信号,即大约每隔10秒,系统会复位一次。
主程序在运行死循环,但串口输出还是可以进行的,这就是中断的功能了:中断程序的执行,处理其他事务。以前学微机原理的时候,讲中断只是抽象的概念,不好理解,这里就看得比较清楚了。
中断处理函数中,应该清除相应的中断请求位。对于看门狗中断,由于是通过子中断寄存器的,所以还要清除子中断源请求寄存器。如果不进行清除动作,则中断请求一直保持,相当于不停地发生中断,无法返回到主程序中。
armcc扩展了C语言,提供__irq关键字用以定义中断处理函数。曾试着不使用__irq,但无论是用C语言还是汇编语言编程,都无法正确实现中断处理,还是对中断处理中应该进行的保存恢复寄存器,以及返回到主程序的操作不熟悉,等以后熟悉了再试着不用这个关键字吧。
5 两个术语
PWM:Pulse Width Modulation,脉宽调制。
脉宽调制(PWM:(Pulse Width Modulation)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。
简而言之,PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。
看门狗:Watchdog
在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的芯片,俗称“看门狗”。
看门狗电路电路的应用,使单片机可以在无人状态下实现连续工作,其工作原理是:看门狗芯片和单片机的一个I/O引脚相连,该I/O引脚通过程序控制它定时地往看门狗的这个引脚上送入高电平(或低电平),这一程序语句是分散地放在单片机其他控制语句中间的,一旦单片机由于干扰造成程序跑飞后而陷入某一程序段进入死循环状态时,写看门狗引脚的程序便不能被执行,这个时候,看门狗电路就会由于得不到单片机送来的信号,便在它和单片机复位引脚相连的引脚上送出一个复位信号,使单片机发生复位,即程序从程序存储器的起始位置开始执行,这样便实现了单片机的自动复位。
看门狗,又叫 watchdog timer,是一个定时器电路, 一般有一个输入,叫喂狗,一个输出到MCU的RST端,MCU正常工作的时候,每隔一端时间输出一个信号到喂狗端,给 WDT 清零,如果超过规定的时间不喂狗,(一般在程序跑飞时),WDT 定时超过,就回给出一个复位信号到MCU,是MCU复位. 防止MCU死机. 看门狗的作用就是防止程序发生死循环,或者说程序跑飞。(
评论