历史上的今天
今天是:2024年09月25日(星期三)
2019年09月25日 | stm32使用DMA传输9路ADC使用中断处理数据
2019-09-25 来源:eefocus
使用中断方式的好处就是在其它地方不会调用到DMA传输BUF。如果不小心调用或修改,可能会死机。具体原因没有深究。
注意中断函数是否和.s文件里面一致,否则也会死机。
根据需求去修改中断函数内容。
dma_adc.h
#ifndef _DMA_ADC_
#define _DMA_ADC_
#include "sys.h"
#define ADC1_DR_Address ((u32)0x40012400+0X4C)
extern u16 ADC_buf[10]; //DMA传输BUF
extern u32 ADC_BUF[10]; //滤波后保存BUF
extern u8 ADC_BUF_flag; //滤波后完成标志
void ADC1_DMA_init(void);
#endif
dma_adc.c
#include "dma_adc.h"
#include "serial.h"
#include "nrf_info.h"
u16 ADC_buf[10];
u32 ADC_BUF[10];
u8 ADC_BUF_flag=0;
void ADC1_DMA_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; //通道引脚
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0; //通道引脚
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
GPIO_Init(GPIOB,&GPIO_InitStructure);
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
DMA_DeInit(DMA1_Channel1);
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* 配置DMA中断源*/
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_InitStructure.DMA_PeripheralBaseAddr=ADC1_DR_Address; //ADC数据寄存器地址
DMA_InitStructure.DMA_MemoryBaseAddr=(u32)ADC_buf; //将ADC1_DR_Address数据转移到ADC_buf
DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC; //数据传输方向,外设作为数据源
DMA_InitStructure.DMA_BufferSize=9; //传输个数据
DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址固定
DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord; //表示每个传输的的数据大小
DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode=DMA_Mode_Circular; //循环传输
DMA_InitStructure.DMA_Priority=DMA_Priority_High; //DMA通道优先级
DMA_InitStructure.DMA_M2M=DMA_M2M_Disable; //禁止内存到内存传输
DMA_Init(DMA1_Channel1,&DMA_InitStructure);
DMA_Cmd(DMA1_Channel1,ENABLE); //使能
DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE); //配置DMA发送完成后产生中断
ADC_InitStructure.ADC_Mode=ADC_Mode_Independent; //独立模式
ADC_InitStructure.ADC_ScanConvMode=ENABLE; //扫描模式,用于多通道采集
ADC_InitStructure.ADC_ContinuousConvMode=ENABLE; //开启连续转换
ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//b不使用外部触发转换
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//采集数据右对齐
ADC_InitStructure.ADC_NbrOfChannel=9; //要转换的个数
ADC_Init(ADC1,&ADC_InitStructure);
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //6分频,12HZ
//扫描顺序,55.5每个周期
ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3,ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_3,4,ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_4,5,ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_5,6,ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_6,7,ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_7,8,ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_8,9,ADC_SampleTime_55Cycles5);
ADC_DMACmd(ADC1,ENABLE); //向DMA发出请求
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1); //复位矫正寄存器
while(ADC_GetResetCalibrationStatus(ADC1)); //等待矫正完成
ADC_StartCalibration(ADC1); //ADC矫正
while(ADC_GetCalibrationStatus(ADC1)); //等待矫正完毕
ADC_SoftwareStartConvCmd(ADC1,ENABLE); //软件触发ADC转换
}
static u8 count=0;
extern "C" void DMA1_Channel1_IRQHandler(void) //DMA中断传输,并且处理数据。
{
if(ADC_BUF_flag==0)
{
if(count==0)
{
//AD清零
for(int i=0;i<9;i++)
{
ADC_BUF[i]=0;
}
}
for(int j=0;j<9;j++)
{
ADC_BUF[j]+=ADC_buf[j];
}
count++;
if(count==30)
{
//取平均滤波
for(int i=0;i<9;i++)
{
ADC_BUF[i]/=count;
}
//---------------------------------------拿到滤波值后------------
nrf_info.ch1=((ADC_BUF[0]*256)/4096);
nrf_info.ch2=((ADC_BUF[1]*256)/4096);
nrf_info.ch3=((ADC_BUF[2]*256)/4096);
nrf_info.ch4=((ADC_BUF[3]*256)/4096);
nrf_info.ch5=((ADC_BUF[4]*256)/4096);
nrf_info.ch6=((ADC_BUF[5]*256)/4096);
nrf_info.ch7=((ADC_BUF[6]*256)/4096);
nrf_info.ch8=((ADC_BUF[7]*256)/4096);
//---------------------------------------发送数据-----------------
if(nrf_info.send_mes())
{
//printf("send OKrn");
PCout(13)=~ PCout(13);
}
else
{
PCout(13)=1;
//printf("send ERRORrn");
}
count=0;
ADC_BUF_flag=1;
}
}
// printf("我进中断了rn");
DMA_ClearITPendingBit(DMA1_IT_TC1);
}
史海拾趣
|
随着第三代移动通信网络技术的发展,移动终端功能的增强和移动业务应用内容的丰富,各种无线应用将极大地丰富人们的日常工作和生活。 近年来,从短信到彩信、彩e、彩铃、手机游戏等,移动增值业务的种类日益丰富。但总体来看,当前移动通信网络提 ...… 查看全部问答> |
|
DDS 概要 1971年,美国学者J.Tierney等人撰写的“A DIGITAL Frequency Synthesizer”-文首次提出了以全数字技术,从相位概念出发直接合成所需波形的一种新给 成原理。限于当时的技术和器件产,它的性牟指标尚不能与已有的技术盯比,故未受到重视。 ...… 查看全部问答> |
|
INtime实时操作系统(RTOS) For Microsoft Windows XP Microsoft Windows XP Embedded Microsoft Windows XP Embedded with Service Pack 1 引言 人们正在越来越多地选择 Microsoft Windows XP 和 Windows XP Embedded 操作系统来运行需要 ...… 查看全部问答> |
|
放大器被用于许多不同的应用中,它们可以被用做高速模数转换器的输入缓冲器、多个视频负载的驱动器和测试仪器应用中的高速脉冲信号放大器等。目前,市场上的大多数高速(>50MHz)放大器的使用都非常方便,但是在适当的情况下,它们会变成非常稳定的振 ...… 查看全部问答> |
|
职位类别:嵌入式应用开发工程师 工作地点:北京 朝阳区 职位月薪:面议 工作性质:全职 招聘人数:4人,限男性 邮箱:topzeal2008@sina.com 职位描述: 1、应用开发、测试及文档编写 2、相关工具的开发及维护 应聘要求: 1、学历不限 ...… 查看全部问答> |




