文章目录
- 前言
- 现象描述
- 原因分析
- 解决方案
- 总结
前言
最近项目用瑞萨RH850系列的1372/1374开发,官方的MCAL做的不咋地就算了,FAE支持也很少。给的demo问题也很多。本文记录一下开发过程中的问题。
现象描述
MCAL配置完ADC1后,运行ADC1的采样程序就跑飞,不管是SW触发的Group还是HW触发的Group,采用的是Interrupt方式。实际在TargetMap中也加入了对应的中断函数。(demo中ADC1的中断没有map)
原因分析
程序版本回退到不触发ADC1采样时,可以正常运行。所以肯定跟ADC1的中断有关。查看EIIC寄存器的值为0x10AA,对应中断为INTADCF1|3,与我配置的中断一致。实际打断点测试中断没有进,所以在进中断之前就跑飞了。也不知道应该在哪里打断点了。
怀疑是中断没有使能,但在代码中没有看到使能中断的函数。
查看初始化的代码,有一个数组,里面应该是地址,查看地址果然是中断控制器寄存器对应的地址。
如下所示:
uint32 RenICR_ADRR[] = {
0xFFFFB040, 0xFFFFB042, 0xFFFFB044, 0xFFFFB046,
0xFFFFB048, 0xFFFFB06A, 0xFFFFB06C, 0xFFFFB06E,
0xFFFFB070, 0xFFFFB072, 0xFFFFB074, 0xFFFFB076,
0xFFFFB078, 0xFFFFB100, 0xFFFFB102, 0xFFFFB104,
0xFFFFB106, 0xFFFFB108, 0xFFFFB10A, 0xFFFFB10C,
0xFFFFB11A, 0xFFFFB11C, 0xFFFFB11E, 0xFFFFB120,
0xFFFFB122, 0xFFFFB124, 0xFFFFB126, 0xFFFFB128,
0xFFFFB08A, 0xFFFFB08C, 0xFFFFB08E,
0xFFFFB092, 0xFFFFB094, 0xFFFFB096, 0xFFFFB098,
0xFFFFB09A, 0xFFFFB09C, 0xFFFFB09E, 0xFFFFB138,
0xFFFFB13A, 0xFFFFB13C, 0xFFFFB13E, 0xFFFFB140,
0xFFFFB142, 0xFFFFB144, 0xFFFFB146, 0xFFFFB148,
0xFFFFB14A, 0xFFFFB090, 0xFFFFB0A0, 0xFFFFB0A2,
0xFFFFB0A4, 0xFFFFB0A6, 0xFFFFB0A8, 0xFFFFB0AA,
0xffffffff
};
实际操作如下:
void Reg_Init(void)
{
uint16 *ptr;
uint8 count;
for (count = 0; RenICR_ADRR[count] != 0xffffffff; count++)
{
ptr = (uint16 *)RenICR_ADRR[count];
*ptr |= 0x47;
}
}
之前一直没有注意这个代码是做什么的,只能说太low了,函数名也没有,备注也没有。不查手册根本不知道在干嘛
查看数组中的地址,果然没有ADC1的,所以ADC1的中断会异常。
对应的寄存器描述如下:
CTn:该位表示中断通道类型。这个位是只读的。
0:表示当前选择与边缘同步检测。
1:表示当前已选中高电平检测。
RFn:这是一个中断请求标志。
RFn位可以从程序中写入。将RFn位设置为1会产生一个EI级别的可屏蔽中断n (INTn),就像中断请求被确认时一样。
0:不发出中断请求(复位后的值)。
1:发出中断请求。
当CTn设置为0时,当中断请求被CPU内核确认时,该位自动清除。可通过软件进行设置和清除
当CTn设置为1时,该位不能通过软件设置或清除。当中断请求被CPU内核确认时,该参数不被清除。
MKn:这是中断请求屏蔽位。为1时屏蔽对应中断的请求。
TBn:这个位用来选择确定中断向量的方式。
0:直接跳转到由优先级确定的地址
1:表引用
中断向量的确定方法请参见RH850系列用户手册:软件
P3n to P0n:这些位将中断优先级指定为16个级别之一,其中0为最高,15为最低。
当多个EI级中断请求同时发出时,从这些位中具有最高优先级设置的源中断被选择并传送到CPU核心首先进行服务。当P3n到P0n位为同时发生的中断请求指定相同的优先级级别时,通道编号较低的源具有高优先级。这个顺序是固定的。
上面对寄存器的值写的0x47,表示使能中断,使用表引用,中断优先级为7
解决方案
快速解决方案为在数组中增加ADC1的寄存器地址,长期解决方案应该使用规范的接口来使能中断和配置优先级。
uint32 RenICR_ADRR[] = {
0xFFFFB040, 0xFFFFB042, 0xFFFFB044, 0xFFFFB046,
0xFFFFB048, 0xFFFFB06A, 0xFFFFB06C, 0xFFFFB06E,
0xFFFFB070, 0xFFFFB072, 0xFFFFB074, 0xFFFFB076,
0xFFFFB078, 0xFFFFB100, 0xFFFFB102, 0xFFFFB104,
0xFFFFB106, 0xFFFFB108, 0xFFFFB10A, 0xFFFFB10C,
0xFFFFB11A, 0xFFFFB11C, 0xFFFFB11E, 0xFFFFB120,
0xFFFFB122, 0xFFFFB124, 0xFFFFB126, 0xFFFFB128,
0xFFFFB08A, 0xFFFFB08C, 0xFFFFB08E,
0xFFFFB092, 0xFFFFB094, 0xFFFFB096, 0xFFFFB098,
0xFFFFB09A, 0xFFFFB09C, 0xFFFFB09E, 0xFFFFB138,
0xFFFFB13A, 0xFFFFB13C, 0xFFFFB13E, 0xFFFFB140,
0xFFFFB142, 0xFFFFB144, 0xFFFFB146, 0xFFFFB148,
0xFFFFB14A, 0xFFFFB090, 0xFFFFB0A0, 0xFFFFB0A2,
0xFFFFB0A4, 0xFFFFB0A6, 0xFFFFB0A8, 0xFFFFB0AA,
0xFFFFB14C, 0xFFFFB14E, 0xFFFFB150, 0xFFFFB152,0xFFFFB154, 0xFFFFB156, /* Use for adc1 INTADCF1ERR INTADCF1I0 INTADCF1I1 INTADCF1I2 INTADCF1I3 INTADCF1I4 */
0xffffffff
};
如果遇到其他开中断跑飞的情况,可以参考上述解决方案。
总结
瑞萨的MCAL做的不完善就算了,支持还少,后面可能还会有更多的坑。