// 不爱用函数库, 又臭又长, 查个功能操作,有时要翻两三个文件一百几十行代码, 最重要是对芯片没感觉,像隔着媒人沟妹子 ~~
// 难道你们不觉得寄存器操作=逻辑直观+代码清晰, 特别在查错调试时, 贼爽贼爽的~~~
// 为毛寄存器操作这么少人用, 代码文章更少, 全网也没多少的样子~~
// 帮顶一个么~~
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");
}
STM32电压采集_ADC_DMA(详细寄存器代码)
猜你喜欢
转载自blog.csdn.net/zhouml_msn/article/details/90574497
今日推荐
周排行