今天对ADC进行了研究,个人感觉,ADC的配置相对也对比较复杂一点,因为需要配置的寄存器是比较多的!
在datasheet 关于ADC的简介中,明确说明ADC的输入时钟不得超过14M,他是有PCLK2经过分频得来的
这次我们选用ADC1_IN0作为讲解的对象,ADC1_IN0 -->PA0
所以在配置时钟的时候要配置PA0和ADC1,关于怎么配置,已经说的很清楚了。
在配置PA0的输入模式方面我要说明一下,有好多人在这个地方还是很郁闷的
在8.1.11 外设GPIO的配置中每种配置都说的很清楚,如果我们对那中模式配置有疑问,我们都可以直接在这里查找
这里的ADC我们采用模拟输入模式:
所以我们这里需要把PA1配置为0000b
输入配置完成,在开头我已经强调过了,ADC的时钟不能超过14MHz,所以我们要对ADC的时钟进行些操作
RCC_CFGR这个寄存器找了我半天,我就感觉在RCC里面配置,但是一直找不到ADC的配置项,后来在网上找了半天,才知道ADC的频率配置在这里选择
我一般在配置系统时钟的时候喜欢配置为72MHz,即PCLK2 = 72MHz
所以为了满足我们的ADC,我们至少需要6分频,当然8分频也可以,好吧废话了一句。。
我们这里就6分频吧:RCC->CFGR &= ~(3<<14);RCC->CRGR |= 2<<14;
这里得到的ADC时钟为12MHz,时钟配置完成后,那我们就来专心配置ADC register了
当然,有经验的人,不用想,直接先找到控制寄存器(CR ,Control Register)
ADC的控制寄存器比较多,我刚开始看的比较郁闷,然后再李想老师的代码里面找了一段(因为最近比较忙,没有时间,所以喜欢搞定现成的代码研究下);当然大家也可以只要,只要你把别人的配置方法,配置原理学会了,也是很不错的,有时候我道觉得这是一种比较学习的快捷办法!这里给大家交流下学习经验
先看看ADCx_CR1
CR1寄存器大部分位是管理WATCH DOG的,我们一般不怎么用WATCH DOG,在430上我基本上没有用过看门狗,感觉这个狗不是很听话,我也不是很了解他,所以以后用到了再说吧。
首先是双模式选择
我们需要注意下:在ADC2和ADC3中这些位为保留的,所以以后我们再配置的时候注意下,还有下面的几行
这里我们用独立模式0000b,在此模式中,双ADC同步不工作,每个ADC接口独立工作;
关于模式大家可以看看11.9章
至今我还没有明白这个扫描模式时干嘛用的!谁会了,帮忙指点下,谢谢了。
关于CR2的配置相对比较多的!
我们这里不使用外部事件来启动转换,直接用软件来转换,所以20位我们要置0,从而在选择启动规则通道组转换的外部事件我们就只能用SWSTART(Software Start)
我们用的是ADC1,而且还关闭了外部启动转换,所以我们这里就选择111
为了保证数据数据的实时性,我们需要进行连续转换,我不知道李想老师为什么选用单次转换,不过也无所谓了。
然后为了保证读书的方便,我们可以把数据存储的时候进行右对齐;这样我们就不需要进行移位的操作了,直接读就ok 了。
关于SQR寄存器,规则序列寄存器,听着都纠结,我们只用一个通道,所以我们就二话不说的配置为0000b
通道的采样时间,我的观念是采样时间越长越精确,经过测试确实是这样
由于我们用的是CH1,所以我们呢就要配置SMPR的SMP1设置为111
这些配置完了,那我们就来启动ADC吧。
还是CR2,打开ADC,进行矫正复位,矫正。
完成后,就没有了,只剩下读数据了。
读数据我要说下:
我们要先配置我们要采样的通道,然后打开控制寄存器CR2上的开始转换 Start Conversion
注意检测状态寄存器里面的转换状态,转换结束,他会把EOC位置1
然后我们就可以读数据了;
现在附上代码,大家可以参考代码看看:
/* adc.c */
#include void adc1_init() { RCC->APB2ENR |= 1<<2; GPIOA->CRL &= ~(0xf<<0); GPIOA->CRL |= 0x0<<0; RCC->APB2ENR |= 1<<9; RCC->APB2RSTR |= 1<<9; RCC->APB2RSTR &= ~(1<<9); RCC->CFGR &= ~(3<<14); RCC->CFGR |= 2<<14; // 6 div PCLK2 / 6 = 12MHz ADC1->CR1 &= ~(0xf<<16); ADC1->CR1 |= 0<<16; //Set Indenpendence Mode ADC1->CR1 &= ~(1<<8); //Scan Mode Disable /* Config Control Register 2*/ ADC2->CR2 |= 1<<1; //Continuous conversion mode ADC1->CR2 &= ~(7<<17); //Clear ADC1->CR2 |= 7<<17; //software start ADC1->CR2 |= 1<<20; //Conversion on external event enable ADC1->CR2 &= ~(1<<11); //Right Alignment ADC1->SQR1 &= ~(0xf<<20); ADC1->SQR1 |= 0<<20; ADC1->SMPR2 &= ~(0x7<<3); ADC1->SMPR2 |= 7<<3; ADC1->CR2 |= 1<<0; //Start ADC to Calibration ADC1->CR2 |= 1<<3; while(ADC1->CR2 & 1<<3); ADC1->CR2 |= 1<<2; while(ADC1->CR2 & 1<<2); } unsigned short get_adc(unsigned char ch) { ADC1->SQR3 &= ~(0xf<<0); ADC1->SQR3 |= ch; ADC1->CR2 |= 1<<22; while(!(ADC1->SR & 1<<1)); return ADC1->DR; } 主函数:::: /* main.c */ #include #include "stdio.h" #include "init.h" #include "usart.h" #include "adc.h" int main() { char buff[256]; sys_init(9); rs232_init(CPU_72M,9600); rs232_send_byte('n'); adc1_init(); while(1) { sprintf(buff,"V:%.3f Vn",3.3*get_adc(1)/4096); rs232_send_str(buff,strlen(buff)); delay_ms(1000); } } ADC有的地方我还没有搞的完全懂,愿意听各位大神指点!
上一篇:【菜鸟入门】stm32 之 实时时钟
下一篇:【STM库应用】stm32 之 TIM (详解一 通用定时器)
推荐阅读最新更新时间:2024-11-05 16:23
设计资源 培训 开发板 精华推荐
- LTC3568EDD 演示板、4MHz、1.8A 同步降压稳压器
- DRV8701_MOTOR_DRIVER
- Razer地狱狂蛇原理图
- [测试通过] 18650 锂电池 露营灯 手电筒 台灯
- AM6TW-2407DH35Z ±7.2V 6 瓦双输出 DC/DC 转换器的典型应用
- 用于工业应用的 C8051F545 MCU 的 C8051F540DK、8051 开发系统
- 具有最大功率点跟踪功能的 LTC4162IUFD-FAD 太阳能供电 3 节 3.2A 充电器的典型应用
- IRAUDAMP21,使用 IR4321 的两通道 90W(2 欧姆)半桥 D 类音频功率放大器
- TS2007EIJT 3W 无滤波器 D 类音频功率放大器的典型应用,具有 6 或 12 dB 固定增益选择
- 使用 Analog Devices 的 LTC2992CDE 的参考设计