映射 SAM L10 设备的中断处理程序

Posted

技术标签:

【中文标题】映射 SAM L10 设备的中断处理程序【英文标题】:Map interrupt handlers for SAM L10 device 【发布时间】:2022-01-04 00:24:15 【问题描述】:

我一直试图在使用 SAM L10 MCU 的系统上设置 I2C。我已经能够在 MPLAB X 上将我的项目作为独立项目构建,而无需使用 MPLAB Harmony v3 代码配置器。我的问题是我似乎无法正确映射中断处理程序。

以下是我正在使用的参考资料: https://github.com/Microchip-MPLAB-Harmony/csp_apps_sam_l10_l11/tree/master/apps/sercom/i2c/master/i2c_eeprom 和 https://microchipdeveloper.com/32arm:samd21-code-gcc-nvic-example

在这两种情况下,似乎都有一个为中断处理程序分配函数指针的表,称为exception_table。我不知道将它合并到我的代码中的正确方法,事实上,我不明白这段代码实际上是如何执行的,因为它只是分配函数指针。

这是我的代码:

init.c

#include <xc.h>
#include "peripheral/clock/plib_clock.h"
#include "peripheral/nvic/plib_nvic.h"
#include "peripheral/sercom/plib_sercom0_i2c_master.h"

#pragma config NVMCTRL_NSULCK = 0x7
#pragma config BOD33_LEVEL = 0x6
#pragma config BOD33_DIS = CLEAR
#pragma config BOD33_ACTION = 0x1
#pragma config WDT_RUNSTDBY = CLEAR
#pragma config WDT_ENABLE = SET
#pragma config WDT_ALWAYSON = CLEAR
#pragma config WDT_PER = 0x9
#pragma config WDT_WINDOW = 0xB
#pragma config WDT_EWOFFSET = 0xB
#pragma config WDT_WEN = CLEAR
#pragma config BOD33_HYST = CLEAR


void port_init (void)

    /* Configure SERCOM0 I2C on PA22 and PA23, Peripheral function C */
    PORT_REGS->GROUP[0].PORT_PINCFG[22] = 0x1;
    PORT_REGS->GROUP[0].PORT_PINCFG[23] = 0x1;
    PORT_REGS->GROUP[0].PORT_PMUX[11] = 0x22;

    
    /* Configure PA25 as an output driven high */
    PORT_REGS->GROUP[0].PORT_DIR = 0x02000000;
    PORT_REGS->GROUP[0].PORT_OUT = 0x02000000;
    PORT_REGS->GROUP[0].PORT_PINCFG[27] = 0x0;


void sys_initialise (void)

    CLOCK_Initialize ();
    port_init ();
    
    
    SERCOM0_I2C_Initialize ();
    NVIC_Initialize ();   
  

main.c

#include <xc.h>
#include "init.h"
#include "peripheral/sercom/plib_sercom0_i2c_master.h"

void main (void)

    sys_initialise ();

    uint8_t reg[1];
    reg[0] = 0xD0;    

    SERCOM0_I2C_Write (0x76, &reg[0], 2);    

我使用 GPIO 进行调试。我认为设置 NVIC 就足够了,但它只启用中断本身,中断处理程序仍未映射。我可以看到它,因为从我的调试中,当我尝试通过 I2C 发送内容时,处理程序永远不会被调用。我还可以看到 I2C 可以正常工作以发送事务的第一部分,即直到 ACK 位的设备地址。从这一点开始,我可以在示波器上看到时钟保持低电平,但 SDA 又回到高电平。我相信这是因为来自https://github.com/Microchip-MPLAB-Harmony/csp_apps_sam_l10_l11/blob/master/apps/sercom/i2c/master/i2c_eeprom/firmware/src/config/sam_l10_xpro/peripheral/sercom/i2c_master/plib_sercom0_i2c_master.c 的中断处理程序SERCOM0_I2C_InterruptHandler 没有被调用,因为它负责发送其余数据。

【问题讨论】:

什么是NVIC_Initialize?你不应该在某处有类似NVIC_EnableIRQ 的东西吗?我不记得各种 SAM 的所有细节,但 NVIC 外设中有可能需要配置的寄存器。 嗨@Lundin,我错过了对NVIC_SetVector() 的调用,它将我提到的中断处理程序与向量表中的相应异常相关联。 【参考方案1】:

我在 xc32 编译器的用户指南中找到了答案,可以在这里访问:https://ww1.microchip.com/downloads/en/DeviceDoc/XC32_PICC_UG_DS50002895A.pdf

我错过了对 NVIC_SetVector() 的调用 - 第 14.3 节展示了如何将中断处理程序与异常相关联。

【讨论】:

以上是关于映射 SAM L10 设备的中断处理程序的主要内容,如果未能解决你的问题,请参考以下文章

使用printf()时,Spi中断处理程序工作

中断机构和中断处理程序

《Linux内核设计与实现》学习笔记——中断中断处理程序

Linux 中断所有知识点

《Linux设备驱动程序》(十六)-中断处理

中断的上半部分与下半部分