当前位置:
文档之家› STM32+DMA+UART+ADC+内部温度传感器
STM32+DMA+UART+ADC+内部温度传感器
{ 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--); }
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; 描 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //软件启动转换 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 对齐 ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); //1 个通道
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);//可以不需要下面的那种操作,很简单的就可将数据从串口 输出!! /* a = adc/1000; b = (adc - a*1000)/100; c = (adc - a*1000 - b*100)/10; d = adc - a*1000 - b*100 - c*10;
USART1_Puts("Temprature is:"); USART1_Putc(a+'0'); USART1_Putc(b+'0'); USART1_Putc(c+'0'); USART1_Putc(d+'0'); USART1_Puts("C \r\n"); */ delay(2234567); } } }
/************************************************************** ** 函数名:DigitFilter ** 功能:软件滤波 ** 注意事项:取 NO 的 2/5 作为头尾忽略值,注意 N 要大于 5,否则不会去头尾 ***************************************************************/ 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])
//数据右
/* 配置通道 16 的采样速度,这里因为是测温,不需要很快,配置为最慢*/ ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_23TempSensorVrefintCmd(ENABLE);
STM32+DMA+UART+ADC+内部温度传感器
说明: 说明:沧海一声笑原创。 沧海一声笑原创。 邮箱: 邮箱:minios@
由于文件很多, 由于文件很多,只列举几个关键的文件。 只列举几个关键的文件。 ADC.c #include "STM32Lib\\stm32f10x.h" u16 ADCCov[16]; volatile bool ADC_Ok=FALSE; static DMA_InitTypeDef DMA_InitStructure; static ADC_InitTypeDef ADC_InitStructure;
//设定外设数据宽度为 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); 道 1 传输完成中断 //DMA 通
//DMA 的配置 void DMA_Configuration(void) { /* 允许 DMA1 */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* DMA 通道 1*/ 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; //外设地址不递增(不变) DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不增加 //内存地址不递增(不变) DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 内存地址增加 // //每次 DMA16 个数据 //片内外设 //获取
} main.c /************************************************************ **实验名称:ADC TEMP **功能:使用片内的温度传感器测量温度,并通过串口输出温度值 *************************************************************/ #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; /* Loop until the end of transmission */ while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) { } return ch; } int main(void) { u16 adc; u8 a,b,c,d; ChipHalInit(); //片内硬件初始化
/* Enable DMA1 channel1 */ 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 /* Includes ------------------------------------------------------------------*/ #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; }