今天對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 <stm32f10x.h>
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 <stm32f10x.h>
#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 V\n",3.3*get_adc(1)/4096);
rs232_send_str(buff,strlen(buff));
delay_ms(1000);
}
}
~~~
ADC有的地方我還沒有搞的完全懂,愿意聽各位大神指點!

- 前言
- 【菜鳥入門】stm32的第一個程序--LED
- 【菜鳥入門】stm32 之 掃描按鍵
- 【菜鳥入門】stm32 之 中斷按鍵
- 【菜鳥入門】stm32 之 USART
- 【菜鳥入門】stm32 之 iic
- 【菜鳥入門】stm32 之 eeprom
- 【菜鳥入門】stm32 之 pwm
- 【菜鳥入門】stm32 之 ADC 模數轉換
- 【菜鳥入門】stm32 之 實時時鐘
- 【菜鳥入門】stm32 之 DMA
- 【菜鳥入門】stm32 之 DAC
- 【STM庫應用】stm32 之 USART
- 中斷源去抖辦法
- stm32 啟動代碼應用技巧
- 【STM庫應用】stm32 之 IIC應用
- 【STM庫應用】stm32 之 中斷按鍵初始化(注意事項)
- 關于結構體初始化
- 【STM庫應用】stm32 之 TIM (詳解一 通用定時器)
- 【STM庫應用】stm32 之 TIM (詳解二 脈沖寬度、周期測量)
- 【stm32庫應用】SD驅動移植(基于SDIO外設)
- SD卡fat文件系統移植
- stm32 DMA初始化選項研究
- stm32 靈活靜態存儲控制器(FSMC)(NORFLASH\PSRAM)
- 【stm32+uC/OS-II】ucosii移植簡單詳細步驟
- STM32 加入調試信息來調試代碼
- NRF24L01 無線通信模塊使用