Stm32标准库函数2——多通道ADC & DMA

 

#include "stm32f10x.h"    //在该头文件中默认定义系统时钟为72M
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "adc.h"
#include "DMA.h"

//串口:A9 A10,波特率115200;AD为A0-A4

//u16 AdcBuff[SIZE];
extern u8 uartFlag;
int main(void)
{        
       u32 i;
//    float temp;
    delay_init();             //延时函数初始化      
    NVIC_Configuration();      //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    DMA_NVIC_Configuration();
    uart_init(115200);         //串口初始化为9600
    Adc_Init();                  //ADC初始化
    DMA_Configuration();//必须重新配置
     while(1)
    {
      if(uartFlag!=0){
        ADC_Cmd(ADC1, ENABLE);    
        delay_ms(1000);    
        for(i=0;i<SIZE;i++)
            Show_u16(AD_Value[i]);
//        USART1_SendData(0X0D);     //换行
//        USART1_SendData(0X0A);     //回车    
        uartFlag=0;    
      }
      //delay_ms(1);
    }    
}

#include "stm32f10x.h"
#include "DMA.h"
#include "usart.h"
#include "delay.h"

u16 AD_Value[SIZE]={0};

/*************
    配置DMA
*************/
void DMA_Configuration(void)
{

    DMA_InitTypeDef DMA_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输
                                                  
    DMA_DeInit(DMA1_Channel1);   //将DMA//的通道1//寄存器重设为缺省//值
    DMA_InitStructure.DMA_PeripheralBaseAddr =  (u32)&ADC1->DR ;  //DMA外设ADC基地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&AD_Value;  //DMA内存基地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //内存作为数据传输的目的地
    DMA_InitStructure.DMA_BufferSize = SIZE;  //DMA通道的DMA缓存的大小
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //数据宽度为16位
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  //工作在循环缓存模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级  
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道
    DMA_Cmd(DMA1_Channel1, ENABLE);
    DMA_ClearITPendingBit(DMA1_IT_GL1);                   //清除DMA1全局中断标志位
    DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);    
    //使能DMA1的存储完成中断    


}
/*******************************
功能:配置嵌套中断向量控制器NVIC
*******************************/
void DMA_NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    
    /* DMA中断优先级配置 */
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn ;   //选择DMA1中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;   //
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能
    NVIC_Init(&NVIC_InitStructure);


}
/******************************
    DAM1中断服务函数
*******************************/
void DMA1_Channel1_IRQHandler(void)
{
     if(DMA_GetITStatus(DMA1_IT_TC1) != RESET )              //DMA是否中断
    {
        ADC_Cmd(ADC1, DISABLE);    //暂停ADC    
        DMA_ClearITPendingBit(DMA1_IT_TC1);                   //清除DMA完成中断标志位
    }
    DMA_ClearITPendingBit(DMA1_IT_GL1);                       //清除DMA中断全局标志位
}

#include "adc.h"
 #include "delay.h"

                                                                    
void  Adc_Init(void)
{     
    ADC_InitTypeDef ADC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1    , ENABLE );      //使能ADC1通道时钟
 

    RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

    //PA1 作为模拟通道输入引脚                         
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1|GPIO_Pin_2| GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //模拟输入引脚
    GPIO_Init(GPIOA, &GPIO_InitStructure);    

    ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值

    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                 //ADC1和ADC2独立工作模式
//    ADC_InitStructure.ADC_ScanConvMode = DISABLE;                         //ADC设置为单通道模式
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;                        
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;                  //设置为连续转换模式
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//由软件控制开始转换
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                //AD输出数值为右端对齐方式
    ADC_InitStructure.ADC_NbrOfChannel = 4;                             //指定要进行AD转换的信道数量
    ADC_Init(ADC1, &ADC_InitStructure);                                 //用上面的参数初始化ADC1

    ADC_RegularChannelConfig(ADC1, ADC_Channel_0,  1, ADC_SampleTime_239Cycles5); //ADC_SampleTime_239Cycles5=239.5个AD时钟周期。
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1,  2, ADC_SampleTime_239Cycles5);  //AD最小转换时间不能小于1.17us(STM32F103),12M Hz是最小为ADC_SampleTime_13Cycles5
    ADC_RegularChannelConfig(ADC1, ADC_Channel_2,  3, ADC_SampleTime_239Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_3,  4, ADC_SampleTime_239Cycles5);
 
    ADC_DMACmd(ADC1, ENABLE);//使能ADC1的DMA                                                                  //采样时间为55.5个周期
    ADC_Cmd(ADC1, ENABLE);                                              //使能ADC1
    ADC_ResetCalibration(ADC1);                                          //重置ADC1校准寄存器
    while(ADC_GetResetCalibrationStatus(ADC1));                          //得到重置校准寄存器状态
    ADC_StartCalibration(ADC1);                                          //开始校准ADC1
    while(ADC_GetCalibrationStatus(ADC1));                              //得到校准寄存器状态
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);                              //使能ADC1由软件控制开始转换

}                  
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)   
{
      //设置指定ADC的规则组通道,一个序列,采样时间
    ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_1Cycles5 );    //ADC1,ADC通道,采样时间为28.5周期                      
 
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);        //使能指定的ADC1的软件转换启动功能    
    
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束

    return ADC_GetConversionValue(ADC1);    //返回最近一次ADC1规则组的转换结果
}

u16 Get_Adc_Average(u8 ch,u8 times)
{
    u32 temp_val=0;
    u8 t;
    for(t=0;t<times;t++)
    {
        temp_val+=Get_Adc(ch);
//        delay_ms(5);
    }
    return temp_val/times;
}     

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fengyuzhe13

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值