嵌入式系统学习——S3C2451之串口中断

  S3C2451开发板除了可以使用上篇博文中提到的查询法,还可以使用其他的方式实现串口的发送和接收。中断法和DMA法就是典型的方法。

  DMA(DIRECT MEMORY ACCESS)即直接存储器存取,是指外部设备不通过CPU而直接与系统内存交换数据的接口技术。 要把外设的数据读入内存或把内存的数据传送到外设,一般都要通过CPU控制完成,如CPU程序查询或中断方式。利用中断进行数据传送,可以大大提高CPU的利用率。

  中断传送是由CPU通过中断服务程序来传送,每次要保护断点,保护现场需要多条指令,每条指令要有取指和执行时间。为了充分利用CPU的高速性能和实时操作的要求,一般中断服务程序要求是尽量的简短,所以当要实现大量数据交换的情况,如从磁盘调入程序或图形数据,如果采用中断传送方式,必然会引起频繁中断的情况,需要执行很多与数据传送无关的中断指令,所以会大大降低系统的执行效率,无法提高数据传送速率。对于一个高速I/O设备,以及批量交换数据的情况,只能采用DMA方式,才能解决效率和速度问题。DMA在外设与内存间直接进行数据交换,而不通过CPU,这样数据传送的速度就取决于存储器和外设的工作速度。

(1)查询方式:主要用于CPU不太忙且传送速度不高的情况下。无条件传送方式作为查询方式的一个特例,主要用于对简单I/O设备的控制或CPU明确知道外设所处状态的情况下。 
(2) 中断方式:主要用于CPU的任务比较忙的情况下,尤其适合实时控制和紧急事件的处理 
(3) DMA方式(直接存储器存取方式):主要用于高速外设进行大批量数据传送的场合


S3C2451串口中断库函数编写:

     s3c2451_irq.h

#ifndef _S3C2451_IRQ_H
#define _S3C2451_IRQ_H

#include "typedef.h"

typedef struct {
		U32 SRCPND;
		U32 INTMOD;
		U32 INTMSK;
		U32 null;
		U32 INTPND;
		U32 INTOFFSET;
		U32 SUBSRCPND;
		U32 INTSUBMSK;
		U32 PRIORITY_MODE;
		U32 PRIORITY_UPDATE;
}volatile* IRQ_MemMabPtr;

#define IRQ1_BASE_PTR				((IRQ_MemMabPtr)0x4A000000)
#define IRQ2_BASE_PTR				((IRQ_MemMabPtr)0x4A000040)

#define INT_ADC						(1<<31)
#define INT_RTC						(1<<30)
#define INT_SPI1					(1<<29)
#define INT_UART0					(1<<28)
#define INT_IIC0					(1<<27)
#define INT_USBH					(1<<26)
#define INT_USBD					(1<<25)
#define INT_NAND					(1<<24)
#define INT_UART1					(1<<23)
#define INT_SPI0					(1<<22)
#define INT_SDI0					(1<<21)
#define INT_SDI1					(1<<20)
#define INT_CFCON					(1<<19)
#define INT_UART3					(1<<18)
#define INT_DMA						(1<<17)
#define INT_LCD						(1<<16)
#define INT_UART2					(1<<15)
#define INT_TIMER4					(1<<14)
#define INT_TIMER3					(1<<13)
#define INT_TIMER2					(1<<12)
#define INT_TIMER1					(1<<11)
#define INT_TIMER0					(1<<10)
#define INT_WDT						(1<<9)
#define INT_TICK					(1<<8)
#define nBATT_FLT					(1<<7)
#define INT_CAM						(1<<6)
#define EINT8_23					(1<<5)
#define EINT4_7						(1<<4)
#define EINT3						(1<<3)
#define EINT2						(1<<2)
#define EINT1						(1<<1)
#define EINT0						(1<<0)

#define SUBINT_DMA7					(1<<30)
#define SUBINT_DMA6					(1<<29)
#define SUBINT_AC97					(1<<28)
#define SUBINT_WDT					(1<<27)
#define SUBINT_ERR3					(1<<26)
#define SUBINT_TXD3					(1<<25)
#define SUBINT_RXD3					(1<<24)
#define SUBINT_DMA5					(1<<23)
#define SUBINT_DMA4					(1<<22)
#define SUBINT_DMA3					(1<<21)
#define SUBINT_DMA2					(1<<20)
#define SUBINT_DMA1					(1<<19)
#define SUBINT_DMA0					(1<<18)
#define SUBINT_LCD4					(1<<17)
#define SUBINT_LCD3					(1<<16)
#define SUBINT_LCD2					(1<<15)
#define SUBINT_CAM_P				(1<<12)
#define SUBINT_CAM_C				(1<<11)
#define SUBINT_ADC					(1<<10)
#define SUBINT_TC					(1<<9)
#define SUBINT_ERR2					(1<<8)
#define SUBINT_TXD2					(1<<7)
#define SUBINT_RXD2					(1<<6)
#define SUBINT_ERR1					(1<<5)
#define SUBINT_TXD1					(1<<4)
#define SUBINT_RXD1					(1<<3)
#define SUBINT_ERR0					(1<<2)
#define SUBINT_TXD0					(1<<1)
#define SUBINT_RXD0					(1<<0)

typedef enum{
		DISABLE = 0,
		ENABLE
}Functionalstate;

extern void IRQ_ClearSRCPND(unsigned int irqx);										//清楚主标志寄存器内容
extern void IRQ_ClearSUBSRCPND(unsigned int irqx);									//清楚子标志寄存器内容
extern void IRQ_INTMSK_Init(unsigned int irqx, Functionalstate newstate);			//主屏蔽寄存器开启关闭
extern void IRQ_INTSUBMSK_Init(unsigned int irqx, Functionalstate newstate);		//子屏蔽寄存器开启关闭
extern Functionalstate IRQ_GetSRCPND(unsigned int irqx);							//获取主标志寄存器有没有响应
extern Functionalstate IRQ_GetSUBSRCPND(unsigned int irqx);							//获取子标志寄存器有没有响应

#endif

s3c2451_irq.c

#include "s3c2451_irq.h"

IRQ_MemMabPtr const IRQ_BASE_PTR[2] = { IRQ1_BASE_PTR, IRQ2_BASE_PTR};

/**函数名:IRQ_ClearSRCPND
  *参数:中断源irqx
  *功能:清楚主标志寄存器内容
  **/
void IRQ_ClearSRCPND(unsigned int irqx)
{
    IRQ_BASE_PTR[0]->SRCPND |= irqx;
	IRQ_BASE_PTR[0]->INTPND |= irqx;
}

/**函数名:IRQ_ClearSUBSRCPND
  *参数:中断源irqx
  *功能:清楚子标志寄存器内容
  **/
void IRQ_ClearSUBSRCPND(unsigned int irqx)
{
	IRQ_BASE_PTR[0]->SUBSRCPND |= irqx;
}

/**函数名:IRQ_INTMSK_Init
  *参数:中断源irqx
  *功能:主屏蔽寄存器开启关闭
  **/
void IRQ_INTMSK_Init(unsigned int irqx, Functionalstate newstate)
{
	if(newstate == ENABLE)
	{
		IRQ_BASE_PTR[0]->INTMSK &= ~irqx;
	}
	else
	{
		IRQ_BASE_PTR[0]->INTMSK |= irqx;
	}	
}

/**函数名:IRQ_INTSUBMSK_Init
  *参数:中断源irqx
  *功能:子屏蔽寄存器开启关闭
  **/
void IRQ_INTSUBMSK_Init(unsigned int irqx, Functionalstate newstate)
{
	if(newstate == ENABLE)
	{
		IRQ_BASE_PTR[0]->INTSUBMSK &= ~irqx;
	}
	else
	{
		IRQ_BASE_PTR[0]->INTSUBMSK |= irqx;
	}	
}

/**函数名:IRQ_GetSRCPND
  *参数:中断源irqx
  *返回值:
  *功能:获取主标志寄存器有没有响应
  **/
Functionalstate IRQ_GetSRCPND(unsigned int irqx)
{
	if((IRQ_BASE_PTR[0]->SRCPND & irqx) == irqx)
	{
		return ENABLE;
	}
	else
	{
		return DISABLE;
	}
}

/**函数名:IRQ_GetSUBSRCPND
  *参数:中断源irqx
  *返回值:
  *功能:获取子标志寄存器有没有响应
  **/
Functionalstate IRQ_GetSUBSRCPND(unsigned int irqx)
{
	if((IRQ_BASE_PTR[0]->SUBSRCPND & irqx) == irqx)
	{
		return ENABLE;
	}
	else
	{
		return DISABLE;
	}
}

s3c2451_it.h

#ifndef _S3C2451_IT_H
#define _S3C2451_IT_H


extern void __irq UART0_IRQ(void);

#endif

s3c2451_it.c

#include "s3c2451_it.h"
#include "main.h"

void __irq UART0_IRQ()
{
	U8 data;
	data = UART_RecvData(UART0);
	if(data == 'a')
	{
		UART_printf("点亮led1\n");
		GPIO_WriteBit(GPIOB, GPIO_Pin_5, BIT_RESET);
	}
	else if(data == 'b')
	{
		UART_printf("熄灭led1\n");
		GPIO_WriteBit(GPIOB, GPIO_Pin_5, BIT_SET);
	}
	else if(data == 'c')
	{
		UART_printf("蜂鸣器响\n");
		GPIO_WriteBit(GPIOB, GPIO_Pin_0, BIT_SET);
	}
	else if(data == 'd')
	{
		UART_printf("蜂鸣器不响\n");
		GPIO_WriteBit(GPIOB, GPIO_Pin_0, BIT_RESET);
	}
	
	IRQ_ClearSRCPND(INT_UART0);
	IRQ_ClearSUBSRCPND(SUBINT_RXD0);
}

s3c2451_uart.c添加函数:

/**函数名:My_interrupt_Uart
  *参数:波特率brandrate,
  *		 中断处理函数Hander_IRQ
  *功能:本人常用的串口初始化设置
  **/
void My_interrupt_Uart(U32 brandrate, U32 Hander_IRQ)
{
	UART_InitTypedef uart_inittypedef;
	uart_inittypedef.brandrate = brandrate;				//波特率
	uart_inittypedef.datalength = DataLength_8Bit;		
	uart_inittypedef.mode = Mode_rx_tx;
	uart_inittypedef.parity = Parity_No;
	uart_inittypedef.stop = STOP_ONE;
	
	UART_INIT(UART0, uart_inittypedef);	
	
	UART_interrupt_init(UART0, Hander_IRQ);
	IRQ_INTMSK_Init(INT_UART0, ENABLE);
	IRQ_INTSUBMSK_Init(SUBINT_RXD0, ENABLE);
}

main函数:

void Main(void)
{	
	My_interrupt_Uart(115200, (U32)UART0_IRQ);
	LED_INIT();
	
	while(1);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值