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

}