野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 28310|回复: 9

(交作业)31-ADC(第6节)—双ADC规则同步模式实验

[复制链接]
发表于 2019-9-19 13:16:44 | 显示全部楼层 |阅读模式
// 作业

// 把程序改成双模式的多通道
  

按要求改成了 adc1 三通道和adc2 三通道



回复

使用道具 举报

 楼主| 发表于 2019-9-19 13:17:21 | 显示全部楼层
[mw_shl_code=c,true]#include "stm32f10x.h"
#include "bsp_usart.h"
#include "bsp_adc.h"


extern __IO uint32_t ADC_ConvertedValue[NOFCHANEL];

// 局部变量,用于保存转换计算后的电压值          
float ADC_ConvertedValueLocal[NOFCHANEL*2]={0};        

// 软件延时
void Delay(__IO uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}

/**
  * @brief  主函数
  * @param  无
  * @retval 无
  */
int main(void)
{       
  uint16_t temp0=0 ,temp1=0,temp2=0 ,temp3=0,temp4=0 ,temp5=0;
        /*初始化USART 配置模式为 115200 8-N-1,中断接收*/
  USART_Config();
        printf("欢迎使用秉火STM32开发板\n\n\n\n");
       
        ADCx_Init();
        while (1)
        {       
    // 取出ADC1数据寄存器的高16位,这个是ADC2的转换数据
                temp0 = (ADC_ConvertedValue[0]&0XFFFF0000) >> 16;
                // 取出ADC1数据寄存器的低16位,这个是ADC1的转换数据
                temp1 = (ADC_ConvertedValue[0]&0XFFFF);       
               
// 取出ADC1数据寄存器的高16位,这个是ADC2的转换数据
                temp2 = (ADC_ConvertedValue[1]&0XFFFF0000) >> 16;
                // 取出ADC1数据寄存器的低16位,这个是ADC1的转换数据
                temp3 = (ADC_ConvertedValue[1]&0XFFFF);       
                // 取出ADC1数据寄存器的高16位,这个是ADC2的转换数据
                temp4 = (ADC_ConvertedValue[2]&0XFFFF0000) >> 16;
                // 取出ADC1数据寄存器的低16位,这个是ADC1的转换数据
                temp5 = (ADC_ConvertedValue[2]&0XFFFF);       
               
                ADC_ConvertedValueLocal[0] =(float) temp0/4096*3.3;
                ADC_ConvertedValueLocal[1] =(float) temp1/4096*3.3;
                ADC_ConvertedValueLocal[2] =(float) temp2/4096*3.3;
                ADC_ConvertedValueLocal[3] =(float) temp3/4096*3.3;
                ADC_ConvertedValueLocal[4] =(float) temp4/4096*3.3;
                ADC_ConvertedValueLocal[5] =(float) temp5/4096*3.3;
       
               
               
               
               
                printf("\r\n ADCx_1 value = %f V \r\n",ADC_ConvertedValueLocal[0]);
                printf("\r\n ADCx_2 value = %f V \r\n",ADC_ConvertedValueLocal[1]);
                printf("\r\n ADCx_3 value = %f V \r\n",ADC_ConvertedValueLocal[2]);
                printf("\r\n ADCx_4 value = %f V \r\n",ADC_ConvertedValueLocal[3]);
                printf("\r\n ADCx_5 value = %f V \r\n",ADC_ConvertedValueLocal[4]);
                printf("\r\n ADCx_6 value = %f V \r\n",ADC_ConvertedValueLocal[5]);
       
               
               
               
               
               
               
               
                printf("\r\n\r\n");
                Delay(0xffffee);
                 
        }

}[/mw_shl_code]
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2019-9-19 13:18:18 | 显示全部楼层
[mw_shl_code=c,true]#include "bsp_adc.h"

__IO uint32_t ADC_ConvertedValue[NOFCHANEL]={0};

static void ADCx_GPIO_Config(void)
{       
        GPIO_InitTypeDef GPIO_InitStructure;
        // ADCx_1 GPIO 初始化      
RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOC, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);       
       
RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOC, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);       
       
RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOC, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);       
       


// ADCx_2 GPIO 初始化
RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOC, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);       

RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOC, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);

RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOC, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);

}

// ANSI C标准,C89 标准
// C99
// C11 2011

static void ADCx_Mode_Config(void)
{
        DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;

// 打开 DMA 时钟
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
        // 打开 ADC 时钟
        RCC_APB2PeriphClockCmd ( RCC_APB2Periph_ADC1, ENABLE );
  RCC_APB2PeriphClockCmd ( RCC_APB2Periph_ADC2, ENABLE );

/* ------------------DMA 模式配置---------------- */
// 复位 DMA 控制器
DMA_DeInit(ADC_DMA_CHANNEL);
// 配置 DMA 初始化结构体
// 外设基址为: ADC 数据寄存器地址
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&( ADCx_1->DR ));
// 存储器地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedValue;

// 数据源来自外设
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
// 缓冲区大小,应该等于数据目的地的大小
DMA_InitStructure.DMA_BufferSize = NOFCHANEL;
// 外设寄存器只有一个,地址不用递增
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
// 存储器地址递增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
// 外设数据大小
DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_Word;
// 内存数据大小,跟外设数据大小相同
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
// 循环传输模式
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
// DMA 传输通道优先级为高,当使用一个 DMA 通道时,优先级设置不影响
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
// 禁止存储器到存储器模式,因为是从外设到存储器
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
// 初始化 DMA
DMA_Init(ADC_DMA_CHANNEL, &DMA_InitStructure);
// 使能 DMA 通道
DMA_Cmd(ADC_DMA_CHANNEL , ENABLE);


/* ----------------ADCx_1 模式配置--------------------- */
// 双 ADC 的规则同步
ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
// 扫描模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE ;
// 连续转换模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
// 不用外部触发转换,软件开启即可
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
// 转换结果右对齐
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
// 转换通道个数
ADC_InitStructure.ADC_NbrOfChannel = NOFCHANEL;
// 初始化 ADC
ADC_Init(ADCx_1, &ADC_InitStructure);
// 配置 ADC 时钟为 PCLK2 的 8 分频,即 9MHz
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
// 配置 ADC 通道的转换顺序和采样时间
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1,ADC_SampleTime_1Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2,ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3,ADC_SampleTime_1Cycles5);



// 使能 ADC DMA 请求
ADC_DMACmd(ADCx_1, ENABLE);


/* ----------------ADCx_2 模式配置--------------------- */
// 双 ADC 的规则同步
ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
// 扫描模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE ;
// 连续转换模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
// 不用外部触发转换,软件开启即可
ADC_InitStructure.ADC_ExternalTrigConv =
ADC_ExternalTrigConv_None;
// 转换结果右对齐
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
// 转换通道个数
ADC_InitStructure.ADC_NbrOfChannel = NOFCHANEL;
// 初始化 ADC
ADC_Init(ADCx_2, &ADC_InitStructure);
// 配置 ADC 时钟N狿 CLK2 的 8 分频,即 9MHz
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
// 配置 ADC 通道的转换顺序和采样时间
ADC_RegularChannelConfig(ADC2, ADC_Channel_13, 1,ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC2, ADC_Channel_14, 2,ADC_SampleTime_1Cycles5);
          ADC_RegularChannelConfig(ADC2, ADC_Channel_15, 3,ADC_SampleTime_1Cycles5);
       
       
/* 使能 ADCx_2 的外部触发转换 */
ADC_ExternalTrigConvCmd(ADC2, ENABLE);

/* ----------------ADCx_1 校准--------------------- */
// 开启 ADC ,并开始转换
ADC_Cmd(ADCx_1, ENABLE);
// 初始化 ADC 校准寄存器
ADC_ResetCalibration(ADCx_1);
// 等待校准寄存器初始化完成
while (ADC_GetResetCalibrationStatus(ADCx_1));
// ADC 开始校准
ADC_StartCalibration(ADCx_1);
// 等待校准完成
while (ADC_GetCalibrationStatus(ADCx_1));

/* ----------------ADCx_2 校准--------------------- */
// 开启 ADC ,并开始转换
ADC_Cmd(ADCx_2, ENABLE);
// 初始化 ADC 校准寄存器
ADC_ResetCalibration(ADCx_2);
// 等待校准寄存器初始化完成
while (ADC_GetResetCalibrationStatus(ADCx_2));
// ADC 开始校准
ADC_StartCalibration(ADCx_2);
// 等待校准完成
while (ADC_GetCalibrationStatus(ADCx_2));

// 由于没有采用外部触发,所以使用软件触发 ADC 转换
ADC_SoftwareStartConvCmd(ADCx_1, ENABLE);




}

void ADCx_Init(void)
{
        ADCx_GPIO_Config();
        ADCx_Mode_Config();
}

[/mw_shl_code]
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2019-9-19 13:18:57 | 显示全部楼层
[mw_shl_code=c,true]#ifndef __BSP_ADC_H
#define        __BSP_ADC_H


#include "stm32f10x.h"


// 双模式时, ADC1 和 ADC2 转换的数据都存放在 ADC1 的数据寄存器,
// ADC1 的在低十六位, ADC2 的在高十六位
// 双 ADC 模式的第一个 ADC,必须是 ADC1
#define ADCx_1                          ADC1
#define ADCx_1_APBxClock_FUN                          RCC_APB2PeriphClockCmd
#define ADCx_1_CLK                                          RCC_APB2Periph_ADC1

#define ADCx_1_GPIO_APBxClock_FUN             RCC_APB2PeriphClockCmd
#define ADCx_1_GPIO_CLK                         RCC_APB2Periph_GPIOC
#define ADCx_1_PORT                            GPIOC
#define ADCx_1_PIN                                   GPIO_Pin_1
#define ADCx_1_CHANNEL                         ADC_Channel_8

// 双 ADC 模式的第二个 ADC,必须是 ADC2
#define ADCx_2                                                                                                 ADC2
#define ADCx_2_APBxClock_FUN                                                                 RCC_APB2PeriphClockCmd
#define ADCx_2_CLK                                                                                         RCC_APB2Periph_ADC2

#define ADCx_2_GPIO_APBxClock_FUN                                          RCC_APB2PeriphClockCmd
#define ADCx_2_GPIO_CLK                                                                                 RCC_APB2Periph_GPIOC
#define ADCx_2_PORT                                                                                                 GPIOC
#define ADCx_2_PIN                                                                                                                         GPIO_Pin_4
#define ADCx_2_CHANNEL                                                                                                                 ADC_Channel_9

#define NOFCHANEL                                                 3
// ADC1 对应 DMA1 通道 1, ADC3 对应 DMA2 通道 5, ADC2 没有 DMA 功能
#define ADC_DMA_CHANNEL                                                                                                 DMA1_Channel1

void ADCx_Init(void);

#endif /* __BSP_ADC_H */

[/mw_shl_code]
回复 支持 1 反对 0

使用道具 举报

发表于 2019-9-19 14:07:51 | 显示全部楼层
干得漂亮。同学,请你把前面的作业也补一补
回复 支持 反对

使用道具 举报

发表于 2020-4-11 14:56:28 | 显示全部楼层
可是我试了一下它们之间 的结果互相影响 咋回事 (F103 ZET6)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-14 10:13:38 | 显示全部楼层
lxy1592762658 发表于 2020-4-11 14:56
可是我试了一下它们之间 的结果互相影响 咋回事 (F103 ZET6)

串口单独一路一路测的吗
回复 支持 反对

使用道具 举报

发表于 2021-4-10 17:47:11 | 显示全部楼层
漂亮,兄弟
回复

使用道具 举报

发表于 2021-8-30 16:25:19 | 显示全部楼层
lxy1592762658 发表于 2020-4-11 14:56
**** 作者被禁止或删除 内容自动屏蔽 ****

应该不会相互影响的,你仔细看看,楼主写的挺好的。仔细点
回复 支持 反对

使用道具 举报

发表于 2021-8-30 16:26:03 | 显示全部楼层
感谢楼主,写的真好
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-22 20:17 , Processed in 0.041314 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表