STM32 7-8

目录

ADC

AD单通道

AD多通道

DMA

DMA转运数据

DMA+AD多通道


ADC

AD单通道

AD.c

#include "stm32f10x.h"                  // Device header/*** @brief  初始化AD所需要的所有设备* @param  无* @retval 无*/
void AD_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADCCLK为六分频GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1, ADC_SampleTime_55Cycles5);//配置输入通道//所选ADC设备,指定ADC通道,规则组序列器中的次序,指定通道采样时间(更快就选小参数,更稳定就选大参数)//初始化ADCADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC工作模式ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//外部触发转换选择//单通道单次转换非扫描模式    //单通道连续转换,非扫描模式ADC_InitStructure.ADC_NbrOfChannel = 1;//通道数目ADC_InitStructure.ADC_ScanConvMode = DISABLE;//扫描转换模式ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//非连续转换模式//ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换模式ADC_Init(ADC1,&ADC_InitStructure);ADC_Cmd(ADC1,ENABLE);//开启ADC1//进行ADC校准ADC_ResetCalibration(ADC1);//复位校准while(ADC_GetResetCalibrationStatus(ADC1) == SET);//等待复位校准完成ADC_StartCalibration(ADC1);//开始校准while(ADC_GetCalibrationStatus(ADC1) == SET);//等待校准完成//ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启软件触发转换
}/*** @brief  获取AD所得值* @param  无* @retval  转化出来的数据量最大为4095*/
uint16_t AD_GetValue(void)
{ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启软件触发转换while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);//获取标志位状态(为Reset表示没有转换完成)//大约等待 (1 / 72MHz / 6) X (55.5 + 12.5) = 5.6usreturn ADC_GetConversionValue(ADC1);//调用后会自动清除EOC标志位
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"uint16_t ADValue;
float Voltage;int main(void)
{OLED_Init();AD_Init();OLED_ShowString(1,1,"ADValue:");OLED_ShowString(2,1,"Voltage:0.00V");while(1){ADValue = AD_GetValue();Voltage = (float)ADValue / 4095 * 3.3;OLED_ShowNum(1,9,ADValue,4);OLED_ShowNum(2,9,Voltage,1);//输出整数部分OLED_ShowNum(2,11,(uint16_t)(Voltage * 100) % 100,2);//输出小数部分Delay_ms(100);}}
AD多通道

AD.c

#include "stm32f10x.h"                  // Device header/*** @brief  初始化AD所需设备* @param  无* @retval 无*/
void AD_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADCCLK为六分频GPIO_InitTypeDef GPIO_InitStructure;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);//初始化ADCADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC工作模式ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//外部触发转换选择//单通道单次转换非扫描模式    ADC_InitStructure.ADC_NbrOfChannel = 1;//通道数目ADC_InitStructure.ADC_ScanConvMode = DISABLE;//扫描转换模式ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//非连续转换模式ADC_Init(ADC1,&ADC_InitStructure);ADC_Cmd(ADC1,ENABLE);//开启ADC1//进行ADC校准ADC_ResetCalibration(ADC1);//复位校准while(ADC_GetResetCalibrationStatus(ADC1) == SET);//等待复位校准完成ADC_StartCalibration(ADC1);//开始校准while(ADC_GetCalibrationStatus(ADC1) == SET);//等待校准完成}/**
*@brief  通过传入不同ADC通道,实现多通道AD,本质还是单通道
*@param  ADC_Channel:所选通道
*@retval 转化出的数据量最大为4095*/
uint16_t AD_GetValue(uint8_t ADC_Channel)
{ADC_RegularChannelConfig(ADC1,ADC_Channel,1, ADC_SampleTime_55Cycles5);//配置输入通道//所选ADC设备,指定ADC通道,规则组序列器中的次序,指定通道采样时间(更快就选小参数,更稳定就选大参数)ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启软件触发转换while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);//获取标志位状态(为Reset表示没有转换完成)//大约等待 (1 / 72MHz / 6) X (55.5 + 12.5) = 5.6usreturn ADC_GetConversionValue(ADC1);//调用后会自动清除EOC标志位
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"uint16_t AD0,AD1,AD2,AD3;int main(void)
{OLED_Init();AD_Init();OLED_ShowString(1,1,"AD0:");OLED_ShowString(2,1,"AD1:");OLED_ShowString(3,1,"AD2:");OLED_ShowString(4,1,"AD3:");while(1){AD0 = AD_GetValue(ADC_Channel_0);AD1 = AD_GetValue(ADC_Channel_1);AD2 = AD_GetValue(ADC_Channel_2);AD3 = AD_GetValue(ADC_Channel_3);OLED_ShowNum(1,5,AD0,4);OLED_ShowNum(2,5,AD1,4);OLED_ShowNum(3,5,AD2,4);OLED_ShowNum(4,5,AD3,4);Delay_ms(100);}}

DMA

DMA转运数据

MyDMA.c

#include "stm32f10x.h"                  // Device headeruint16_t MyDMA_Size;/*** @brief  初始化DMA* @param  无* @retval 无*/
void MyDMA_Init(uint32_t AddrA,uint32_t AddrB,uint16_t Size)
{MyDMA_Size = Size;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//开启MDA1时钟DMA_InitTypeDef DMA_InitStructrue;DMA_InitStructrue.DMA_PeripheralBaseAddr = AddrA;//外设起始地址DMA_InitStructrue.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据宽度DMA_InitStructrue.DMA_PeripheralInc = DMA_PeripheralInc_Enable;//外设是否自增DMA_InitStructrue.DMA_MemoryBaseAddr = AddrB;//存储器起始地址DMA_InitStructrue.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte ;//存储器数据宽度DMA_InitStructrue.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器是否自增DMA_InitStructrue.DMA_DIR = DMA_DIR_PeripheralSRC;//传输方向(外设作为源头)DMA_InitStructrue.DMA_BufferSize = Size;//传输计数器(传输次数)DMA_InitStructrue.DMA_Mode = DMA_Mode_Normal;//传输模式,是否使用自动重装(转运后停止)DMA_InitStructrue.DMA_M2M = DMA_M2M_Enable;//选择硬件触发,还是软件触发(软件触发)DMA_InitStructrue.DMA_Priority = DMA_Priority_Medium;//优先级(多个通道进行配置)DMA_Init(DMA1_Channel1,&DMA_InitStructrue);DMA_Cmd(DMA1_Channel1,DISABLE);//不让DMA初始化后立刻转运
}/*** @brief  将外设数据通过DMA写入存储器* @param  无* @retval 无*/
void MyDMA_Transfer(void)
{DMA_Cmd(DMA1_Channel1,DISABLE);//为传输计数器赋值,需先失能DMADMA_SetCurrDataCounter(DMA1_Channel1,MyDMA_Size);//重新给传输计数器写入值DMA_Cmd(DMA1_Channel1,ENABLE);//使能DMAwhile(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);//检查DMA1通道1转换完成的标志位(完成标志位置一)//未完成则一直空循环等待DMA_ClearFlag(DMA1_FLAG_TC1);//需要手动清除标志位
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyDMA.h"uint8_t DataA[] = {0x01,0x02,0x03,0x04};
uint8_t DataB[] = {0,0,0,0};uint8_t i;int main(void)
{OLED_Init();MyDMA_Init((uint32_t)DataA,(uint32_t)DataB,4);//DataA 转运至 DataOLED_ShowString(1,1,"DataA");OLED_ShowString(3,1,"DataA");OLED_ShowHexNum(1,8,(uint32_t)DataA,8);OLED_ShowHexNum(3,8,(uint32_t)DataB,8);for(i = 0;i < 4;i++){OLED_ShowHexNum(2,3*i+1,DataA[i],2);}for(i = 0;i < 4;i++){OLED_ShowHexNum(4,3*i+1,DataB[i],2);}while(1){DataA[0] ++;DataA[1] ++;DataA[2] ++;DataA[3] ++;for(i = 0;i < 4;i++){OLED_ShowHexNum(2,3*i+1,DataA[i],2);}for(i = 0;i < 4;i++){OLED_ShowHexNum(4,3*i+1,DataB[i],2);}Delay_s(1);MyDMA_Transfer();//开始转运for(i = 0;i < 4;i++){OLED_ShowHexNum(2,3*i+1,DataA[i],2);}for(i = 0;i < 4;i++){OLED_ShowHexNum(4,3*i+1,DataB[i],2);}Delay_s(1);}}
DMA+AD多通道

AD.c

#include "stm32f10x.h"                  // Device headeruint16_t AD_Value[4];/*** @brief  初始化AD以及DMA* @param  无* @retval 无*/
void AD_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//开启MDA1时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADCCLK为六分频GPIO_InitTypeDef GPIO_InitStructure;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设备,指定ADC通道,规则组序列器中的次序,指定通道采样时间(更快就选小参数,更稳定就选大参数)//初始化ADCADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC工作模式ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//外部触发转换选择//ADC扫描模式+数据转运 //ADC连续扫描+DMA循环转运ADC_InitStructure.ADC_NbrOfChannel = 4;//通道数目ADC_InitStructure.ADC_ScanConvMode = ENABLE;//扫描转换模式(设置为扫描模式)//ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//是否为连续模式ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;ADC_Init(ADC1,&ADC_InitStructure);//配置DMADMA_InitTypeDef DMA_InitStructrue;DMA_InitStructrue.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//外设起始地址DMA_InitStructrue.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据宽度(16位)DMA_InitStructrue.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设是否自增(始终转运同一位置数据)DMA_InitStructrue.DMA_MemoryBaseAddr =  (uint32_t)AD_Value;//存储器起始地址DMA_InitStructrue.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存储器数据宽度DMA_InitStructrue.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器是否自增DMA_InitStructrue.DMA_DIR = DMA_DIR_PeripheralSRC;//传输方向(外设作为源头)DMA_InitStructrue.DMA_BufferSize = 4;//传输计数器(传输次数)//DMA_InitStructrue.DMA_Mode = DMA_Mode_Normal;//传输模式,是否使用自动重装(转运后停止)DMA_InitStructrue.DMA_Mode = DMA_Mode_Circular;//循环模式DMA_InitStructrue.DMA_M2M = DMA_M2M_Disable;//选择硬件触发,还是软件触发(硬件触发)DMA_InitStructrue.DMA_Priority = DMA_Priority_Medium;//优先级(多个通道进行配置)DMA_Init(DMA1_Channel1,&DMA_InitStructrue);//这里的通道必须使用DMA1_Channel1,详情查表DMA_Cmd(DMA1_Channel1,ENABLE);//让DMA初始化后立刻转运ADC_DMACmd(ADC1,ENABLE);//开启ADC触发DMA信号ADC_Cmd(ADC1,ENABLE);//开启ADC1//进行ADC校准ADC_ResetCalibration(ADC1);//复位校准while(ADC_GetResetCalibrationStatus(ADC1) == SET);//等待复位校准完成ADC_StartCalibration(ADC1);//开始校准while(ADC_GetCalibrationStatus(ADC1) == SET);//等待校准完成ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启软件触发转换
}/**
*@brief  通过传入不同ADC通道,实现多通道AD,本质还是单通道
*@param  ADC_Channel:所选通道
*@retval 转化出的数据量最大为4095*/
//void AD_GetValue(void)
//{
//    DMA_Cmd(DMA1_Channel1,DISABLE);//为传输计数器赋值,需先失能DMA
//    DMA_SetCurrDataCounter(DMA1_Channel1,4);//重新给传输计数器写入值
//    DMA_Cmd(DMA1_Channel1,ENABLE);//使能DMA
//    
//    //ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启软件触发转换
//    
//    while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);//检查DMA1通道1转换完成的标志位(完成标志位置一)
//    //未完成则一直空循环等待
//    DMA_ClearFlag(DMA1_FLAG_TC1);//需要手动清除标志位
//}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"int main(void)
{OLED_Init();AD_Init();OLED_ShowString(1,1,"AD0:");OLED_ShowString(2,1,"AD1:");OLED_ShowString(3,1,"AD2:");OLED_ShowString(4,1,"AD3:");while(1){//AD_GetValue();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);Delay_ms(100);}}

7

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/465251.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SPI NOR FLASH和SPI NAND FLASH

SPI NOR FLASH和SPI NAND FLASH是两种不同的存储设备&#xff0c;它们在硬件接口和软件应用上都有所不同。以下是关于这两种存储设备更详细的介绍&#xff1a; 1.SPI NOR FLASH SPI NOR FLASH是一种非易失性存储器&#xff0c;它通过串行接口进行数据传输&#xff0c;具有读写…

【fortran】开源BLAS库矩阵乘法的简单Fortran示例

一、安装开源BLAS库OpenBLAS 安装 OpenBLAS 可以通过几个步骤来完成&#xff0c;这些步骤因操作系统的不同而有所变化。以下是为几种常见系统下的安装。 在 Ubuntu/Debian Linux 上安装 OpenBLAS 在基于 Debian 的系统&#xff08;如 Ubuntu&#xff09;上&#xff0c;可以使…

FAST角点检测算法

FAST&#xff08;Features from Accelerated Segment Test&#xff09;角点检测算法是一种快速且高效的角点检测方法。它通过检测每个像素周围的连续像素集合&#xff0c;确定是否为角点。以下是 FAST 角点检测算法的基本流程&#xff1a; FAST 角点检测算法的基本过程主要包括…

内网安全-内网穿透

目录 内网渗透 Nc使用详解 Nc监听和探测 Nc传文件 termite内网穿透工具 ssh代理内网穿透 ssh配置socket代理 MSF多级网络穿透 内网渗透 Nc使用详解 Nc监听和探测 Nc传文件 termite内网穿透工具 1、termite 之前叫ew &#xff08;可以进行正向连接&#xff0c;可以…

读千脑智能笔记11_保存人类遗产

1. 智能生物通常能延续多久 1.1. SETI和METI计划的可行性在很大程度上取决于智能生物通常能延续多久 1.1.1. 搜寻地外文明&#xff08;以下简称SETI&#xff09;计划的目标 1.1.1.1. 这是一个力图寻找宇宙其他地方智能生物存在证据的研究项目 1.1.1.2. SETI计划旨在寻找含有…

mac卸载被锁定的app

sudo chflags -hv noschg /Applications/YunShu.app 参考&#xff1a;卸载云枢&#xff08;MacOS 版&#xff09;

Java的接口

目录 1.接口的概念 2.语法规则 3.接口的使用 4.接口的特性 总结&#xff1a; 5.实现多个接口 6.接口间的继承 1.接口的概念 接口就是公共的行为规范标准&#xff0c;大家在实现时&#xff0c;只要符合规范标准&#xff0c;就可以通用。 在Java中&#xff0c;接口可以看成…

Deepin基本环境查看(九)【被封印的创世神】

文章目录 - 相关文章目录1、概述2、Deepin中的创世神和管理员1&#xff09;创世神root2&#xff09;root被封印原因3&#xff09;其他的神灵【管理员】 3、神殿管理【su与sudo】1&#xff09;su&#xff08;Switch User&#xff09;2&#xff09;sudo&#xff08;Superuser Do&…

centos间文件传输

scp /home/vagrant/minio zx192.168.56.34:/home/zx /home/vagrant/minio 是你要传输的文件而且是当前机器登录用户有权限操作的文件 zx是目标机器的用户192.168.56.34是目标机器的地址 /home/zx是要传到这个文件夹下 要确保zx有/home/zx这个文件夹的操作权限 本质就是ssh文…

LeetCode Python -8.字符串转整数

文章目录 题目答案运行结果 题目 请你来实现一个 myAtoi(string s) 函数&#xff0c;使其能将字符串转换成一个 32 位有符号整数&#xff08;类似 C/C 中的 atoi 函数&#xff09;。 函数 myAtoi(string s) 的算法如下&#xff1a; 读入字符串并丢弃无用的前导空格检查下一个…

如何把手机平板变为电脑的屏幕

文章目录 安装软件运行效果结尾 本文首发地址 https://h89.cn/archives/181.html 最新更新地址 https://gitee.com/chenjim/chenjimblog 闲置的手机平板、触屏音箱等&#xff0c;均可作为电脑的扩展屏&#xff0c;为电脑增加一块显示屏&#xff0c;本文介绍如何使用免费的软件s…

python基于flask的网上订餐系统769b9-django+vue

课题主要分为两大模块&#xff1a;即管理员模块和用户模块&#xff0c;主要功能包括个人中心、用户管理、菜品类型管理、菜品信息管理、留言反馈、在线交流、系统管理、订单管理等&#xff1b; 如果用户想要交换信息&#xff0c;他们需要满足双方交换信息的需要。由于时间有限…