原因其实很多,
下面就是一个例子:
代码里面的"while(1)"
在ble的例程里面,如果使用内部32K RC时钟,在做RC时钟校准时,需要用到当前芯片温度的函数,函数如下:
(该代码 位于CH573 EVT的EXAMBLEHALMCU.c 文件中,不同版本EVT 可能存在差异,下面代码来源于CH573 EVT 1.7 )
uint16 HAL_GetInterTempValue( void )
{
uint8 sensor, channel, config, tkey_cfg;
uint16 adc_data;
tkey_cfg = R8_TKEY_CFG;
sensor = R8_TEM_SENSOR;
channel = R8_ADC_CHANNEL;
config = R8_ADC_CFG;
ADC_InterTSSampInit();
R8_ADC_CONVERT |= RB_ADC_START;
while( R8_ADC_CONVERT & RB_ADC_START )
;
adc_data = R16_ADC_DATA;
R8_TEM_SENSOR = sensor;
R8_ADC_CHANNEL = channel;
R8_ADC_CFG = config;
R8_TKEY_CFG = tkey_cfg;
return ( adc_data );
}
这里很明显,有个while,
如果,我们在别处更高优先级(比如中断)里使用了这个外设,恰好在
R8_ADC_CONVERT |= RB_ADC_START;
之后,
while( R8_ADC_CONVERT & RB_ADC_START )
之前
那么,当我们在回到这里后,由于硬件状态机已经被中断改变,可能就会出现while 永远不会跳出的现象了.
解决方式有两种:
1,上述代码加原子操作(执行开始前关闭全局中断,结束后开全局中断)
2,不要在中断中 使用ADC;
原因其实很多,
下面就是一个例子:
代码里面的"while(1)"
在ble的例程里面,如果使用内部32K RC时钟,在做RC时钟校准时,需要用到当前芯片温度的函数,函数如下:
(该代码 位于CH573 EVT的EXAMBLEHALMCU.c 文件中,不同版本EVT 可能存在差异,下面代码来源于CH573 EVT 1.7 )
uint16 HAL_GetInterTempValue( void )
{
uint8 sensor, channel, config, tkey_cfg;
uint16 adc_data;
tkey_cfg = R8_TKEY_CFG;
sensor = R8_TEM_SENSOR;
channel = R8_ADC_CHANNEL;
config = R8_ADC_CFG;
ADC_InterTSSampInit();
R8_ADC_CONVERT |= RB_ADC_START;
while( R8_ADC_CONVERT & RB_ADC_START )
;
adc_data = R16_ADC_DATA;
R8_TEM_SENSOR = sensor;
R8_ADC_CHANNEL = channel;
R8_ADC_CFG = config;
R8_TKEY_CFG = tkey_cfg;
return ( adc_data );
}
这里很明显,有个while,
如果,我们在别处更高优先级(比如中断)里使用了这个外设,恰好在
R8_ADC_CONVERT |= RB_ADC_START;
之后,
while( R8_ADC_CONVERT & RB_ADC_START )
之前
那么,当我们在回到这里后,由于硬件状态机已经被中断改变,可能就会出现while 永远不会跳出的现象了.
解决方式有两种:
1,上述代码加原子操作(执行开始前关闭全局中断,结束后开全局中断)
2,不要在中断中 使用ADC;
举报