ADC的内部通道:
STM32的ADC除了可以用外部通道来采集外部模拟电压信号之外,还有两个内部通道16和17。其中通道16是连接至芯片上的温度传感器,通道17是连接至内部电源模块.(所以这两个通道可以用来检测STM32芯片d额温度和电源状态,就可以检测芯片运行的状态啦!)
温度检测实例:
通道16是把内部温度传感器输出的模拟电压转换成数字值,通过公式运算我们就可以得到温度值.内部温度传感器支持的温度范围从 -40 至 125摄氏度.精度是比较差的,所以只适合检测温度的变化,并不适合做绝对的温度检测.(如果需要测量精确的温度,可以使用一个外置的温度传感器)
main函数:
/用于存放ADC1转换的值/
extern __IO u16 ADC_ConvertedValue;
/温度值/
u16 Current_Temp;
int main(void)
{
/* USART1 config 115200 8-N-1 */
USART1_Config();
Temp_ADC1_Init();
while (1)
{
Delay(0xffffee); // 延时
Current_Temp=(V25-ADC_ConvertedValue)/Avg_Slope+25;
printf("\r\n The current temperature= %3d ℃ \r\n,Current_Temp);
main函数里面配置好串口1以及ADC1的通道16后,ADC转换的值就被DMA传输到ADC_ConvertedValue变量里面。然后就可以往串口不断更新温度数据了.
**根据STM32内部温度传感器检测温度的计算公式:
温度 = {(V25 - Vsense)/Avg_Slope}+25**
Vsense:通过ADC通道16检测的ADC转换值(变量)
V25:是25度时的ADC转换值(常量)
Avg_Slope:是温度与Vsense曲线的平均斜率(单位为 mV/ °C 或 μV/ °C)(常量)
Ps:
其中V25以及Avg_Slope都是根据数据手册定义好的宏(少了个#,好像会放大就不写了)
define V25 0x6EE
define Avg_Slope 0x05
ADC初始化:
void Temp_ADC1_Init(void)
{
ADC1_GPIO_Config();
ADC1_Mode_Config();
}
DMA以及ADC的配置:
static ADC1_Mode_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
/这里是DMA的配置/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//ADC1的地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;//内存地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设为数据源
DMA_InitStructure.DMA_BufferSize = 1;//DMA缓存大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址固定
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;//内存地址固定
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设传输数据单位半字
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //内存传输数据单位半字
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环传输
DMA_InitStructure.DMA_Priority = DMA_Priority_High;//优先级设置为高
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //关闭内存到内存的传输
DMA_Init(DMA1_Channel1, &DMA_InitStructure); //填充DMA,配置为DMA1的通道11
DMA_Cmd(DMA1_Channel1, ENABLE); //使能通道11
/*这里是ADC的配置*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立的ADC模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE ;//关闭扫描模式(扫描一般用于多通道采集)
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//开启连续转换模式(就是不停的进行ADC转换)
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不使用外部触发转换
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//采集的数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //要转换的通道数量是1个
ADC_Init(ADC1, &ADC_InitStructure);//填充ADC1
RCC_ADCCLKConfig(RCC_PCLK2_Div8); //设置ADC时钟的分频,为PCLK2的8分频,就是9HZ 72/8 = 9
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_239Cycles5);//配置ADC1的通道16为239.5个采样周期
ADC_TempSensorVrefintCmd(ENABLE);//使能温度传感器和内部参考电压
/*这里是ADC的复位校准操作*/
ADC_DMACmd(ADC1, ENABLE);//使能ADC1的DMA
ADC_Cmd(ADC1, ENABLE); //使能ADC1
ADC_ResetCalibration(ADC1);//复位ADC1校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1)); //等待校准寄存器复位成功
ADC_StartCalibration(ADC1);//ADC1校准
while(ADC_GetCalibrationStatus(ADC1));//等待ADC1校准成功
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使用软件触发ADC转换,因为没有采用外部触发
温度检测的ADC初始化和ADC采集外部数据时的差不多,只有以下两条有改变:
ADC_RegularChannelConfig(ADC1,ADC_Channel_16,1,ADC_SampleTime_239Cycles5)
配置ADC通道16,把周期改为ADC_SampleTime_239Cycles5(239.5周期),这个周期是根据手册推荐的内部温度传感器ADC转换时间为17.1us,这里为28us.
ADC_TempSensorVrefintCmd(ENABLE);
这是一个库函数,功能是使能或关闭内部温度传感器.它是使用内部温度传感器时必须调用的,默认的温度传感器shi不开启的,当然也就测量不到正确的温度值.