智能车制作
标题:
STM32F4演示例程之DMA模式下ADC转换
[打印本页]
作者:
demon
时间:
2012-5-20 23:46
标题:
STM32F4演示例程之DMA模式下ADC转换
[attach]24763[/attach][attach]24761[/attach]
/************************************
标题:ADC
软件平台:IAR for ARM6.21
硬件平台:stm32f4-discovery
主频:168M
author:小船
data:2012-02-16
*************************************/
#include <stm32f4xx.h>
#include "MyDebugger.h"
__IO uint16_t ADCConvertedVault[10000];
char TXbuffer[] = "PC1输入电压为:x.xxxV\n\r";
void ADC_IO_Config(void);
void ADC_DMA_Config(void);
void ADC_Common_Config(void);
void ADC3_IN11_Config(void);
void ADC2_IN11_Config(void);
void ADC1_IN11_Config(void);
void main ()
{
SCB->AIRCR = 0x05AF0000 | 0x400; //中断优先级分组 抢占:响应=3:1
ADC_IO_Config();
ADC_DMA_Config();
ADC_Common_Config();
ADC3_IN11_Config();
ADC2_IN11_Config();
ADC1_IN11_Config();
ADC3->CR2 |= (1<<0); //开启ADC3转换
ADC2->CR2 |= (1<<0); //开启ADC2转换
ADC1->CR2 |= (1<<0); //开启ADC1转换
ADC1->CR2 |= (1<<30); //触发转换开始
MyDebugger_Init();
while(1)
{
};
}
void ADC_Common_Config(void)
{
RCC->APB2ENR |= ( (1<<8) | (1<<9) | (1<<10) ); //使能ADC时钟
ADC->CCR &= 0x00000000;
/*
DMA模式1
最后一次ADC转换后发出dma请求
交错模式
2次采样之间的延迟5个周期
*/
ADC->CCR |= ( 0x00004000 | (1<<13) | 0x00000017 | 0x00000000);
}
/***ADC1设置***/
void ADC1_IN11_Config(void)
{
ADC1->SQR1 = 0x00000000;//转换一个通道
ADC1->SQR3 = 0x0000000B;//第一个通道为ADC1_in11
ADC1->CR1 &= 0x00000000;
ADC1->CR2 &= 0x00000000;
ADC1->CR2 |= (1<<1); //连续转换
ADC1->CR2 |= (1<<9); //最后一次ADC转换后发出dma请求
ADC1->CR2 |= (1<<8);//ADC dma发送模式使能
}
/***ADC2设置***/
void ADC2_IN11_Config(void)
{
ADC2->SQR1 = 0x00000000;//转换一个通道
ADC2->SQR3 = 0x0000000B;//第一个通道为ADC1_in11
ADC2->CR1 &= 0x00000000;
ADC2->CR2 &= 0x00000000;
ADC2->CR2 |= (1<<1); //连续转换
ADC2->CR2 |= (1<<9); //最后一次ADC转换后发出dma请求
}
/***ADC3设置***/
void ADC3_IN11_Config(void)
{
ADC3->SQR1 = 0x00000000;//转换一个通道
ADC3->SQR3 = 0x0000000B;//第一个通道为ADC3_in11
ADC3->CR1 &= 0x00000000;
ADC3->CR2 &= 0x00000000;
ADC3->CR2 |= (1<<1); //连续转换
ADC3->CR2 |= (1<<9); //最后一次ADC转换后发出dma请求
}
/***GPIO设置***/
void ADC_IO_Config(void)
{
RCC->AHB1ENR |= (1<<2); //打开GPIOC时钟
GPIOC->MODER &= 0xfffffff3;//PC1模拟模式
GPIOC->MODER |= 0x0000000C;
GPIOC->PUPDR &= 0xfffffff3;//无上拉无下拉
}
/***DMA设置***/
void ADC_DMA_Config(void)
{
RCC->AHB1ENR |= (1<<22); //使能DMA2时钟
ADC3->CR2 &= ~(1<<8);//ADC3 dma发送模式除能
DMA2_Stream0->CR &= 0xFFFFFFFE; //除能DMA2_Stream0
while(DMA2_Stream0->CR & 0x00000001);//确保DMA可以被设置
DMA2->LIFCR |= 0x0000003D;//传送前清空DMA2_Stream0所有中断标志
DMA2_Stream0->PAR = (uint32_t)&ADC->CDR;//设置外设地址
DMA2_Stream0->M0AR = (uint32_t)ADCConvertedVault; //设置内存地址
DMA2_Stream0->CR |= 0x0002800;//16位数据
DMA2_Stream0->NDTR = 10000; //设置dma传输数据的数量
/*
设置dma2通道0,即ADC1
优先级Medium
传输方向外设到内存
内存递增模式
循环模式
传输完成中断
*/
DMA2_Stream0->CR |= ( 0x00000000 | 0x00010000 | 0x0
| (1<<10) | (1<<8) | (1<<4) );
NVIC->IP[56] = 0xB0;
NVIC->ISER[1] |= (1<<(56-32));
DMA2_Stream0->CR |= 1; //DMA2数据流0使能
}
void DMA2_Stream0_IRQHandler (void)
{
uint32_t i;
uint32_t Average;
if(DMA2->LISR & 0x00000010)
{
DMA2->LIFCR |= 0x00000010;
for(i = 0; i < 10000; i++) // 对一万个数据取平均值
Average += ADCConvertedVault
;
Average *= 3;
Average /= 40960;
TXbuffer[14] = ( Average / 1000 ) % 10 + 0x30;//转换成ASCII码
TXbuffer[16] = ( Average / 100 ) % 10 + 0x30;
TXbuffer[17] = ( Average / 10 ) % 10 + 0x30;
TXbuffer[18] = Average % 10 + 0x30;
MyDebugger_Message(TXbuffer, sizeof(TXbuffer)/sizeof(char));
}
}
作者:
0726silence
时间:
2012-5-21 12:51
沙发,嘿嘿顶,正打算学32 的
作者:
星斗520
时间:
2012-5-22 13:19
顶一个
作者:
鹄虫2
时间:
2012-8-6 14:13
楼主调试成功没?
作者:
kdtxwx
时间:
2012-9-9 11:00
可以说说DMA普通模式下,DMA关闭后的再次重启吗,我做了好多试验不能成功
欢迎光临 智能车制作 (http://dns.znczz.com/)
Powered by Discuz! X3.2