本文主要是介绍2440LED点灯、K1~K6按键、24401中断、2440时钟,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
我要成为嵌入式高手之4月12日ARM第七天!!
————————————————————————————
2440GPIO
GPIO:通用目的输入输出
LED
要把GPBCON初始化
地址是固定的,可以当做无符号int型
控制所有灯就需要初始化GPBCON5.6.7.8
#include "led.h"void led_init(void)
{unsigned int t = 0;t = GPBCON;t &= ~((3 << 10) | (3 << 12) | (3 << 14) | (3 << 16));t |= (1 << 10) | (1 << 12) | (1 << 14) | (1 << 16);GPBCON = t;
}void ledAllOn(void)
{GPBDAT &= ~(0x0F << 5);//低电平打开
}void ledAllOff(void)
{GPBDAT |= (0x0F << 5);//高电平关闭
}void ledAllNor(void)
{GPBDAT ^= (0x0F << 5);
}void delay(unsigned int n)
{ while (n--);
}//关闭看门狗定时器
void wdt_init(void)
{WTCON &= ~(1 << 5);
}void ledOn(unsigned char n)
{unsigned int t = 0;n &= 0x0F;t = GPBDAT;t &= ~(0x0F << 5); t |= n << 5;GPBDAT = t;
}
main.c
#include "led.h"int main(void)
{wdt_init();led_init();ledAllOff();while (1){ledAllNor();delay(0x3FFF);ledOn(8);delay(0x3FFF);}
}
按键
首先初始化GPEGCON
K1与K6有上拉电阻,故应将附加上拉电阻功能禁止
GPGUP |= (1 << 0);
#include "key.h"void key_init(void)
{GPGCON &= ~((3 << 0) | (3 << 6) |(3 << 10) | (3 << 12) | (3 << 14) | (3 << 22));GPGUP |= (1 << 0);//第一个按键和最后一个按键有物理上拉电阻,故在此将附加上拉功能禁止
}int key_press(void)
{if ((GPGDAT & (1 << 0)) == 0){return 1;}else if ((GPGDAT & (1 << 3)) == 0){return 2;}else if ((GPGDAT & (1 << 5)) == 0){return 4;}else if ((GPGDAT & (1 << 6)) == 0){return 8;}else if ((GPGDAT & (1 << 7)) == 0){return 9;}else if ((GPGDAT & (1 << 11)) == 0){return 10;}return 0;
}
main.c
int main(void)
{wdt_init();led_init();key_init();ledAllOff();while (1){//ledOn(key_press());}
}
2440中断
中断处理流程
1、中断源发出中断请求
2、CPU查询是否允许中断和该终端是否被屏蔽
3、CPU查询中断优先级
4、保护现场(和栈有关)
5、执行中断函数
6、恢复现场
外部中断的60个中断源最后经过筛选,比较,最终将中断请求交给920T内核;然后920T内核通过FIQ异常或者IRQ异常来采取措施最终实现中断。(由于我写的startup.s用的是IRQ异常,故将中断处理为IRQ异常)
要初始化的寄存器
中断模式(INTMOD)寄存器
需要置0改为IRQ模式
中断屏蔽(INTMSK)寄存器
需要置0改为可服务模式
此外,还需要设置GPIO,改为中断模式
GPGCON寄存器
EXTINTn(外部中断控制寄存器 n)
控制中断如何发生(上升沿、下降沿……)
EINTMASK(外部中断屏蔽寄存器)
至此初始化流程完成
———————————————————————————————————————————
中断服务函数
进入中断服务函数后要查询中断源的寄存器:
中断偏移(INTOFFSET)寄存器
写在中断处理函数中(interrupt_handle)
中断偏移寄存器中的值表明了是哪个 IRQ 模式的中断请求在 INTPND 寄存器中。此位可以通过清楚 SRCPND 和 INTPND 自动清除。
判断完之后读GPIO中的寄存器确定到底是哪个中断源
EINTPEND(外部中断挂起寄存器)
写在中断详细处理方案函数中(eint_handle)
用来查询是哪个中断源,且需要软件写“1”清零
1:发生中断 0:不发生中断
源挂起(SRCPND)寄存器
写在中断处理函数中(interrupt_handle)
中断处理完成后需要清除那些数据中被设置为 1 的相应 位置的 SRCPND 位。
中断挂起(INTPND)寄存器
写在中断处理函数中(interrupt_handle)
必须在中断服务程序中清除了 SRCPND 寄存器后清除此寄存器。
//中断初始化
void eint_init(void)
{//设置中断INTMOD &= ~(1 << 5);INTMSK &= ~(1 << 5);//设置GPIOGPGCON |= (2 << 0);//设置外部中断触发方式EXTINT1 |= (2 << 0);//设置外部中断使能EINTMASK &= ~(1 << 8);
}
//中断处理函数
void eint_handle(void)
{if ((EINTPEND & (1 << 8)) != 0){key = 1;}EINTPEND = EINTPEND;//指定位写1,用来清零
}//中断服务函数
void interrupt_handle(void)
{switch(INTOFFSET){case 5:eint_handle();break;default:break;}SRCPND = SRCPND;INTPND = INTPND;
}
2440时钟
注意是时钟,不是实时时钟
这里的时钟指的是处理器运算时的主频(即程序运行一条指令所需要的时间)
实时时钟是一个表,可以记录 年 月 日 时 分 秒
PLL(phase lock loop)锁相环电路:
作用:倍频作用
时钟发生模块框图
时钟发生模块框图
step1:配置PLL(MPLL)
1、先清零MDIV . PDIV . SDIV
2、后填数设置倍频为400M
step2:配置时钟分频控制(CLKDIVN)寄存器
配置之前要查询摄像头时钟分频(CAMDIVN)寄存器
这篇关于2440LED点灯、K1~K6按键、24401中断、2440时钟的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!