ADC采集内部温度传感器的时候,下载开发板自带例程,读温度正常;移植到ucos后,读温度异常。逐行比对,发现温度传感器使能函数位置引起的。
【正常程序】如下:
//时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟
//初始化ADC1通道5IO口---PA5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PA5 通道5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
//复位ADC1
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE); //复位ADC1
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE); //复位结束
/* 使能内部温度传感器 */
ADC_TempSensorVrefintCmd(ENABLE);
【异常程序】如下:
//时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟
/* 使能内部温度传感器 */
ADC_TempSensorVrefintCmd(ENABLE);
//初始化ADC1通道5IO口---PA5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PA5 通道5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
//复位ADC1
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE); //复位ADC1
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE); //复位结束
问题就出在:温度传感器使能函数放在了ADC复位函数之前
为什么放在它之前不可以?
因为即便使能了,但是一旦复位后,使能也就没用了,除非再次使能。不过应该不会有人这么做,除非他蛋疼。
为什么复位这么函数这么牛逼?如果我想复位ADC2/3是不是也可以直接在参数里填上就可以了?
于是我goto了,发现……
#define RCC_APB2Periph_ADC ((uint32_t)0x00000100)
#define RCC_APB2Periph_ADC1 ((uint32_t)0x00000100)
#define RCC_APB2Periph_ADC2 ((uint32_t)0x00000200)
#define RCC_APB2Periph_ADC3 ((uint32_t)0x00000400)
看来确实是,想复位谁,直接把形参换成对应的ADC选项就可以了。
不过,既然都看到了Hex了,不如再看下寄存器位吧,于是打开了datasheet
位 10:9 保留,必须保持复位值。
位 8 ADCRST:ADC 接口复位(所有 ADC 共用)(ADC interface reset (common to all ADCs))
由软件置 1 和清零。
0:不复位 ADC 接口
1:复位 ADC 接口
这就日了狗了
所以,想复位ADC2/3,只能选择“RCC_APB2Periph_ADC”或者“RCC_APB2Periph_ADC1”,但是,这样的话所有的ADC都会复位。
若有错误之处,还请诸位不吝赐教!多谢!(jnfxx)