2440 ARM中断服务程序Isr_Init详解:异常与定时器1中断处理

需积分: 9 3 下载量 125 浏览量 更新于2024-09-14 收藏 55KB DOC 举报
本文主要针对Atmel ATMega2440单片机平台的中断系统进行深入解析,具体聚焦于`main.c`文件中的`Isr_Init`函数。`Isr_Init`是初始化中断服务程序的关键部分,它在中断发生时确保了正确的中断处理流程。 首先,函数`Isr_Init`的主要任务是设置中断向量表(Interrupt Vector Table,IVT)。IVT是系统内存中的一块区域,用于存储中断处理程序的地址,当对应的中断源触发时,处理器会自动跳转到该地址执行相应的服务代码。在这里,作者将四个特殊的中断向量指向了`HaltUndef`、`HaltSwi`、`HaltPabort`和`HaltDabort`这些预定义的处理函数,它们分别对应未定义指令、软件中断、PABORT(预取中止)和DAABORT(数据访问中止)等异常情况。 `HaltUndef`函数被设置为未定义指令异常的处理函数,当遇到无法识别的指令时,系统会调用这个函数来报告错误并停止执行。该函数的内容简单明了,通过`Uart_Printf`输出错误信息后进入无限循环,防止程序进一步执行。 紧接着,文章提到`Timer1_ISR`中断服务程序,这是一个定时中断的例子。每当定时器1溢出时,就会触发中断,这个函数会更新一个计数器并设置相应的中断标志位,以便外部能够检查中断是否已处理。这里的`static int count`变量用于记录定时器的计数,每经过一秒,计数加一,并且通过调整中断屏蔽寄存器`rINTPND`和`rSRCPND`来控制中断的处理。 总结来说,`Isr_Init`函数在Atmega2440中扮演着至关重要的角色,它初始化中断向量表,确保在不同类型的中断发生时,处理器能够准确地跳转到相应的处理函数,执行相应的错误处理或周期性任务。理解这个函数的工作原理有助于开发人员更好地管理和优化他们的嵌入式系统,提高系统的可靠性和响应速度。

#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File #include "DSP2833x_Examples.h" // DSP2833x Examples Include File #include "leds.h" #include "time.h" #include "uart.h" /******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ Uint16 rx_buf[50]; int count = 0; int timeoutFlag = 0; int systick = 0; int send_flag = 0; int alarm_flag = 0; void interrupt ISR_RXD(void); void main() { int i = 0; int distance; int speed; int time; char buff[] = {0x55 ,0x5A ,0x02 ,0xD3 ,0x84,0x00}; char *msg = (char *)buff; Uint16 *p = 0; Uint16 ReceivedChar=0; InitSysCtrl(); InitPieCtrl(); IER = 0x0000; IFR = 0x0000; InitPieVectTable(); LED_Init(); TIM0_Init(150,1000);//200ms UARTa_Init(115200); EALLOW; PieVectTable.SCIRXINTA=&ISR_RXD; EDIS; IER |= M_INT9; PieCtrlRegs.PIEIER9.bit.INTx1= 1; EINT; ERTM; while(1) { if(systick-send_flag>=100) { send_flag = systick; UARTa_SendString(msg); } if(alarm_flag) { LED7_TOGGLE; alarm_flag = 0; send_flag = systick; while(systick-send_flag<=1000); LED7_TOGGLE; } if((timeoutFlag>=10)&&(count>=12)) { for(i = 0;i<count;i++) { if((rx_buf[i] == 0x55)&&((rx_buf[i+1] == 0xA5))) { p = &rx_buf[i]; break; } } if(p!=0) { distance = p[4]*256+p[5]; speed =p[6]*256+p[7]; time=distance/speed; if(time<=2) alarm_flag = 1; else alarm_flag = 0; p = 0; } count = 0; timeoutFlag = 0; } } } void interrupt ISR_RXD(void) { PieCtrlRegs.PIEACK.all = PIEACK_GROUP9; rx_buf[count] = SciaRegs.SCIRXBUF.all; count++; timeoutFlag = 0; }详细解释这段代码

2023-06-07 上传

注释以下每一行代码#include "bflb_mtimer.h" #include "bflb_uart.h" #include "bflb_clock.h" #include "board.h" struct bflb_device_s *uartx; void uart_isr(int irq, void *arg) { uint32_t intstatus = bflb_uart_get_intstatus(uartx); int ret; uint32_t baudrate; if (intstatus & UART_INTSTS_RX_AD5) { bflb_uart_int_clear(uartx, UART_INTCLR_RX_AD5); ret = bflb_uart_feature_control(uartx, UART_CMD_GET_AUTO_BAUD, UART_AUTO_BAUD_0X55); baudrate = bflb_clk_get_peripheral_clock(BFLB_DEVICE_TYPE_UART, uartx->idx) / (ret + 1); printf("Detected baudrate by 0x55 is %d\r\n", baudrate); } if (intstatus & UART_INTSTS_RX_ADS) { bflb_uart_int_clear(uartx, UART_INTCLR_RX_ADS); ret = bflb_uart_feature_control(uartx, UART_CMD_GET_AUTO_BAUD, UART_AUTO_BAUD_START); baudrate = bflb_clk_get_peripheral_clock(BFLB_DEVICE_TYPE_UART, uartx->idx) / (ret + 1); printf("Detected baudrate by startbit is %d\r\n", baudrate); } } int main(void) { board_init(); board_uartx_gpio_init(); uartx = bflb_device_get_by_name(DEFAULT_TEST_UART); struct bflb_uart_config_s cfg; cfg.baudrate = 2000000; cfg.data_bits = UART_DATA_BITS_8; cfg.stop_bits = UART_STOP_BITS_1; cfg.parity = UART_PARITY_NONE; cfg.flow_ctrl = 0; cfg.tx_fifo_threshold = 7; cfg.rx_fifo_threshold = 7; bflb_uart_init(uartx, &cfg); bflb_uart_feature_control(uartx, UART_CMD_SET_AUTO_BAUD, 1); bflb_uart_feature_control(uartx, UART_CMD_SET_ABR_ALLOWABLE_ERROR, 3); bflb_irq_attach(uartx->irq_num, uart_isr, NULL); bflb_irq_enable(uartx->irq_num); while (1) { } }

2023-05-15 上传