手搓瑞萨单片机IO – RA2L1

/ 0评 / 0

之前就已经自己写启动文件,成功执行到FreeRTOS空跑,现在计划做一个IO应用.

需要怎么看呢,就是找手册.

static void app_main(void *args)
{
    (void) args;

    // 解除 PFS 写保护:先允许写 PFSWE,再置位 PFSWE
    R_PMISC->PWPR = 0;           // B0WI = 0
    R_PMISC->PWPR = (1U << 6);   // PFSWE = 1(允许改 PmnPFS)

    R_PFS->PORT[0].PIN[1].PmnPFS_b.PMR  = 0;   // GPIO 模式
    R_PFS->PORT[0].PIN[1].PmnPFS_b.PDR  = 0;   // 输入
    R_PFS->PORT[0].PIN[1].PmnPFS_b.ISEL = 1;   // 使能作为 IRQn 引脚

    R_PFS->PORT[4].PIN[3].PmnPFS_b.PMR  = 0;  // 端口模式(不是外设)
    R_PFS->PORT[4].PIN[3].PmnPFS_b.PODR = 1;  // 先写输出数据寄存器位
    R_PFS->PORT[4].PIN[3].PmnPFS_b.PDR  = 1;  // 再把方向设为输出

    R_PFS->PORT[4].PIN[4].PmnPFS_b.PMR  = 0;
    R_PFS->PORT[4].PIN[4].PmnPFS_b.PODR = 1;
    R_PFS->PORT[4].PIN[4].PmnPFS_b.PDR  = 1;

    R_PFS->PORT[4].PIN[5].PmnPFS_b.PMR  = 0;
    R_PFS->PORT[4].PIN[5].PmnPFS_b.PODR = 1;
    R_PFS->PORT[4].PIN[5].PmnPFS_b.PDR  = 1;

    // 重新上锁 PFS
    R_PMISC->PWPR = 0;           // B0WI = 0(允许改 PFSWE)
    R_PMISC->PWPR = (1U << 7);   // B0WI = 1,上锁;同时 PFSWE 清 0

    R_ICU->IRQCR_b[1].FLTEN = 1;      // 开滤波(可选)
    R_ICU->IRQCR_b[1].FCLKSEL = 0b10; // 采样时钟 PCLKB/32(示例)
    R_ICU->IRQCR_b[1].IRQMD = 0b00;   // 下降沿

    R_ICU->IELSR[7] = 0;
    R_ICU->IELSR_b[7].IELS = 0x11;
    R_ICU->IELSR_b[7].IR = 0;

    // NVIC:清挂起,设优先级,开中断 -- 槽号 = IELSR 索引
    NVIC_ClearPendingIRQ((IRQn_Type)7);
    NVIC_SetPriority((IRQn_Type)7, 3);     // 自定优先级(0 = 最高)
    NVIC_EnableIRQ((IRQn_Type)7);

    for (;;)
    {
        R_PORT4->PCNTR3_b.PORR = (1U << 3);  // 复位
        vTaskDelay(100);
        R_PORT4->PCNTR3_b.PORR = (1U << 4);  // 复位
        vTaskDelay(100);
        R_PORT4->PCNTR3_b.PORR = (1U << 5);  // 复位
        vTaskDelay(100);
        R_PORT4->PCNTR3_b.POSR = (1U << 3);  // 复位
        vTaskDelay(100);
        R_PORT4->PCNTR3_b.POSR = (1U << 4);  // 复位
        vTaskDelay(100);
        R_PORT4->PCNTR3_b.POSR = (1U << 5);  // 复位
        vTaskDelay(100);
        // R_PORT4->PIDR_b.PIDR0;
    }
}

瑞萨的中断和STM32这些还不同,属于很自由的那种.

void __attribute__((interrupt)) irq1_falling_isr(void);
void __attribute__((interrupt)) irq1_falling_isr(void)
{
    volatile uint32_t dummy = R_PFS->PORT[0].PIN[1].PmnPFS; // 读一次,保证时序
    (void)dummy;
    R_ICU->IELSR_b[7].IR = 0;   // 写 0 清 IR(DTCE 要为 0)
    // ... 用户处理 ...
}

__attribute__((used)) const exc_ptr_t __VectorsApplication[32] __attribute__((section(".application_vectors"))) = {
    [7] = irq1_falling_isr,
    // 其他没用到的保持 0 或默认
};

完成最简单的裸戳中断.

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注