单片机/MCU论坛
直播中

李晶

8年用户 1012经验值
私信 关注
[问答]

TLE9893-2QKW62S SDADC解调后数据读取,中断方式无法读取数据怎么解决?

使用TLE9893-2QKW62S的SDADC实现旋转变压器sin+、sin-及cos+、cos-数据解调,使用查询方式可读取到SDADC的RES0 RESULT、RES1 RESULT(暂未知数据正确性),但使用中断方式可在上电后进入RESULT的中断回调几次,但后续再也无法进入中断回调,请问该如何配置SDADC的中断呢?
中断未开启:串口输出读取数据中断未开启:MCU Configuration Wizard-未开启中断中断未开启:keil主循环中读取数据开启中断:MCU Configuration Wizard-开启中断开启中断:串口输出读取数据开启中断:中断回调中读取数据

回帖(1)

醉清歌

2025-8-7 18:29:06

针对TLE9893-2QKW62S的SDADC中断方式无法持续读取数据的问题,以下是系统性解决方案:


根本原因分析



  1. 中断标志未清除:SDADC转换完成后触发的标志位未被清除,导致后续中断被阻塞。

  2. 寄存器访问冲突:在中断中直接读取RESULT寄存器可能触发硬件保护机制(需通过影子寄存器访问)。

  3. 配置顺序错误:中断使能时机不当或关键配置步骤缺失。


解决方案步骤


1. 正确配置中断标志清除


在中断回调函数中必须清除中断标志(关键步骤):


// SDADC中断回调函数示例
void SDADC_IRQHandler(void) {
    // 检查RES0中断标志
    if(SDADC->IRQSTAT & SDADC_IRQSTAT_RES0_IRQ_Msk) {
        // 读取RES0数据(通过影子寄存器)
        volatile uint32_t sinData = *(volatile uint32_t*)(SDADC_SHADOW_RES0_ADDR);

        // 清除中断标志(写1清除)
        SDADC->IRQSTAT = SDADC_IRQSTAT_RES0_IRQ_Msk;
    }

    // 检查RES1中断标志
    if(SDADC->IRQSTAT & SDADC_IRQSTAT_RES1_IRQ_Msk) {
        volatile uint32_t cosData = *(volatile uint32_t*)(SDADC_SHADOW_RES1_ADDR);
        SDADC->IRQSTAT = SDADC_IRQSTAT_RES1_IRQ_Msk;
    }
}


:寄存器地址请查阅手册(如SDADC_SHADOW_RES0_ADDR通常为0x400F6000



2. 修正硬件寄存器访问


禁止直接访问RESULT寄存器,改用影子寄存器机制:


// 错误方式(导致锁存):
// uint32_t data = SDADC->RES0_RESULT;

// 正确方式(通过预定义地址访问影子寄存器):
#define SDADC_SHADOW_RES0_ADDR    (*(volatile uint32_t*)0x400F6000)
uint32_t safe_data = SDADC_SHADOW_RES0_ADDR;

3. 优化初始化序列


按严格顺序配置(Keil Wizard生成的代码可能顺序错误):


void SDADC_Init(void) {
    // 1. 关闭SDADC
    SDADC->CTRL &= ~SDADC_CTRL_SDADCEN_Msk;

    // 2. 配置时钟/滤波器/增益等
    SDADC->FILTER = ...; // 滤波器设置
    SDADC->GAIN = ...;   // 增益设置

    // 3. 配置中断并清除所有遗留标志
    SDADC->IRQSTAT = 0xFFFFFFFF; // 清除所有标志
    SDADC->IRQEN = SDADC_IRQEN_RES0_IRQEN_Msk | SDADC_IRQEN_RES1_IRQEN_Msk;

    // 4. 最后使能SDADC
    SDADC->CTRL |= SDADC_CTRL_SDADCEN_Msk;

    // 5. 启动转换(连续模式)
    SDADC->START = SDADC_START_START_Msk;
}

4. 使能嵌套中断(NVIC配置)


MCU Configuration Wizard中:



  1. 勾选 NVIC SettingsSDADC_IRQ

  2. 设置优先级(建议0-1级)

  3. 生成代码后手动确认NVIC使能:
    // 在main()初始化中添加
    NVIC_EnableIRQ(SDADC_IRQn);
    NVIC_SetPriority(SDADC_IRQn, 0);


关键验证点



  1. 中断标志清除:使用调试器监控SDADC->IRQSTAT寄存器,每次中断后相应位应归零。

  2. 寄存器访问:检查是否存在对SDADC->RESx_RESULT的直接访问(替换为影子寄存器)。

  3. 转换状态:监控SDADC->STATUS寄存器确认SDADC处于运行状态(RUN位为1)。


调试建议



  • 最小化中断处理:在回调函数中仅读取数据+清除标志,避免复杂操作

  • 错误中断处理:添加对错误标志的监控:
    if(SDADC->IRQSTAT & SDADC_IRQSTAT_ERR_IRQ_Msk) {
      // 处理溢出/时钟错误等
      SDADC->IRQSTAT = SDADC_IRQSTAT_ERR_IRQ_Msk;
    }

  • 示波器验证:检查旋变激励信号(EXC)是否正常,确保SDADC前端电路工作


按照上述步骤调整后,中断应可持续触发。重点确保中断标志清除影子寄存器访问两个核心操作正确实现。如果问题仍存在,请检查硬件接线(特别是Sin/Cos差分信号质量)和供电稳定性。



注:具体寄存器位定义请参考《TLE9893 Technical Reference Manual》第22章SDADC章节。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分