当前位置: 首页 > news >正文

有什么网站是layui做的网站注册备案查询

有什么网站是layui做的,网站注册备案查询,建设医院的网站,搜索引擎网站推广法怎么做一、简介 上节课我们讲解了DMA的主要结构以及实现数据转运的基本原理,在本节课我们主要学习代码部分,使用DMA实现数据转运以及结合ADC实现多通道的使用。 上节课的地址:初学者STM32—DMA数据储存-CSDN博客 二、转运数组数据 void MyDMA_In…

一、简介

上节课我们讲解了DMA的主要结构以及实现数据转运的基本原理,在本节课我们主要学习代码部分,使用DMA实现数据转运以及结合ADC实现多通道的使用。

上节课的地址:初学者STM32—DMA数据储存-CSDN博客

二、转运数组数据

void MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size)
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);DMA_InitTypeDef DMA_InitStructure;DMA_InitStructure.DMA_PeripheralBaseAddr = AddrA ;	//起始地址(外设)DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;	//数据宽度DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;			//是否自增DMA_InitStructure.DMA_MemoryBaseAddr = AddrB;				//起始地址(存储器)DMA_InitStructure.DMA_MemoryDataSize= DMA_MemoryDataSize_Byte;			//数据宽度DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;		//是否自增

首先就是打开DMA的总线,通过查找可以知道DMA是AHB总线的设备,所以是AHB时钟。

初始化外设与存储器的三个参数:起始地址、数据宽度、是否自增

外设的起始置:地址为AddrA,这个地址是我设置初始数据地址,这是一个地址后面要用

数据宽度:字节传输uint8_t

是否自增:是(传输一个数值,地址++,因为这里是传输数组,所以要自增)

寄存器起始地址:AddrB,这个地址是我设置的,后面会传入地址

数据宽度:字节传输uint8_t

是否自增:是(传输一个后挪一个坑位防止数据覆盖)

	DMA_InitStructure.DMA_DIR= DMA_DIR_PeripheralSRC; //传输方向DMA_InitStructure.DMA_BufferSize = Size;//缓冲区大小DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //传输模式(是否重装)DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;	//存储器到存储器(硬件触发或者软件触发)DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //优先级DMA_Init(DMA1_Channel1,&DMA_InitStructure);DMA_Cmd(DMA1_Channel1,ENABLE);

传输方向:外设为资源(也就是从外设传输到储存器) 

缓冲区大小BufferSize:Size(这个是我在函数定义中定义的大小,后面通过调用传入数值)

是否重装:否(这里是因为采用了软件触发的方式,不能用自动重装)

触发方式:软件触发。

优先级:中(这个程序只有一个数据转运,没有先后之分,这里就用中等)

随后将结构体配置传进DMA_Init中(DMA1_Channel1按照上图要求填写)

最后开启DMA_Cmd。

uint8_t DataA[4] ={0x01,0x02,0x03,0x04};
uint8_t DataB[4] ={0,0,0,0};
MyDMA_Init((uint32_t)DataA, (uint32_t)DataB, 4);

因为我们地址没有数值,所以定义了DataA数组和DataB数组,我们尝试通过数据转运将DataA里面的数据传入DataB。

所以将这DataA和DataB的地址以及传输的次数(BufferSize)传进MyDMA_Init初始化函数里面。

虽然DataA和DataB是数组名,是一个地址,但是也需要强制转换成32位的地址,这样就能够与DMA所写入的地址保持一致了。

void DMA_Tranfer()
{DMA_Cmd(DMA1_Channel1,DISABLE);DMA_SetCurrDataCounter(DMA1_Channel1,MyDMA_Size);DMA_Cmd(DMA1_Channel1,ENABLE);while((DMA_GetFlagStatus(DMA1_FLAG_TC1))== RESET)DMA_ClearFlag(DMA1_FLAG_TC1);
}

最后,为了能够让改变DataA数据也能够转运到DataB当中,我加入了转换函数,其原理就是先关闭DMA转运,再重新放入转运的次数和通道再开启DMA

然后就是转运标志位必须要转运完成后进行清除才能进行下一次的转运。

最后程序能够实现DataA转运到DataB当中,且DataA在改变数据的同时也能转运到DataB。

 三、DMA对ADC多通道转运

在ADC的扫描模式当中,由于转换过程中会因为数据无法及时挪走而导致数据被覆盖,所以我们引入DMA在扫描每一次都进行触发转运,这样就能够实现每一个数据都能够得到转换。

上图为主要思路。 

连线图

电位器、光敏传感器、热敏传感器、反射式红外传感器 分别接入PA0,PA1,PA2,PA3这三个接口

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);			//开启RCC时钟ADC时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);		//开启GPIO时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);RCC_ADCCLKConfig(RCC_PCLK2_Div6);		//72Mhz/6=12MhzGPIO_InitTypeDef GPIO_InitStructure;		//通过结构体配置GPIO模式GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;		//配置为模拟输入模式GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);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);	

首先就是正常的配置RCC时钟,GPIO配置。。

然后进行ADC通道的选择,四个通道,四个序列,采样时时间不变

	ADC_InitTypeDef ADC_InitStructure;			ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_NbrOfChannel = 4;	//扫描4个ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //持续转换模式ADC_InitStructure.ADC_ScanConvMode = ENABLE;	//扫描模式			ADC_Init(ADC1,&ADC_InitStructure);

ADC结构体配置
模式:选择独立模式,即单独使用ADC1
数据对齐:选择右对齐
外部触发:使用软件触发,不需要外部触发
连续转换:使能,每转换一次规则组序列后立刻开始下一次转换
扫描模式:使能,扫描规则组的序列,扫描数量由ADC_NbrOfChannel确定
通道数:4,扫描规则组的前4个通道
最后将结构体变量交给ADC_Init,配置ADC1

	DMA_InitTypeDef DMA_InitStructure;DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR ;	//起始地址(外设)DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;	//数据宽度DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//是否自增DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)AD_Value;	//起始地址(存储器)DMA_InitStructure.DMA_MemoryDataSize= DMA_MemoryDataSize_HalfWord;	//数据宽度DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;	//是否自增DMA_InitStructure.DMA_DIR= DMA_DIR_PeripheralSRC;	//传输方向DMA_InitStructure.DMA_BufferSize = 4;			//缓冲区大小DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;	//传输模式(是否重装)DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;	//存储器到存储器(硬件触发或者软件触发)DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;	//优先级DMA_Init(DMA1_Channel1,&DMA_InitStructure);

定义DMA结构体变量
外设基地址:(uint32_t)&ADC1->DR ,选择的是ADC1的地址
外设数据宽度:半字,对应16为的ADC数据寄存器
外设地址自增:失能,始终以ADC数据寄存器为源

存储器基地址:给定存放AD转换结果的全局数组AD_Value
存储器数据宽度:半字,与源数据宽度对应
存储器地址自增:使能,每次转运后,数组移到下一个位置

数据传输方向:选择由外设到存储器,ADC数据寄存器转到数组
转运的数据大小(转运次数):与ADC通道数一致为 4
模式:循环模式,与ADC的连续转换一致
存储器到存储器:失能,数据由ADC外设触发转运到存储器
优先级:选择中等
最后将结构体变量交给DMA_Init,配置DMA1的通道1

	DMA_Cmd(DMA1_Channel1,ENABLE);ADC_DMACmd(ADC1,ENABLE);ADC_Cmd(ADC1,ENABLE);ADC_ResetCalibration(ADC1);		//复位校准while(ADC_GetCalibrationStatus(ADC1) == SET);	//返回复位校准状态ADC_StartCalibration(ADC1);			//开始校准while(ADC_GetCalibrationStatus(ADC1) == SET);ADC_SoftwareStartConvCmd(ADC1,ENABLE);

最后就是开关函数

打开DMA、ADC触发DMA、ADC三个使能开关。

我们看到框中的这个位置: 我们选择的是ADC1触发DMA,然后经过总裁器选择触发优先级(这里只有ADC1这一个触发),必须要开启这里一路才有效。

ADC_DMACmd(ADC1,ENABLE) 这个函数

接着校准ADC,这个是固定的操作

最后打开软件触发:软件触发ADC开始工作,由于ADC处于连续转换模式,故触发一次后ADC就可以一直连续不断地工作

最后成功实现ADC扫描模式+DMA转运数据并显示出来

四、ADC+DMA完整代码

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"int main(void)
{AD_Init();   //AD转换初始化函数OLED_Init();	//初始化OLEDOLED_ShowString(1,1,"AD0:");OLED_ShowString(2,1,"AD1:");	OLED_ShowString(3,1,"AD2:");OLED_ShowString(4,1,"AD3:");while(1){OLED_ShowNum(1,5,AD_Value[0],4);OLED_ShowNum(2,5,AD_Value[1],4);OLED_ShowNum(3,5,AD_Value[2],4);OLED_ShowNum(4,5,AD_Value[3],4);}
}

AD.c

#include "stm32f10x.h"                  // Device headeruint16_t AD_Value[4];void AD_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);			//开启RCC时钟ADC时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);		//开启GPIO时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);RCC_ADCCLKConfig(RCC_PCLK2_Div6);		//72Mhz/6=12MhzGPIO_InitTypeDef GPIO_InitStructure;		//通过结构体配置GPIO模式GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;		//配置为模拟输入模式GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);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_InitTypeDef ADC_InitStructure;			ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_NbrOfChannel = 4;	//扫描4个ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //持续转换模式ADC_InitStructure.ADC_ScanConvMode = ENABLE;	//扫描模式			ADC_Init(ADC1,&ADC_InitStructure);DMA_InitTypeDef DMA_InitStructure;DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR ;	//起始地址(外设)DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;	//数据宽度DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//是否自增DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)AD_Value;	//起始地址(存储器)DMA_InitStructure.DMA_MemoryDataSize= DMA_MemoryDataSize_HalfWord;	//数据宽度DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;	//是否自增DMA_InitStructure.DMA_DIR= DMA_DIR_PeripheralSRC;	//传输方向DMA_InitStructure.DMA_BufferSize = 4;			//缓冲区大小DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;	//传输模式(是否重装)DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;	//存储器到存储器(硬件触发或者软件触发)DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;	//优先级DMA_Init(DMA1_Channel1,&DMA_InitStructure);DMA_Cmd(DMA1_Channel1,ENABLE);ADC_DMACmd(ADC1,ENABLE);ADC_Cmd(ADC1,ENABLE);ADC_ResetCalibration(ADC1);		//复位校准while(ADC_GetCalibrationStatus(ADC1) == SET);	//返回复位校准状态ADC_StartCalibration(ADC1);			//开始校准while(ADC_GetCalibrationStatus(ADC1) == SET);ADC_SoftwareStartConvCmd(ADC1,ENABLE);
}

AD.h 

#ifndef __AD_H
#define __AD_Hextern uint16_t AD_Value[4];
void AD_Init(void);#endif

 

 

 

 

 

 

http://www.dtcms.com/a/543909.html

相关文章:

  • 做旅游去哪个网站找图it外包服务平台
  • 专业网站定制流程万能视频下载神器
  • 万维网站续费多少一年苏州吴江保洁公司
  • 杭州网站建设找思创网络沧州青县机械加工网
  • 云南俊发建设集团网站html简单一套网页源代码
  • 财经网站源码 织梦咸阳 网站建设
  • 网站开发程序开发广东网站开发收费
  • 配资网站建设是什么意思北京哪些做网站的公司好
  • 乐清网站建设服务wordpress 使用ip访问
  • 深圳制作网站搜行者seojs特效如何放到网站上
  • 怎么建设公司网站信息优质做网站费用
  • 班级网站建设的参考文献求个网站谢谢啦
  • 印尼网站建设费用专业的新乡网站建设
  • 公司网站建设哪家比较好欢乐海岸网站建设
  • 广州网站制作在线美妆购物网站开发的总结
  • 门户网站建设公司价位设计类网站app
  • 网站项目总体设计模板兰州市门户网站
  • 网站会员管理wordpress编辑富文
  • 贴心的合肥网站建设低价网站建设教程
  • 盘锦网站推广西安是哪个省的城市
  • 域名注册后如何建网站电商网站开发哪家好
  • 外贸网站模板推荐阿里云1m宽带做网站卡吗
  • 格尔木市公司网站建设网络推广怎么做黄页88
  • 沈阳网站推广有什么技巧青岛君哲网站建设公司怎么样
  • 物流公司网站制作模板电子商务网站建设的语言及特点
  • 甘肃嘉峪关建设局网站网站建设与实践心得
  • 公众号申请网站企查查 天眼查
  • 天津+交友+网站建设哪些属于功能型网站
  • 品网站建设网站源码下载安全吗
  • 做装饰网站公司网页设计与制作课程评价内实