查看: 1403|回复: 0

【青风带你学stm32f051系列教程】第10课 ADC采样/DMA通道

[复制链接]

该用户从未签到

发表于 2013-1-19 00:09:37 | 显示全部楼层 |阅读模式
分享到:
第10 课   ADC采样/DMA通道
模数转换器 (ADC) 外设用于将连续的模拟电压转换成离散的数字量。Stm32f051包含一个分辨率为12位的ADC模块,同时具有19个ADC通道,其中16个外部采样通道和3个内部信号源。ADC采样通道源和ADC管脚如下表所示:

本实验我们采样ADC_IN选取其中一个管脚作为输入引脚,需要对 ADC进行配置。需要配置的几个参数:ADC转化分辨率 ,配置采样的采样方式和扫描方向。这几个参数的配置在stm32f0xx_ad.H中使用一个结构体进行了说:
[c]
typedef struct{uint32_t ADC_Resolution; // 配置ADC的转化分辨率FunctionalState ADC_ContinuousConvMode; // 配置选择连续采样或单次采样uint32_t ADC_ExternalTrigConvEdge; // ADC内部边缘触发uint32_t ADC_ExternalTrigConv; //ADC 内部触发uint32_t ADC_DataAlign; // 设置ADC是左对齐或者右对齐uint32_t ADC_ScanDirection; // 设置ADC扫描方向}ADC_InitTypeDef;
[/c]
使用中给出一组操作,基于直接存储器访问DMA的控制方式:称为为直接存储器访问模式:DMA。这种方式是为了更为有效地利用处理器和总线可用带宽而设计的。他不需要CPU的情况完成操作。下大大提高了运行效率。
DMA控制器依赖于处理器内核,但DMA不影响总线传输,因为DMA控制器总是在系统总线空闲的时候使用总线。该总线实现处理器和DMA控制器之间最优化设计,使两者之间的冲突降到最低,因此传输性能得到提高。
提供了存储单元到存储单元,外设到存储单元,存储单元到外设等转换模式。DMA为每种支持的外设功能提供专用通道,可以各自独立进行配置。其配置模式多种多样,时候于各自不同的设置要求。
采样库函数配置了DMA的几个参数:
[c]
typedef struct{ uint32_t DMA_PeripheralBaseAddr; //配置外设地址 uint32_t DMA_MemoryBaseAddr; // 配置内存映射地址 uint32_t DMA_DIR; // 制定外设的源或者目的地 uint32_t DMA_BufferSize; // DMA缓冲设置 uint32_t DMA_PeripheralInc; //设置外设地址是否增加或不增加 uint32_t DMA_MemoryInc; // 设置内存地址是否增加或不增加 uint32_t DMA_PeripheralDataSize; //外设数据宽度设置 uint32_t DMA_MemoryDataSize; //内存数据宽度设置 uint32_t DMA_Mode; // DMA模式 uint32_t DMA_Priority; // DMA优先级 uint32_t DMA_M2M; // memory-to-memory 传输模式设置}DMA_InitTypeDef;
[/c]
硬件准备:
硬件配置入下图所示,采用PA1作为引脚,对变阻器输入的信号进行转换:


软件准备:
软件采用库函数进行配置,用户需要配置编写adc.c驱动函数,工程目录如下图所示:

首先我们需要初始化AD配置,在adc.c文件中,我们编写ADC1_DMA_Init()函数,通过配置DMA通道和ADC外设,首先DMA配置如下:
[c]
/* DMA1 Channel1 Config */ DMA_DeInit(DMA1_Channel1);//选择频道 DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;//设置外设地址 DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&RegularConvData_Tab;//设置内存映射地址DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;DMA_InitStruct.DMA_BufferSize =4;//缓冲为4DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//关外设地址计数DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;//关内存地址计数DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//半字节DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;//循环模式DMA_InitStruct.DMA_Priority = DMA_Priority_High;//高优先级DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;//关内存到内存DMA_Init(DMA1_Channel1, &DMA_InitStruct);
/* DMA1 Channel1 enable */DMA_Cmd(DMA1_Channel1, ENABLE);//频道使能ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);//配置DMA循环模式/* Enable ADC_DMA */ ADC_DMACmd(ADC1, ENABLE);
[/c]
然后对ADC参数进行配置:
[c]
/* 初始 ADC 配置 */ ADC_StructInit(&ADC_InitStruct); /* 配置ADC1 在连续模式下分辨率为12 bits */ ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b; ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStruct.ADC_ScanDirection = ADC_ScanDirection_Backward; ADC_Init(ADC1, &ADC_InitStruct);/* Convert the ADC1 Vref with 55.5 Cycles as sampling time */ ADC_ChannelConfig(ADC1, ADC_Channel_1 , ADC_SampleTime_55_5Cycles); /* ADC 刻度 */ ADC_GetCalibrationFactor(ADC1); ADC_DMACmd(ADC1, ENABLE); /* 使能ADC1 */ ADC_Cmd(ADC1, ENABLE); /* 等待ADCEN 标志 */ while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));
/* ADC1 定期变换 */ ADC_StartOfConversion(ADC1);
 
[/c]
写好初始化函数后,在子函数内就可以直接调用:
[c]
#include "stm32f0xx.h"#include "adc.h"#include "systick.h"#include "w25x16.h"#include "ili9328.h"// ADC1转换的电压值通过MDA方式传到flashextern __IO uint16_t RegularConvData_Tab;
// 局部变量,用于存从flash读到的电压值__IO uint16_t ADC_ConvertedValueLocal;
void delay(__IO uint32_t nCount){ for(; nCount != 0; nCount--);}
int main(void){ SystemInit(); ADC1_DMA_Init(); LCD_init(); // 液晶显示器初始化 SPI_FLASH_Init(); LCD_Clear(WHITE); // 全屏显示白色 POINT_COLOR = BLACK; // 定义笔的颜色为黑色 BACK_COLOR = WHITE; // 定义笔的背景色为白色 LCD_DrawRectage(0, 0, 320, 20, DARKBLUE); // 画一个深蓝色边框的矩形 LCD_ShowString(2,2,"实验十"); LCD_ShowString(100,2,"adc采样实验"); while(1) { ADC_ConvertedValueLocal= RegularConvData_Tab; delay(0xffffee); LCD_ShowString(20,40,"adc采样值:"); LCD_ShowNum(100,40,ADC_ConvertedValueLocal,4); }}
 
[/c]
实验现象:
调节滑动变阻器,AD转换后成不同的值,结果如下图所示:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /2 下一条

手机版|小黑屋|与非网

GMT+8, 2024-3-29 14:54 , Processed in 0.123566 second(s), 19 queries , MemCache On.

ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

苏公网安备 32059002001037号

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.