作者: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--); } |
|