天天看點

STM32+DMA+UART+ADC+内部溫度傳感器

作者:number007cool

轉自:http://blog.chinaunix.net/uid-21658993-id-1820027.html

由于檔案很多,隻列舉幾個關鍵的檔案。 ADC.c

#include "STM32Lib\\stm32f10x.h"

u16 ADCCov[16];

volatile bool ADC_Ok=FALSE;

static DMA_InitTypeDef DMA_InitStructure;

static ADC_InitTypeDef ADC_InitStructure;

//ADC,内部溫度傳感器配置

void ADCTEMP_Configuration(void)

{

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);

 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;      //獨立模式

 ADC_InitStructure.ADC_ScanConvMode = DISABLE;       //單通道模式

 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;      //連續掃描

 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);

 ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_239Cycles5);

 ADC_TempSensorVrefintCmd(ENABLE);

 ADC_DMACmd(ADC1, ENABLE);

 ADC_Cmd(ADC1, ENABLE);

 ADC_ResetCalibration(ADC1);

 while(ADC_GetResetCalibrationStatus(ADC1));

 ADC_StartCalibration(ADC1);

 while(ADC_GetCalibrationStatus(ADC1));

 ADC_SoftwareStartConvCmd(ADC1, ENABLE);

}

//DMA的配置

void DMA_Configuration(void)

{

 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

 DMA_DeInit(DMA1_Channel1);

 //指定DMA外設基位址

 DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)( &(ADC1->DR));  //ADC1資料寄存器

 //設定DMA記憶體基位址

 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADCCov;     //擷取ADC的數組

 //外設作為資料傳輸的來源

 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;     //片内外設作源頭

 //指定DMA通道的DMA緩存大小

 DMA_InitStructure.DMA_BufferSize = 16;        //每次DMA16個資料

 //外設位址不遞增(不變)

 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外設位址不增加

 //記憶體位址不遞增(不變)

 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;    //記憶體位址增加

 //設定外設資料寬度為16位

 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //半字

 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;   //半字

 //設定DMA的工作模式普通模式,還有一種是循環模式

 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;        //普通模式

 //設定DMA通道的軟體優先級

 DMA_InitStructure.DMA_Priority = DMA_Priority_High;       //高優先級

 //使能DMA記憶體到記憶體的傳輸,此處沒有記憶體到記憶體的傳輸

 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;        //非記憶體到記憶體

 DMA_Init(DMA1_Channel1, &DMA_InitStructure);

 DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);        //DMA通道1傳輸完成中斷

 DMA_Cmd(DMA1_Channel1, ENABLE);

}

//重新允許DMA,

void DMAReConfig(void)

{

 DMA_DeInit(DMA1_Channel1);

 DMA_Init(DMA1_Channel1, &DMA_InitStructure);

 DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);

 DMA_Cmd(DMA1_Channel1, ENABLE);

}

stm32f10x_it.c

#include "STM32Lib\\stm32f10x.h"

#include "hal.h"

extern volatile bool ADC_Ok;

void DMA1_Channel1_IRQHandler(void)

{

 if(DMA_GetITStatus(DMA1_IT_TC1))//通道1傳輸完成中斷

  {

  DMA_ClearITPendingBit(DMA1_IT_GL1); //清除全部中斷标志

  ADC_Ok=TRUE;

 }

}

main.c

#include "STM32Lib\\stm32f10x.h"

#include "hal.h"

#include "stdio.h"

extern volatile bool ADC_Ok;

extern u16 ADCCov[16];

extern void DMAReConfig(void);

void delay(u32 z);

u16 DigitFilter(u16* buf,u8 no);

int fputc(int ch, FILE *f) 

 //USART_SendData(USART1, (u8) ch); 

 USART1->DR = (u8) ch; 

 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) 

 { 

 } 

 return ch; 

}

int main(void)

{

 u16 adc;

 u8 a,b,c,d;

 ChipHalInit();   //片内硬體初始化

 ChipOutHalInit();  //片外硬體初始化

 for(;;)

 {

  if(ADC_Ok==TRUE)

  {

   ADC_Ok=FALSE;

   adc=DigitFilter(ADCCov,16); //濾波,隻要資料的中間一段

   DMAReConfig();//重新啟動DMA

   adc=(1.42 - adc*3.3/4096)*1000/4.35 + 25;//轉換為溫度值,實際應用中,可考慮用毫伏為機關,避免浮點運算

   printf("T: %d C\r\n",adc);//可以不需要下面的那種操作,很簡單的就可将資料從序列槽輸出!!

   delay(2234567);

  }

 }

}

u16 DigitFilter(u16* buf,u8 no)

{

 u8 i,j;

 u16 tmp;

 u8 cut_no=0;

 //排序,将buf[0]到buf[no-1]從大到小排列

 for(i=0;i<no;i++)

 {

  for(j=0;j<no-i-1;j++)

  { 

   if(buf[j]>buf[j+1])

   { 

   tmp=buf[j];

   buf[j]=buf[j+1];

   buf[j+1]=tmp;

   }

  }

 }

 if(no>5)//no為整形,此處是将no的前2/5丢掉

 {

  cut_no=no/5;

 }

 //平均

 tmp=0;

 for(i=cut_no;i<no-cut_no;i++) //隻取中間n-2*cut_no個求平均

  tmp+=buf[i];

 return(tmp/(no-2*cut_no));

}

void delay(u32 z)

{

while(z--);

}

STM32+DMA+UART+ADC+内部溫度傳感器
檔案: 6_ADC_TEMP.rar
大小: 3364KB
下載下傳: 下載下傳

繼續閱讀