STM32电压采集_ADC_DMA(详细寄存器代码)

在这里插入图片描述

 // 不爱用函数库, 又臭又长, 查个功能操作,有时要翻两三个文件一百几十行代码, 最重要是对芯片没感觉,像隔着媒人沟妹子 ~~ 
 // 难道你们不觉得寄存器操作=逻辑直观+代码清晰, 特别在查错调试时, 贼爽贼爽的~~~
 // 为毛寄存器操作这么少人用, 代码文章更少, 全网也没多少的样子~~
 // 帮顶一个么~~ 
    u16 ADCVal[3];               // 结果存放数组, 应用时自行参考修改    [0] 通道7    [1]通道6     [2]芯片内温度        
    void ADC_Init(void)
    {
        // 1_GPIO
        GPIOA->MODER |=  0X3<<(2*7);  // PA7 模拟输入
        GPIOA->PUPDR &=~(0X3<<(2*7)); // 不上拉,不下拉
        GPIOA->MODER |=  0x3<<2*6;    // PA6 模拟输入
        GPIOA->PUPDR &=~(0x3<<2*6);                   
        // 2_DMA
        RCC->AHB1ENR |= 0x1<<22;              // 使能DMA2时钟  
        DMA2_Stream0 ->CR   = 0;              // EN    [0]     禁止数据流 ,才能写寄存器 
        DMA2_Stream0 ->PAR  = (u32)ADC1+0x4C; // 外设地址      ADC1->DR
        DMA2_Stream0 ->M0AR = (u32)ADCVal;    // 存储器地址    内部SDRAM的变量
        DMA2_Stream0 ->NDTR = 3;              // 一次传输数量      
        DMA2_Stream0 ->FCR  = 0x21;           // 复位值        FIFO所有配置失效    
          DMA2_Stream0 ->CR |= 0<< 6;         // DIR   [7:6]   传输方向       0_PtM, 1_Mtp, 2_MtM
          DMA2_Stream0 ->CR |= 1<< 8;         // CIRC  [8]     循环模式       0_禁止 1_使能
          DMA2_Stream0 ->CR |= 0<< 9;         // PINC  [9]     外设递增       0_外设地址指针固定  1_递增
          DMA2_Stream0 ->CR |= 1<<10;         // MINC  [10]    存储器递增     0_存储器指针固定    1_递增
          DMA2_Stream0 ->CR |= 1<<11;         // PSIZE [12:11] 外设数据大小   0_8位  1_16位  10_32位
          DMA2_Stream0 ->CR |= 1<<13;         // MSIZE [14:13] 存储器数据大小 0_8位  1_16位  10_32位
          DMA2_Stream0 ->CR |= 1<<16;         // PL    [17:16] 优先级         0_低 1_中 2_高 3_最高
          DMA2_Stream0 ->CR |= 0<<21;         // PBURST[22:21] 外设突发传输   0_单次 1_4节拍 2_8节拍 3_16节拍
          DMA2_Stream0 ->CR |= 0<<23;         // MBURST[24:23] 存储器突发传输 0_单次 1_4节拍 2_8节拍 3_16节拍
          DMA2_Stream0 ->CR |= 0<<25;         // CHSEL [27:25] 通道选择
          DMA2_Stream0 ->CR |= 1<<0;          // EN    [0]     使能数据流, 使能后DMA大部份寄存器都不能写
        // 3_ADC时钟使能
        RCC->APB2ENR  |=  0x1<<8;     // 使能 ADC1 时钟
        RCC->APB2RSTR |=  0x1<<8;     // ADCx复位
        RCC->APB2RSTR &=~(0x1<<8);    // 复位结束
        // 4_通用控制寄存器
        ADC->CCR   = 0;               // MULTI  [ 4: 0]   模式选择     0_独立模式        
        ADC->CCR  |= 0<<8;            // DELAY  [11: 8]   2 个采样阶段之间的延迟;这些位在双重或三重交错模式下使用 .
        ADC->CCR  |= 0<<13;           // DDS    [13]      DMA禁止选择  0_一次      1_[14]==1时,连续      (对于多个 ADC 模式)
        ADC->CCR  |= 0<<14;           // DMA    [15:14]   直接存储器访问模式       0_禁止DMA模式         (对于多个 ADC 模式)
        ADC->CCR  |= 1<<16;           // ADCPRE [17:16]   预分频器 ;ADCCLK=PCLK2/4=90/4=22.5Mhz,ADC时钟不要超过36Mhz
        ADC->CCR  |= 0<<22;           // Vbat   [22]      VBAT通道     0_关闭      1_使能                 [22] 和 [23] 同时使能时, [22]生效
        ADC->CCR  |= 1<<23;           // TSVREFE[23]      温度传感器   0_关闭      1_使能    ADC1_通道18  [22] 和 [23] 同时使能时, [22]生效
        // 5_ADC工作模式
        ADC1->CR1  = 0;               // 00000000
        ADC1->CR1 |= 1<<8 ;           // SCAN    [8 ]     扫描模式     0_禁止      1_使能(多通道时用)       
        ADC1->CR1 |= 0<<24;           // RES     [25:24]  分辨率       0_12位      
        ADC1->CR2  = 0;               // 00000000
        ADC1->CR2 |= 1<<1 ;           // CONT    [1]      连续转换     0_单次      1_连续    
        ADC1->CR2 |= 1<<8;            // DMA     [8]      直接内存存取 0_禁止DMA   1_使用DMA                               (对于单一 ADC 模式)
        ADC1->CR2 |= 1<<9 ;           // DDS     [9]      连续DMA请求  0_只一次    1_只要发生数据转换且 DMA = 1,便发出请求 (对于单一 ADC 模式)
        ADC1->CR2 |= 0<<11;           // ALIGN   [11]     数据对齐     0_右对齐
        ADC1->CR2 |= 0<<24;           // EXTSEL  [27:24]  触发时件     [29:28]==0  本寄存器无效,随便                        (规则通道)
        ADC1->CR2 |= 0<<28;           // EXTEN   [29:28]  外部触发使能 0_禁止      1_上升沿    2_下降沿     3_上升下降      (规则通道)
        // 6_采样时间/规则次序
        ADC1->SMPR1  = 0;             // 清零   [0:0:0]   SMPR1:18-10 , SMPR2:9-0  
        ADC1->SMPR1 |= 5<<(3*(18-10));// 通道18           内部温度
        ADC1->SMPR2  = 0;             // 清零   [0:0:0]   SMPR1:18-10 , SMPR2:9-0        
        ADC1->SMPR2 |= 5<<3*7;        // 采样时间         0_3个周期   1_15   2_28   3_56   4_84   5_112   6_144  7_480
        ADC1->SMPR2 |= 5<<3*6;        // 111:480 个周期      
        
        ADC1->SQR1   = 0;             // 清零  [0:0:0:0:0]
        ADC1->SQR1  |= 2<<20;         // L     [23:20]   转换总数, x+1 个转换在规则序列中
        ADC1->SQR3   = 0;             // 清零  SQR1:第16~13个 , SQR2:第12~7个 , SQR3:第6~1个
        ADC1->SQR3  |= 7<<(5*0);      // 序列1 = ch7
        ADC1->SQR3  |= 6<<(5*1);      // 序列2 = ch6  
        ADC1->SQR3  |= 18<<(5*2);     // 序列3 = ch18
        // 7_开始转换
        ADC1->CR2 |= 0x1<<0;          // 使能 ADC 
        ADC1->CR2 |= 0x1<<30;         // 开始 AD转换         
        printf("ADC     配置完成\n");
    }

猜你喜欢

转载自blog.csdn.net/zhouml_msn/article/details/90574497
今日推荐