针对TLE9893-2QKW62S的SDADC中断方式无法持续读取数据的问题,以下是系统性解决方案:
RESULT寄存器可能触发硬件保护机制(需通过影子寄存器访问)。在中断回调函数中必须清除中断标志(关键步骤):
// 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)
禁止直接访问RESULT寄存器,改用影子寄存器机制:
// 错误方式(导致锁存):
// uint32_t data = SDADC->RES0_RESULT;
// 正确方式(通过预定义地址访问影子寄存器):
#define SDADC_SHADOW_RES0_ADDR (*(volatile uint32_t*)0x400F6000)
uint32_t safe_data = SDADC_SHADOW_RES0_ADDR;按严格顺序配置(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;
}在MCU Configuration Wizard中:
// 在main()初始化中添加
NVIC_EnableIRQ(SDADC_IRQn);
NVIC_SetPriority(SDADC_IRQn, 0);SDADC->IRQSTAT寄存器,每次中断后相应位应归零。SDADC->RESx_RESULT的直接访问(替换为影子寄存器)。SDADC->STATUS寄存器确认SDADC处于运行状态(RUN位为1)。if(SDADC->IRQSTAT & SDADC_IRQSTAT_ERR_IRQ_Msk) {
// 处理溢出/时钟错误等
SDADC->IRQSTAT = SDADC_IRQSTAT_ERR_IRQ_Msk;
}按照上述步骤调整后,中断应可持续触发。重点确保中断标志清除和影子寄存器访问两个核心操作正确实现。如果问题仍存在,请检查硬件接线(特别是Sin/Cos差分信号质量)和供电稳定性。
注:具体寄存器位定义请参考《TLE9893 Technical Reference Manual》第22章SDADC章节。
举报
更多回帖