STM32学习笔记之ADC--DMA方式

程序功能是把ADC1模块里通道14的输入电压转换后通过USART2发送到PC,在PC机上用串口调试助手观察接收数据:
STM32是12位ADC,测量结果基本还可以!程序用了DMA来传输ADC转换值,调高了读取速度。串口部分用是上一篇串口调试笔记里的代码。
/************************************************************************
     Copyright (c) 2008 wormchen            
     All rights reserved            
文 件 名: main.c             
说    明: 将ADC转换值通过串口发送到PC端         
主要硬件: EMSTM32V1+miniSTMV100(外部8MRC)        
编译环境: MDK3.10             
当前版本: 1.0              
作    者: 陈崇              
完成日期: 2008年3月24日9:08:41          
取代版本: 1.0              
原作  者: 陈崇             
完成日期: 2008年3月24日9:08:46         
************************************************************************/
#include <stm32f10x_lib.h>
#include <stdio.h>

#define ADC1_DR_Address    ((u32)0x4001244C)

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

vu16 ADC_ConvertedValue;

void RCC_Config(void);
void GPIO_Config(void);
void USART_Config(void);
void DMA_Config(void);
void ADC_Config(void);
void Put_String(u8 *p);
void Delay(vu32 nCount);
int main(void)
{
    RCC_Config();
    GPIO_Config();
    USART_Config();
    DMA_Config();
    ADC_Config();
    while(1)
    {
        Delay(0x8FFFF);  
        printf("ADC = %X Volt = %d mv/r/n", ADC_ConvertedValue, ADC_ConvertedValue*3300/4096);
    }
}
/*************************************************
函数: void RCC_Config(void)
功能: 配置系统时钟
参数: 无
返回: 无
**************************************************/
void RCC_Config(void)
{
     ErrorStatus HSEStartUpStatus;//定义外部高速晶体启动状态枚举变量
     RCC_DeInit();//复位RCC外部设备寄存器到默认值
     RCC_HSEConfig(RCC_HSE_ON); //打开外部高速晶振
     HSEStartUpStatus = RCC_WaitForHSEStartUp();//等待外部高速时钟准备好
     if(HSEStartUpStatus == SUCCESS)//外部高速时钟已经准别好
    {
        RCC_HCLKConfig(RCC_SYSCLK_Div1);//配置AHB(HCLK)时钟=SYSCLK
        RCC_PCLK2Config(RCC_HCLK_Div1); //配置APB2(PCLK2)钟=AHB时钟
        RCC_PCLK1Config(RCC_HCLK_Div2);//配置APB1(PCLK1)钟=AHB 1/2时钟
        RCC_ADCCLKConfig(RCC_PCLK2_Div4);//配置ADC时钟=PCLK2 1/4

        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
        //配置PLL时钟 == 外部高速晶体时钟*9
        RCC_ADCCLKConfig(RCC_PCLK2_Div4);//配置ADC时钟= PCLK2/4

        RCC_PLLCmd(ENABLE);//使能PLL时钟
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) //等待PLL时钟就绪
        {
        }
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//配置系统时钟 = PLL时钟

        while(RCC_GetSYSCLKSource() != 0x08) //检查PLL时钟是否作为系统时钟
        {
        }
    }
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA, ENABLE);//使能DMA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
    //使能ADC1,GPIOC时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);
    //打开GPIOD和AFIO时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);//使能串口2时钟
}
/*************************************************
函数: void GPIO_Config(void)
功能: GPIO配置
参数: 无
返回: 无
**************************************************/
void GPIO_Config(void)
{
    //设置RTS(PD.04),Tx(PD.05)为推拉输出模式
    GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO初始化结构体
    GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);//使能GPIO端口映射USART2
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;//选择PIN4 PIN5
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //引脚频率50M
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//引脚设置推拉输出
    GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化GPIOD
    //配置CTS (PD.03),USART2 Rx (PD.06)为浮点输入模式
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    //配置PC4为模拟输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}
/*************************************************
函数: void DMA_Config(void)
功能: DMA配置
参数: 无
返回: 无
**************************************************/
void DMA_Config(void)
{
    DMA_InitTypeDef DMA_InitStructure;//定义DMA初始化结构体
    DMA_DeInit(DMA_Channel1);//复位DMA通道1
    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //定义 DMA通道外设基地址=ADC1_DR_Address
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue; //定义DMA通道存储器地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//指定外设为源地址
    DMA_InitStructure.DMA_BufferSize = 1;//定义DMA缓冲区大小1
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//当前外设寄存器地址不变
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;//当前存储器地址不变
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//定义外设数据宽度16位
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //定义存储器数据宽度16位
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA通道操作模式位环形缓冲模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA通道优先级高
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//禁止DMA通道存储器到存储器传输
    DMA_Init(DMA_Channel1, &DMA_InitStructure);//初始化DMA通道1
    DMA_Cmd(DMA_Channel1, ENABLE); //使能DMA通道1
}
/*************************************************
函数: void ADC_Config(void)
功能: ADC配置
参数: 无
返回: 无
**************************************************/
void ADC_Config(void)
{
    ADC_InitTypeDef ADC_InitStructure;//定义ADC初始化结构体变量
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC1和ADC2工作在独立模式
    ADC_InitStructure.ADC_ScanConvMode = ENABLE; //使能扫描
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//ADC转换工作在连续模式
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//有软件控制转换
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//转换数据右对齐
    ADC_InitStructure.ADC_NbrOfChannel = 1;//转换通道为通道1
    ADC_Init(ADC1, &ADC_InitStructure); //初始化ADC
    ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_28Cycles5);
    //ADC1选择信道14,音序器等级1,采样时间239.5个周期
    ADC_DMACmd(ADC1, ENABLE);//使能ADC1模块DMA
    ADC_Cmd(ADC1, ENABLE);//使能ADC1
    ADC_ResetCalibration(ADC1); //重置ADC1校准寄存器
    while(ADC_GetResetCalibrationStatus(ADC1));//等待ADC1校准重置完成
    ADC_StartCalibration(ADC1);//开始ADC1校准
    while(ADC_GetCalibrationStatus(ADC1));//等待ADC1校准完成
    ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能ADC1软件开始转换
}
/*************************************************
函数: void USART_Config(void)
功能: USART配置
参数: 无
返回: 无
**************************************************/
void USART_Config(void)
{
    USART_InitTypeDef USART_InitStructure; //定义串口初始化结构体
    USART_InitStructure.USART_BaudRate = 115200;//波特率9600
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据
    USART_InitStructure.USART_StopBits = USART_StopBits_1;//1个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No ; //无校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    //禁用RTSCTS硬件流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//使能发送接收
    USART_InitStructure.USART_Clock = USART_Clock_Disable; //串口时钟禁止
    USART_InitStructure.USART_CPOL = USART_CPOL_Low; //时钟下降沿有效
    USART_InitStructure.USART_CPHA = USART_CPHA_2Edge;//数据在第二个时钟沿捕捉
    USART_InitStructure.USART_LastBit = USART_LastBit_Disable;
    //最后数据位的时钟脉冲不输出到SCLK引脚
    USART_Init(USART2, &USART_InitStructure);//初始化串口2
    USART_Cmd(USART2, ENABLE);//串口2使能
}
/*************************************************
函数: void Put_String(void)
功能: 向串口输出字符串
参数: 无
返回: 无
**************************************************/
void Put_String(u8 *p)
{
    while(*p)
    {
        USART_SendData(USART2, *p++);
        while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
        {
        }
    }
}
/*****************************************************
函数: void Delay(vu32 nCount)
功能: 延时指定时间
参数: vu32 nCount 延时指定时间
返回: 无
******************************************************/
void Delay(vu32 nCount)
{
    for(; nCount != 0; nCount--);
}
/*****************************************************
函数:PUTCHAR_PROTOTYPE
功能: 重定向C库printf函数
参数: 无
返回: 无
*****************************************************/
PUTCHAR_PROTOTYPE
{
    USART_SendData(USART2, (u8) ch);//发送一字节数据
    while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
    {
    }//等待发送完成
    return ch;
}

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

 

void ADC_Configuration(void)
{
    ADC_InitTypeDef ADC_InitStructure;

    /* ADC1 Configuration ------------------------------------------------------*/
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    ADC_Init(ADC1, &ADC_InitStructure);

    /* ADC1 regular channel14 configuration */
    ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_13Cycles5);

    /* Enable ADC1 */
    ADC_Cmd(ADC1, ENABLE);

    /* Start ADC1 Software Conversion */
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

ADCVal = ADC_GetConversionValue(ADC1);   //查询方式


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值