2023年12月18日发(作者:)
#include
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "exti.h"
#include "wdg.h"
#include "timer.h"
#include "lcd.h"
#include "rtc.h"
#include "wkup.h"
#include "adc.h"
#include "dma.h"
//Mini STM32开发板范例代码13
//ADC 实验
//正点原子@ALIENTEK
//技术论坛:
#define N 50 //每个通道采样50次
#define M 2 //采样通道个数
u16 adcx;
u16 AD_Value[N][M];
u16 AD_After_Filter[M];
//u8 Send_buf_Ch0[3];
//u8 Send_buf_Ch1[3];
//求采样值的平均值
void filter(void)
{
int i,sum = 0;
u8 count;
for(i=0;i { for ( count=0;count { sum += AD_Value[count][i]; } AD_After_Filter[i]=sum/N; sum=0; } } void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr) { u32 DR_Base; //做缓冲用,不知道为什么.非要不可 RCC->AHBENR|=1<<0;//开启DMA1时钟 __nop(); //等待 DMA1 时钟稳定 __nop(); //经测试最少 2 个 nop __nop(); DR_Base=cpar; DMA_CHx->CPAR=DR_Base; //DMA1 外设地址 DMA_CHx->CMAR=(u32)cmar; //DMA1,存储器地址 DMA1_MEM_LEN=cndtr; //保存DMA传输数据量 DMA_CHx->CNDTR=cndtr; //DMA1,传输数据量 DMA_CHx->CCR=0X00000000;//复位 DMA_CHx->CCR|=0<<4; //从外设读 DMA_CHx->CCR|=1<<5; //循环模式 DMA_CHx->CCR|=0<<6; //外设地址非增量模式 DMA_CHx->CCR|=1<<7; //存储器增量模式 DMA_CHx->CCR|=1<<8; //外设数据宽度为16位 DMA_CHx->CCR|=1<<10; //存储器数据宽度16位 DMA_CHx->CCR|=2<<12; //中等优先级 //最高优先级 DMA_CHx->CCR|0<<14; //非存储器到存储器模式 } //开启一次DMA传输 void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx) { DMA_CHx->CCR&=~(1<<0); //关闭DMA传输 DMA_CHx->CNDTR=DMA1_MEM_LEN; //DMA1,传输数据量 DMA_CHx->CCR|=1<<0; //开启DMA传输 } void Adc_Init(void) { RCC->APB2ENR|=1<<2|1<<9; //开启PA时钟 ,以及ADC时钟 RCC->APB2RSTR|=1<<9;//复位adc1 RCC->APB2RSTR&=~(1<<9);//复位完成,需要将复位关闭,否则将一直保持复位 RCC->CFGR|=1<<15;//设置为6分频给ADC转换时钟 //读取ADC0的值 GPIOA->CRL&=0XFFFFFF00;//PA0 1 anolog输入//设置PA0口为模拟上拉输入,PA1口模拟上拉输入 ADC1->CR2|=1<<20;//允许软件外部触发 ADC1->CR2|=1<<19|1<<18|1<<17;//选择为软件触发 //ADC1->SMPR1=0X1c0000; //为了提高精度,1通道以及16通道 ADC1->SMPR2=0X3f; //通道0,1采样间隔为最大 //ADC1->CR2|=1<<23;//开启内部温度传感器 ADC1->CR2|=1<<0;//开启转换 ADC1->CR1|=1<<8;//开启扫描模式 ADC1->CR2|=1<<3;//初始化复位校准寄存器 ADC1->CR2|=1<<8;//允许dma访问 while(ADC1->CR2&1<<3);//等待校准结束 ADC1->CR2|=1<<2;//开始校准 while(ADC1->CR2&1<<2); //等待校准结束 //ADC1->CR1|=1<<5;//允许中断 ADC1->CR2|=1<<1;//设置为连续模式 ADC1->SQR1|=1<<20;//开启三个转换 ADC1->CR2|=1<<22;//开始规则转换 // MY_NVIC_Init(2,1,ADC1_2_IRQChannel,2);//设置中断优先级 ADC1->SQR3=0|1<<5; //这个表明在第一规则通道当中,进行转换的将是16通道的数据 //通道0,1以及通道16转换 } int main(void) { // u16 adcx; u8 t; //float pro=0; int temp0,temp1; Stm32_Clock_Init(9);//系统时钟设置 delay_init(72); //延时初始化 uart_init(72,9600); //串口1初始化 Adc_Init(); MYDMA_Config(DMA1_Channel1,(u32)&ADC1->DR,(u32)AD_Value,N*M); //DMA1通道1初始化配置 MYDMA_Enable(DMA1_Channel1); //开启DMA通道1 // ADC1->CR2|=1<<0; //开启AD转换器 // ADC1->CR2|=1<<22; //开始转换规则组 // while(!(ADC1->SR&1<<1)); //等待转换结束 adcx=ADC1->DR; //0x20000028 0x4001244C while(1) { if(DMA1->ISR&(1<<1))//等待通道1传输完成 { DMA1->IFCR|=1<<1; //清除传输完成标志 } filter(); //滤波求平均值 temp0=AD_After_Filter[0]*330/4096; temp1=AD_After_Filter[1]*330/4096; //通道0和1采样电压值放大100倍 USART_RX_BUF[0]=temp0/100+'0'; //放入数组,准备发送到串口 USART_RX_BUF[1]='.'; USART_RX_BUF[2]=temp0/10%10+'0'; USART_RX_BUF[3]=temp0%10+'0'; USART_RX_BUF[4]='V'; } USART_RX_BUF[5]=temp1/100+'0'; USART_RX_BUF[6]='.'; USART_RX_BUF[7]=temp1/10%10+'0'; USART_RX_BUF[8]=temp1%10+'0'; USART_RX_BUF[9]='V'; printf("nADC采样电压:n"); for(t=0;t<10;t++) { USART1->DR=USART_RX_BUF[t]; while((USART1->SR&0X40)==0); } printf("nn"); delay_ms(5); }


发布评论