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);

	//设置GPIO
	GPGCON |= (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)寄存器

void clock_init(void)
{
	//设置倍频寄存器
	unsigned int t;
	t = MPLLCON;
	t &= ~(0xFF << 12);//清MDIV
	t &= ~(0x3F << 4);//清PDIV
	t &= ~(3 << 1);//清SDIV

	t |= (127 << 12);
	t |= (2 << 4);
	t |= (1 << 0);	
	
	//设置分频器
	CLKDIVN |= (2 << 1) | (1 << 0);
	
	MPLLCON = t;
}

  • 16
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值