[应用相关] STM32DAC+TIM的方法

[复制链接]
1601|3
 楼主| 捉虫天师 发表于 2016-12-14 17:49 | 显示全部楼层 |阅读模式
TIM_SelectOutputTrigger
TIM_PrescalerConfig(TIM6, 0xF, TIM_PSCReloadMode_Update);
TIM_SetAutoreload(TIM6, 0xFF);


TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);


DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;
     DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
   DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
    DAC_Init(DAC_Channel_1, &DAC_InitStructure);
 楼主| 捉虫天师 发表于 2016-12-14 17:51 | 显示全部楼层
内部温度传感器(ADC采集)
STM32 有一个内部的温度传感器,可以用来测量 CPU 及周围的温度(TA)。该温度传感器在内部和 ADCx_IN16 输入通道相连接,此通道把传感器输出的电压转换成数字值。温度传感器模拟输入推荐采样时间是 17.1μ s。 STM32 的内部温度传感器支持的温度范围为: -40~125度,精度为± 1.5℃左右(实际效果不咋地)。
效果确实不咋地。。大冬天的测出来是20多度。。

STM32 内部温度传感器的使用很简单,只要设置一下内部 ADC,并激活其内部通道就差不多了。关于 ADC 的设置,我们在第上一章已经进行了详细的介绍,这里就不再多说。接下来我们介绍一下和温度传感器设置相关的 2 个地方。


第一个地方,我们要使用 STM32 的内部温度传感器,必须先激活 ADC 的内部通道,这里通过 ADC_CR2 的 AWDEN 位( bit23)设置。设置该位为 1 则启用内部温度传感器。第二个地方, STM32 的内部温度传感器固定的连接在 ADC 的通道 16 上,所以,我们在设置好 ADC 之后只要读取通道 16 的值,就是温度传感器返回来的电压值了。根据这个值,我们就可以计算出当前温度。计算公式如下:
T(℃) ={( V25-Vsense) /Avg_Slope}+25
上式中:
V25=Vsense 在 25 度时的数值(典型值为: 1.43)。
Avg_Slope=温度与 Vsense 曲线的平均斜率(单位: mv/℃或 uv/℃)(典型值: 4.3mv/℃)。
利用以上公式,我们就可以方便的计算出当前温度传感器的温度了。


上一节的ADC是读取外部通道的值,而内部温度传感器相当与把通道端口连接在内部温度传感器上。


配置ADC和上一节大体类似,只不过不用初始化外部IO,但要增加一句开启内部温度传感器的语句。

 楼主| 捉虫天师 发表于 2016-12-14 17:52 | 显示全部楼层
temperate.c
  1. #include "temperate.h"
  2. void T_Adc_Init(void)
  3. {
  4.         ADC_InitTypeDef ADC_ist;
  5.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE );
  6.         //72M/6=12,ADC 最大时间不能超过 14M
  7.         RCC_ADCCLKConfig(RCC_PCLK2_Div6);//设置 ADC分频因子6
  8.         ADC_DeInit(ADC1);//复位 ADC1,将外设 ADC1 的全部寄存器重设为缺省值
  9.        
  10.         ADC_ist.ADC_Mode= ADC_Mode_Independent;//ADC 独立模式
  11.         ADC_ist.ADC_ScanConvMode=DISABLE;//单通道模式
  12.         ADC_ist.ADC_ContinuousConvMode=DISABLE;//单次转换模式
  13.         //转换由软件而不是外部触发启动
  14.         ADC_ist.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
  15.         ADC_ist.ADC_DataAlign=ADC_DataAlign_Right;//ADC 数据右对齐
  16.         ADC_ist.ADC_NbrOfChannel=1;//顺序进行规则转换的 ADC 通道的数目
  17.         ADC_Init(ADC1,&ADC_ist);
  18.        
  19.         ADC_TempSensorVrefintCmd(ENABLE);  //开启内部温度传感器
  20.         ADC_Cmd(ADC1,ENABLE);//使能指定的 ADC1
  21.         ADC_ResetCalibration(ADC1);//开启复位校准
  22.         while(ADC_GetResetCalibrationStatus(ADC1));//等待复位校准结束
  23.         ADC_StartCalibration(ADC1);//开启 AD 校准
  24.         while(ADC_GetCalibrationStatus(ADC1));//等待校准结束
  25. }
  26. //获得 ADC 值
  27. //ch:通道值 0~3
  28. u16 T_Get_Adc(u8 ch)
  29. {
  30.         //设置指定 ADC 的规则组通道设置它们的转化顺序和采样时间
  31.         ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_239Cycles5);
  32.         ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能指定的 ADC1 的软件转换功能
  33.         while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//等待转换结束
  34.         return ADC_GetConversionValue(ADC1);//返回最近一次 ADC1 规则组的转换结果
  35. }
  36. u16 T_Get_Temp(void)
  37. {
  38.         u16 temp_val=0;u8 i;
  39.         for(i=0;i<10;i++)
  40.         {
  41.                 temp_val+=T_Get_Adc(ADC_Channel_16);
  42.                 delay_ms(5);
  43.         }
  44.         return temp_val/10;
  45. }
  46. u16 T_Get_Adc_Average(u8 ch,u8 times)
  47. {
  48.         u32 tem_val=0;
  49.         u8 i;
  50.         for(i=0;i<times;i++)
  51.         {
  52.                 tem_val+=T_Get_Adc(ch);
  53.                 delay_ms(5);
  54.         }
  55.         return tem_val/times;
  56. }
temperate.h
  1. #ifndef _TEMP_H
  2. #define _TEMP_H
  3. #include "sys.h"
  4. #include "delay.h"

  5. #define ADC_CH_TEMP          ADC_Channel_16 //温度传感器通道
  6. void T_Adc_Init(void);
  7. u16 T_Get_Adc(u8 ch);
  8. u16 T_Get_Temp(void);
  9. u16 T_Get_Adc_Average(u8 ch,u8 times);
  10. #endif


 楼主| 捉虫天师 发表于 2016-12-14 17:53 | 显示全部楼层
主函数是在上一节的基础上修改的。。
  1. #include "led.h"
  2. #include "delay.h"
  3. #include "sys.h"
  4. #include "usart.h"
  5. #include "lcd.h"
  6. #include "temperate.h"
  7. void init()
  8. {
  9.         delay_init();                     //延时函数初始化          
  10.         uart_init(9600);                 //串口初始化为9600
  11.         LED_Init();                                  //初始化与LED连接的硬件接口
  12.         LCD_Init();
  13.         T_Adc_Init();
  14.         POINT_COLOR=RED;//设置字体为红色
  15.         LCD_ShowString(60,40,200,24,24,"ADC Test ^-^");
  16.         LCD_ShowString(60,70,200,16,16,"Medium difficulty");
  17.         LCD_ShowString(60,90,200,16,16,"2015/1/25");
  18.         LCD_ShowString(60,110,200,16,16,"By--Mr yh");
  19.         //显示提示信息
  20.         POINT_COLOR=BLUE;//设置字体为蓝色
  21.         LCD_ShowString(60,130,200,16,16,"TEMP_VAL:");             
  22.         LCD_ShowString(60,150,200,16,16,"TEMP_VOL:0.000V");             
  23.         LCD_ShowString(60,170,200,16,16,"TEMPERATE:00.00C");          
  24. }
  25. int main(void)
  26. {
  27.         u16 adcnum;
  28.         float tem,temperate;
  29.         init();
  30.         while(1)
  31.         {
  32.                 adcnum=T_Get_Adc_Average(ADC_CH_TEMP,10);
  33.                 LCD_ShowxNum(132,130,adcnum,4,16,0);//显示ADC的值
  34.                 tem=(float)adcnum*(3.3/4096);
  35.                 temperate=tem;
  36.                 adcnum=tem;
  37.                 LCD_ShowxNum(132,150,adcnum,1,16,0);//显示电压值的整数位
  38.                 tem-=(u8)tem;
  39.                 LCD_ShowxNum(148,150,(u32)(tem*1000),3,16,0X80);//显示电压值的小数位
  40.                 temperate=(1.43-temperate)/0.0043+25;                //计算出当前温度值
  41.                 LCD_ShowxNum(140,170,(u8)temperate,2,16,0); //显示温度整数部分
  42.                 temperate-=(u8)temperate;
  43.                 LCD_ShowxNum(164,170,temperate*100,2,16,0X80);//显示温度小数部分
  44.                 LED0=!LED0;
  45.                 delay_ms(250);
  46.         }
  47. }


您需要登录后才可以回帖 登录 | 注册

本版积分规则

216

主题

3284

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部