OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9782|回复: 9

STM32 ADC 中断方式 如何采集温度传感器数据 ??

[复制链接]

7

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2013-4-19
在线时间
3 小时
发表于 2013-4-22 13:20:51 | 显示全部楼层 |阅读模式
STM32   ADC  中断方式  如何采集温度传感器数据 ?? 
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-4-22 14:00:46 | 显示全部楼层
看温度传感器的数据手册.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

7

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2013-4-19
在线时间
3 小时
 楼主| 发表于 2013-4-22 14:06:22 | 显示全部楼层
回复【2楼】正点原子:

看温度传感器的数据手册.

---------------------------------
#include "stm32f10x.h"
#include "stm32_eval.h"
#include <stdio.h>

#define  ADC1_DR_Address                  ((uint32_t)0x4001244C) //ADC1 DR寄存器基地址
u16 adcx;

void ADC1_Configuration(void)   
 {   
     ADC_InitTypeDef ADC_InitStructure;     
     //启动ADC1时钟    
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); 
     ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //转换模式为独立,还有交叉等非常多样的选择   
     ADC_InitStructure.ADC_ScanConvMode = DISABLE;   
     ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  //连续转换开启    
     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;   
     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;   
     ADC_InitStructure.ADC_NbrOfChannel = 1;       
     ADC_Init(ADC1, &ADC_InitStructure);   
       
     //ADC内置温度传感器使能(要使用片内温度传感器,切忌要开启它)    
     ADC_TempSensorVrefintCmd(ENABLE);   
       
     ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_239Cycles5); 
    
     ADC_Cmd(ADC1, ENABLE);   
    
     ADC_ResetCalibration(ADC1);   
     // Check the end of ADC1 reset calibration register    
     while(ADC_GetResetCalibrationStatus(ADC1));   
    
     // Start ADC1 calibaration    
     ADC_StartCalibration(ADC1);   
     // Check the end of ADC1 calibration    
     while(ADC_GetCalibrationStatus(ADC1));   
     // ADC自动校准结束---------------    
     ADC_SoftwareStartConvCmd(ADC1, ENABLE); //ADC启动    
 }  

  void USART1_Configuration(void)
 {
     USART_InitTypeDef USART_InitStructure;
     
     USART_InitStructure.USART_BaudRate = 9600;
     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
     USART_InitStructure.USART_StopBits = USART_StopBits_1;
     USART_InitStructure.USART_Parity = USART_Parity_No;
     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
     USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
     USART_Init(USART1, &USART_InitStructure);
     
     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
     
     USART_Cmd(USART1, ENABLE);
 }

  int fputc(int ch, FILE *f)
 {
     //USART_SendData(USART1, (u8) ch);
     USART1->DR = (u8) ch;
     
    /* Loop until the end of transmission */
     while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
     {
     }
 
    return ch;
 }

void delay_ms(u16 nms)
{        
   while(nms);
   nms--;    
}  

int main(void)
{
   ADC1_Configuration();
   USART1_Configuration();
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
{
adcx=ADC_GetConversionValue(ADC1);
printf("%d\r\n",adcx);
 delay_ms(1999999);
}

}


 u16 ADCConvertedValue;
 void ADC1_2_IRQHandler(void)
 {
  ADCConvertedValue=ADC_GetConversionValue(ADC1);
  ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);
 }

哪儿有错啊? 串口没有数据输出啊
回复 支持 反对

使用道具 举报

7

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2013-4-19
在线时间
3 小时
 楼主| 发表于 2013-4-22 14:40:24 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
#include "stm32f10x_lib.h" 用新版本的哪些文件来替换?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-4-22 14:56:32 | 显示全部楼层
http://www.openedv.com/posts/list/0/10955.htm#58784
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

7

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2013-4-19
在线时间
3 小时
 楼主| 发表于 2013-4-22 15:49:37 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
参考网上的程序后自己改写了部分,为什么串口不显示啊????  搞了2天了,急死我了,新手伤不起啊,没人指导!

/******************************************************************************
 * 文件实现ADC模块的基本功能
 * 设置ADC1的常规转换序列包含CH10和CH16(片内温度传感器)
 * 设置了连续转换模式,并使用DMA传输
 * AD转换值被放在了AD_Value[2]数组内,[0]保存CH0结果,[1]保存CH16结果
 * GetVolt函数计算[0]的值对应的电压值(放大100倍,保留2位小数)
 * GetTemp函数计算[1]的值对应的温度值,计算公式在相应函数内有说明
 *******************************************************************************/
 
/* Includes ------------------------------------------------------------------*/
// #include "stm32f10x_lib.h"
#include "stm32f10x.h"
#include "stm32_eval.h"
#include "stm32f10x_conf.h"
#include "stm32f10x_dac.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_rcc.h"
#include <stdio.h>

/* rivate typedef -----------------------------------------------------------*/
 /* rivate define ------------------------------------------------------------*/
 #define ADC1_DR_Address    ((u32)0x4001244C)
 /* rivate macro -------------------------------------------------------------*/
 /* rivate variables ---------------------------------------------------------*/
 vu16 AD_Value[2];
 vu16 i=0;
 s16  Temp;
 u16  Volt;
 
/* rivate function prototypes -----------------------------------------------*/
 void RCC_Configuration(void);
 void GPIO_Configuration(void);
 void NVIC_Configuration(void);
 void USART1_Configuration(void);
 void ADC1_Configuration(void);
 void DMA_Configuration(void);
 
int fputc(int ch, FILE *f);
 void Delay(void);
 u16 GetTemp(u16 advalue);
 u16 GetVolt(u16 advalue);
 /* rivate functions ---------------------------------------------------------*/
 /*******************************************************************************
 * Function Name: main
 * Description : Main program.
 * Input       : None
 * Output      : None
 * Return      : None
 *******************************************************************************/
 int main(void)
 {
     RCC_Configuration();
     GPIO_Configuration();
     NVIC_Configuration();
     USART1_Configuration();
     DMA_Configuration();
     ADC1_Configuration();
     
    //启动第一次AD转换
     ADC_SoftwareStartConvCmd(ADC1, ENABLE); 
    //因为已经配置好了DMA,接下来AD自动连续转换,结果自动保存在AD_Value处   
    
    while (1)
     {
         Delay();
         Temp = GetTemp(AD_Value[1]);
         Volt = GetVolt(AD_Value[0]);
         //注意,USART_SendData函数不检查是否发送完成
         //等待发送完成
         while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)   
       {
    printf("电压:%d.%d\t温度:%d.%d℃\r\n", Volt/100, Volt%100, Temp/100, Temp%100);
   }
         
    }
 }

/*******************************************************************************
 * Function Name: 重定义系统putchar函数int fputc(int ch, FILE *f)
 * Description : 串口发一个字节
 * Input       : int ch, FILE *f
 * Output      : 
* Return      : int ch
 *******************************************************************************/
 int fputc(int ch, FILE *f)
 {
     //USART_SendData(USART1, (u8) ch);
     USART1->DR = (u8) ch;
     
    /* Loop until the end of transmission */
     while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
     {
     }
 
    return ch;
 }
 
/*******************************************************************************
 * Function Name: Delay
 * Description : 延时函数
 * Input       : None
 * Output      : None
 * Return      : None
 *******************************************************************************/
 void Delay(void)
 {
     u32 i;
     for(i=0;i<0x4f0000;i++);
     return;
 }                            

/*******************************************************************************
 * Function Name: GetTemp
 * Description : 根据ADC结果计算温度
 * Input       : u16 advalue
 * Output      : 
* Return      : u16 temp
 *******************************************************************************/
 u16 GetTemp(u16 advalue)
 {
     u32 Vtemp_sensor;
     s32 Current_Temp;
     
//    ADC转换结束以后,读取ADC_DR寄存器中的结果,转换温度值计算公式如下:
 //          V25 - VSENSE
 //  T(℃) = ------------  + 25
 //           Avg_Slope
 //   V25:  温度传感器在25℃时 的输出电压,典型值1.43 V。
 //  VSENSE:温度传感器的当前输出电压,与ADC_DR 寄存器中的结果ADC_ConvertedValue之间的转换关系为: 
//            ADC_ConvertedValue * Vdd
 //  VSENSE = --------------------------
 //            Vdd_convert_value(0xFFF)
 //  Avg_Slope:温度传感器输出电压和温度的关联参数,典型值4.3 mV/℃。
 
    Vtemp_sensor = advalue * 330 / 4096;
     Current_Temp = (s32)(143 - Vtemp_sensor)*1000/34 + 2500; 
    return (s16)Current_Temp;
 }  


/*******************************************************************************
 * Function Name: GetVolt
 * Description : 根据ADC结果计算电压
 * Input       : u16 advalue
 * Output      : 
* Return      : u16 temp
 *******************************************************************************/
 u16 GetVolt(u16 advalue)
 {
     return (u16)(advalue * 330 / 4096);
 } 
                          

/*******************************************************************************
 * Function Name: RCC_Configuration
 * Description : 系统时钟设置
 * Input       : None
 * Output      : None
 * Return      : None
 *******************************************************************************/
 RCC_ClocksTypeDef RCC_ClockFreq;
void RCC_Configuration(void)
{
SystemInit();//源自system_stm32f10x.c文件,只需要调用此函数,则可完成RCC的配置.具体请看2_RCC

/**************************************************
获取RCC的信息,调试用
请参考RCC_ClocksTypeDef结构体的内容,当时钟配置完成后,
里面变量的值就直接反映了器件各个部分的运行频率
***************************************************/
RCC_GetClocksFreq(&RCC_ClockFreq);

/* 这个配置可使外部晶振停振的时候,产生一个NMI中断,不需要用的可屏蔽掉*/
//RCC_ClockSecuritySystemCmd(ENABLE);
}
 

/*******************************************************************************
 * Function Name: GPIO_Configuration
 * Description : GPIO设置
 * Input       : None
 * Output      : None
 * Return      : None
 *******************************************************************************/
 void GPIO_Configuration(void)
 {
     GPIO_InitTypeDef GPIO_InitStructure;
    //USART1_TX
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
     GPIO_Init(GPIOA, &GPIO_InitStructure);
     
    //USART1_RX
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
     GPIO_Init(GPIOA, &GPIO_InitStructure);
     
    //ADC_CH10--> C0
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
     GPIO_Init(GPIOC, &GPIO_InitStructure); 

}
 


/*******************************************************************************
 * Function Name: NVIC_Configuration
 * Description : NVIC设置
 * Input       : None
 * Output      : None
 * Return      : None
 *******************************************************************************/
 void NVIC_Configuration(void)
 {
     NVIC_InitTypeDef NVIC_InitStructure;
 
#ifdef  VECT_TAB_RAM
     // Set the Vector Table base location at 0x20000000
     NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
 #else  /* VECT_TAB_FLASH  */
     // Set the Vector Table base location at 0x08000000
     NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
 #endif
 
    //设置NVIC优先级分组为Group2:0-3抢占式优先级,0-3的响应式优先级
     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
     //串口中断打开
     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);
 }
 

/*******************************************************************************
 * Function Name: USART1_Configuration
 * Description : NUSART1设置
 * Input       : None
 * Output      : None
 * Return      : None
 *******************************************************************************/
 void USART1_Configuration(void)
 {
     USART_InitTypeDef USART_InitStructure;    
     
     USART_InitStructure.USART_BaudRate = 9600;
     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
     USART_InitStructure.USART_StopBits = USART_StopBits_1;
     USART_InitStructure.USART_Parity = USART_Parity_No;
     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
     USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
     USART_Init(USART1, &USART_InitStructure);
     
     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
     
     USART_Cmd(USART1, ENABLE);
 }
 
/*******************************************************************************
 * Function Name: ADC1_Configuration
 * Description : ADC1设置(包括ADC模块配置和自校准)
 * Input       : None
 * Output      : None
 * Return      : None
 *******************************************************************************/
 void ADC1_Configuration(void)
 {
     ADC_InitTypeDef ADC_InitStructure;
 
     ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
     ADC_InitStructure.ADC_ScanConvMode = ENABLE;
     ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  //连续转换开启
     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
     ADC_InitStructure.ADC_NbrOfChannel = 2;     //设置转换序列长度为2
     ADC_Init(ADC1, &ADC_InitStructure);
     
    //ADC内置温度传感器使能(要使用片内温度传感器,切忌要开启它)
     ADC_TempSensorVrefintCmd(ENABLE);
     
    //常规转换序列1:通道10
     ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_13Cycles5);
     //常规转换序列2:通道16(内部温度传感器),采样时间>2.2us,(239cycles)
     ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_239Cycles5);
     
    // Enable ADC1
     ADC_Cmd(ADC1, ENABLE);
     // 开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数)
     ADC_DMACmd(ADC1, ENABLE);
     
    // 下面是ADC自动校准,开机后需执行一次,保证精度
     // Enable ADC1 reset calibaration register 
    ADC_ResetCalibration(ADC1);
     // Check the end of ADC1 reset calibration register
     while(ADC_GetResetCalibrationStatus(ADC1));
 
    // Start ADC1 calibaration
     ADC_StartCalibration(ADC1);
     // Check the end of ADC1 calibration
     while(ADC_GetCalibrationStatus(ADC1));
     // ADC自动校准结束---------------
     
}
 
/*******************************************************************************
 * Function Name: DMA_Configuration
 * Description : DMA设置:从ADC模块自动读转换结果至内存
 * Input       : None
 * Output      : None
 * Return      : None
 *******************************************************************************/
 void DMA_Configuration(void)
 {
     DMA_InitTypeDef DMA_InitStructure;
     
     DMA_DeInit(DMA1_Channel1);
     DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
     DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&AD_Value;
     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
     //BufferSize=2,因为ADC转换序列有2个通道
     //如此设置,使序列1结果放在AD_Value[0],序列2结果放在AD_Value[1]
     DMA_InitStructure.DMA_BufferSize = 2;
     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
     //循环模式开启,Buffer写满后,自动回到初始地址开始传输
     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通道
     DMA_Cmd(DMA1_Channel1, ENABLE);
 }
回复 支持 反对

使用道具 举报

7

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2013-4-19
在线时间
3 小时
 楼主| 发表于 2013-4-22 15:51:00 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
一定要帮帮我啊!!   原子哥
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-4-22 20:43:18 | 显示全部楼层
很忙,等我有时间了再说吧.
建议你先从简单的搞起,新手就应该先单个的东西学会,再去整合.
你现在用到的:串口,ADC,DMA.三个外设.
你单个的弄懂了么?能实验么?
如果单个的都不行,你搞三个无非就是多浪费时间罢了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

4

主题

41

帖子

0

精华

初级会员

Rank: 2

积分
179
金钱
179
注册时间
2012-9-20
在线时间
19 小时
发表于 2015-4-1 23:36:41 | 显示全部楼层
温度采集不准确啊,30度跳动!原子哥有好办法吗?
回复 支持 反对

使用道具 举报

6

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2016-3-7
在线时间
15 小时
发表于 2016-4-3 20:10:50 | 显示全部楼层
eternity86 发表于 2015-4-1 23:36
温度采集不准确啊,30度跳动!原子哥有好办法吗?

是显示跳动还是采集的数据有跳动?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-19 03:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表