新手上路
- 积分
- 38
- 金钱
- 38
- 注册时间
- 2015-3-19
- 在线时间
- 0 小时
|
弄了一晚上的ADC1多路采集+DMA传输终于成功啦!
论坛上DMA许多都是非循环模式的,个人觉得比较麻烦,因此采用循环模式
ADC和DMA 配置代码如下
#include "adc.h"
#include "delay.h"
vu16 adc_dat[3]={0,0,0};
void DMA_Init(void);
void ADC1_Init(void)
{
DMA_Init();
RCC->APB2ENR|=1<<2; //使能PORTA口时钟
GPIOA->CRL &=0xff00ff0f;//PA.1 PA.4 PA.5 模拟输
RCC->APB2ENR|=1<<9; //ADC1时钟使能
RCC->APB2RSTR|=1<<9; //ADC1复位
RCC->APB2RSTR&=~(1<<9);//复位结束
ADC1->CR1|=(1<<8); //扫描模式
ADC1->CR2|=1<<1; //连续转换模式
ADC1->CR2&=~(7<<17);
ADC1->CR2|=7<<17; //软件控制转换
ADC1->CR2|=1<<20; //使用用外部触发(SWSTART)
ADC1->CR2&=~(1<<11); //右对齐
//设置通道1的采样时间
ADC1->SMPR2&=~(7<<3); //通道1采样时间清空
ADC1->SMPR2|=7<<3; //通道1 239.5周期,提高采样时间可以提高精确度
ADC1->SQR1&=~(0XF<<20);
ADC1->SQR1|=1<<21; //3个转换序列
ADC1->SQR3&=0XFFFFE000;//规则序列1 通道ch
ADC1->SQR3|=1;
ADC1->SQR3 |=4<<5;//IN4
ADC1->SQR3 |=5<<10; //IN5
ADC1->CR2 |=1<<8;//DMA模式
ADC1->CR2|=1<<0; //开启AD转换器
ADC1->CR2|=1<<3; //使能复位校准
while(ADC1->CR2&1<<3); //等待校准结束
ADC1->CR2|=1<<2; //开启AD校准
while(ADC1->CR2&1<<2); //等待校准结束
ADC1->CR2|=1<<22; //启动规则转换通道
}
void DMA_Init(void)
{
RCC->AHBENR |=1;//open DMA1 clock
delay_ms(5);
DMA1_Channel1->CNDTR =3;//传输数据数量
DMA1_Channel1->CPAR = 0X4001244C;//外设地址
DMA1_Channel1->CMAR =(u32)&adc_dat;//存储器地址
DMA1_Channel1->CCR =0x00000000;//复位
DMA1_Channel1->CCR|=0<<4; //从外设器件读数据
DMA1_Channel1->CCR|=1<<5; //循环模式
DMA1_Channel1->CCR|=0<<6; //外设地址非增量模式
DMA1_Channel1->CCR|=1<<7; //存储器增量模式
DMA1_Channel1->CCR|=1<<8; //外设数据宽度为16位
DMA1_Channel1->CCR|=1<<10; //存储器数据宽度16位
DMA1_Channel1->CCR|=1<<13; //高优先级
DMA1_Channel1->CCR|=1<<0; //开启DMA传输
}
u16 Get_ADC(u8 ch)
{
if(ch==1) return adc_dat[0];
else if(ch==4) return adc_dat[1];
else if(ch==5) return adc_dat[2];
else return 0;
}
然后main.c 中
while(1)
{
//可以加条件,再触发转换
ADC1->CR2|=1<<22; //启动规则转换通道
}
|
|