⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 嵌入式开发试验:中断按钮实验
💻 C
字号:
/*
 *	main.c    -     demo of int0 api
 *	
 *	Author: 	li ming <admin@lumit.org>
 *	Date:		2005-6-12
 *	Copyleft:	http://www.lumit.org
 */


#include "int0_api.h"
#include "led_api.h"
 
#define IRQ_SOURCE_NUM		21  // 21个中断源

void (*device_irq_handler[IRQ_SOURCE_NUM])(int irq);

int request_irq( unsigned int irq, void (*handler)(int irq) )
{
	if( device_irq_handler[irq] )
		return -1;	// fail to request, free this irq first
		
	// fill the device_irq_handler vector
	device_irq_handler[irq] = handler;
	
	return 0;	
}

int free_irq( unsigned int irq, void (*handler)(int irq) )
{
	if( !device_irq_handler[irq] )
		return -1;	// fail to free, install this irq first
		
	// free the device_irq_handler vector
	device_irq_handler[irq] = 0;
	
	return 0;	
}

void do_irq( void )
{
	void (* current_pc)();
	int irq_source;
	int i;
	
	// get irq number from INTPND	
	irq_source = INTPND;  //得到当前中断源的寄存器的值
	
	// get current device irq handler to current_pc
	for( i = 0; i < IRQ_SOURCE_NUM; i++ )
	{
		if( irq_source & ( 1 << i ) ) //对每一位中断源的bit位判断
		{	// here is an interrupt at source i	
			
			if( device_irq_handler[i] ) //判断是否已被注册
			{	// if this interrupt has an registered handler
				// then get this handler address to current_pc			
				current_pc = device_irq_handler[i];
				// call registered device irq handler to do_irq
				((void (*)(void))(current_pc))(); /* thanks, STheobald */	
			}
		}	
	}
	
	return;	
}

static void install_irq_handler( void (*isr)(void) )
{<input type="button" <input type="button" <input type="button" <input type="button" <input type="button" >>>>>
	/* ARM irq exception vector addr is 0x00000018  */
	unsigned int * irq_vec_addr = ( unsigned int * ) 0x18; //向量表,只有一个表项,在内存中动态建立
	/* this is isr entry address, could be another address like 0x3c, 0x58... */
	unsigned int * isr_entry_addr = ( unsigned int * ) 0x38;

	unsigned int instruction;
	
	/* set the ISR entry at 0x38  */
	*isr_entry_addr = (unsigned int)isr;
	
	/* make an instruction(构造一条指令): it is machine-code for "ldr  pc, [pc, #(38-18-8)]"  
	18是跳转指令,-8是流水线的问题*/
	instruction = ((unsigned int) isr_entry_addr  - (unsigned int)irq_vec_addr - 0x08) | 0xe59ff000;
	
	/* set this instruction at 0x18  */
	*irq_vec_addr = instruction;	
	
	return;
}

void irq_handler( void );

void int0_irq_hooker( void )
{
	// we add a hooker of int0 interrupt ( just let led_3 to blink one time )
	led_one_light(3);
	led_delay( 10 );
	led_one_dark(3);
}

int main( void )
{	
	int i = 1;
	
	install_irq_handler( irq_handler );

	int0_install_irq_hooker( int0_irq_hooker );

	led_init();
		
	// should be after hooker installation
	int0_init();
		
	while(i++)
	{
		led_one_light(i%3);
		led_delay( 100 );
		led_one_dark(i%3);
	}
	
	return 0;
}

void __rt_entry( void )
{	
	main();	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -