久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

stm32 AD模數(shù)轉(zhuǎn)換[操作寄存器+庫函數(shù)]-Changing's Blog

 杭州文軒 2014-11-27
stm32f103最少有2個AD模數(shù)轉(zhuǎn)換器,,每個ADC都有18個通道,,可以測量16個外部和2個內(nèi)部模擬量,。最大轉(zhuǎn)換頻率為1Mhz,也就是轉(zhuǎn)換時間為1us(在 ADCCLK = 14Mhz,采樣周期為1.5個時鐘周期時),。最大時鐘超過14Mhz,,將導(dǎo)致ADC轉(zhuǎn)換準(zhǔn)確度降低,。stm32的ADC是12位精度的,。
stm32的ADC轉(zhuǎn)換有兩種通道,規(guī)則通道和注入通道,,注入通道可以搶占式地打斷規(guī)則通道的采樣,,執(zhí)行注入通道采樣后,再執(zhí)行之前的規(guī)則通道采樣,,和中斷類似,。本例只使用規(guī)則通道實現(xiàn)獨立模式的中斷采樣,這里不再贅述兩種通道區(qū)別,。
stm32的ADC可以由外部事件觸發(fā)(例如定時器捕獲,,EXTI線)和軟件觸發(fā)(即在配置相關(guān)寄存器時,直接開啟采樣),。

本例實現(xiàn)AD采樣PB0口,,使用串口輸出PB0口電壓值,。PB0口接變阻器以改變調(diào)整電壓。
效果如下:
                                     ADValue = 1.39v
                                     ADValue = 1.38v
                                     ADValue = 1.40v
                                     ADValue = 1.38v
                                     ADValue = 1.39v

直接操作寄存器
首先需要配置ADC的時鐘分頻值,,在RCC->CFGR的[15:14]位:
  • 00:PCLK2 2分頻后作為ADC時鐘         01:PCLK2 4分頻后作為ADC時鐘
  • 10:PCLK2 6分頻后作為ADC時鐘         11:PCLK2 8分頻后作為ADC時鐘
設(shè)定各通道的采樣時間ADCx->SMPR,該寄存器給每個通道3位來選擇8種采樣周期:
  • 000:1.5周期               100:41.5周期
  • 001:7.5周期               101:55.5周期
  • 010:13.5周期             110:71.5周期
  • 011:28.5周期             111:239.5周期
采樣時間算法為: (采樣周期+12.5)/分頻后的時鐘
ADC采樣得到的只是一個相對值,,將 轉(zhuǎn)換值/4096*參考電壓 即可得到采樣電壓 這里的4096是因為stm32的adc為12位精度,表示參考電壓時即為 2^12=4096
代碼如下:  (system.h 和 stm32f10x_it.h 等相關(guān)代碼參照 stm32 直接操作寄存器開發(fā)環(huán)境配置
User/main.c
#include <stm32f10x_lib.h>	 
#include "system.h" 
#include "usart.h"
#include "adc.h" 
#include "stdio.h"	

#define LED1 PAout(4)
#define LED2 PAout(5)

#define VREF 3.3		 //參考電壓
void Gpio_Init(void);

int main(void)
{				  
	u16 ADValue;
	float temp;

	Rcc_Init(9); 			 //系統(tǒng)時鐘設(shè)置
	Usart1_Init(72,9600);	//設(shè)置串口時鐘和波特率

	Adc1_Init(8,7);	  //使用8通道采樣,,采樣時間系數(shù)為7(111),,據(jù)手冊可得采樣時間為 (239.5+12.5)/12= 21 (us)
	Gpio_Init();

	while(1){
	   	
		ADValue = Get_Adc(ADC_1,8);
		temp = (float)VREF*(ADValue/4096);	   //ADC精度為12位精度,即達(dá)到 VREF電壓時為 2^12 = 4096

		printf("\r\n ADValue = %.2fv\r\n",temp);

		LED2 = !LED2;

		delay(100000);   //延時100ms

	}		
}


void Gpio_Init(void)
{
	RCC->APB2ENR|=1<<2;    //使能PORTA時鐘 	
	RCC->APB2ENR|=1<<3;    //使能PORTB時鐘 	
	   	 	  

	GPIOA->CRL&=0xFF0FFFF0; 
	GPIOA->CRL|=0xFF3FFFF0; // PA0設(shè)置為模擬輸入,PA4推挽輸出

	GPIOB->CRL&=0xFFFFFFF0; 
	GPIOB->CRL|=0xFFFFFFF0; // PB0設(shè)置為模擬輸入

	
	//USART1 串口I/O設(shè)置

	GPIOA -> CRH&=0xFFFFF00F;   //設(shè)置USART1 的Tx(PA.9)為第二功能推挽,,50MHz,;Rx(PA.10)為浮空輸入
	GPIOA -> CRH|=0x000008B0;	  
}
Library/src/adc.c
#include <stm32f10x_lib.h>		 
#include "adc.h"


//ADC1采樣初始化
//獨立工作模式
//參數(shù)說明:
//			ADC_CH_x    選擇使用通道(0~17),目前暫支持0~15通道
//			ADC_CH_SMP 	設(shè)定采樣周期(0~7)
//采樣周期算法:

void Adc1_Init(u8 ADC_CH_x,u8 ADC_CH_SMP)
{
	RCC -> APB2ENR |= 1<<9;   		//開啟ADC1時鐘
	RCC -> APB2RSTR |= 1<<9;  		//復(fù)位ADC1
	RCC -> APB2RSTR &= ~(1<<9);  	//ADC1復(fù)位結(jié)束

	RCC -> CFGR &= ~(3<<14);		//分頻因子清零
	RCC -> CFGR |= 2<<14;			//設(shè)定分頻因數(shù)為2,PCLK2 6分頻后作為ADC時鐘

	ADC1 -> CR1 &= 0xF0FFFF;		//工作模式清零
	ADC1 ->	CR1 |= 0<<16;			//設(shè)定為獨立模式
	ADC1 -> CR1 &= ~(1<<8);			//非掃描工作模式
	ADC1 -> CR2 &= ~(1<<1);			//關(guān)閉連續(xù)轉(zhuǎn)換

	ADC1 -> CR2 &= ~(7<<17);		//清除規(guī)則通道啟動事件
	ADC1 -> CR2 |= 7<<17;			//設(shè)定規(guī)則通道啟動事件為軟件啟動(SWSTART)

	ADC1 -> CR2 |= 1<<20;			//使用外部事件觸發(fā) SWSTART
	ADC1 -> CR2 &= ~(1<<11);		//設(shè)置對齊模式為右對齊

	ADC1 -> SQR1 &= ~(0xF<<20);		//清零規(guī)則序列的數(shù)量
	ADC1 -> SQR1 |= 15<<20;			//設(shè)置規(guī)則序列的數(shù)量為16

	ADC1 -> SMPR2 &= 0x00000000;	//清零通道采樣時間
	ADC1 -> SMPR1 &= 0xFF000000;	

	if(ADC_CH_x <= 9 ){
		ADC1 -> SMPR2 |= 7<<(ADC_CH_x*3);			//設(shè)置通道x采樣時間,,提高采樣時間可以提高采樣精度 
	}

	if(ADC_CH_x > 9 ){
		ADC1 -> SMPR1 |= 7<<((ADC_CH_x-10)*3);		
	}
	

	ADC1 -> CR2 |= 1<<0;			//開啟AD轉(zhuǎn)換
	ADC1 -> CR2 |= 1<<3;			//使能復(fù)位校準(zhǔn),,由硬件清零
	while((ADC1 -> CR2)& (1<<3));	//等待校準(zhǔn)結(jié)束
	ADC1 -> CR2 |= 1<<2;			//開啟AD校準(zhǔn),由硬件清零
	while((ADC1 -> CR2)& (1<<2));	//等待校準(zhǔn)結(jié)束

}

//取得數(shù)模轉(zhuǎn)換的值
//參數(shù)說明:(參數(shù)定義于adc.h)
//		 ADC_x  (0~3),選擇數(shù)模轉(zhuǎn)換器
//		 ADC_CH_x    (0~15),選擇通道
u16 Get_Adc(u8 ADC_x,u8 ADC_CH_x)
{
	u16 data = 0;

	switch(ADC_x)	
	{
		case 1 : {

			ADC1 -> SQR3 &= 0xFFFFFFE0;	  		//清除通道選擇
			ADC1 -> SQR3 |= ADC_CH_x;				//選擇通道
			ADC1 -> CR2  |= 1<<22;				//開啟AD轉(zhuǎn)換
			while(!(ADC1 -> SR & 1<<1));			//等待轉(zhuǎn)換結(jié)束

			data = ADC1->DR;
			break;
		}
		case 2 : {break;}
		case 3 : {break;}
	}

	return data;
}
Library/inc/adc.h
#include <stm32f10x_lib.h>	

#define  ADC_1 0x01
#define  ADC_2 0x02
#define  ADC_3 0x03

void Adc1_Init(u8 ADC_CH_x,u8 ADC_CH_SMP);
u16 Get_Adc(u8 ADC_x,u8 ADC_CH_x);
庫函數(shù)操作
main.c
#include "stm32f10x.h"
#include "stdio.h"


#define	 PRINTF_ON  1
#define  VREF       3.3        // 參考電壓


void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);
void ADC_Configuration(void);


int main(void)
{
	float ADValue = 0.00;
	u32 delayTime = 0;

  	RCC_Configuration();
  	GPIO_Configuration();
	USART_Configuration();
	ADC_Configuration();

	while(1)
	{
		if(delayTime++ >=2000000)
		{
			delayTime = 0;
			ADValue = VREF*ADC_GetConversionValue(ADC1)/0x0fff;
			printf("\r\n ADValue = %.2fv\r\n",ADValue);
		
		}
	}
}

  
void GPIO_Configuration(void)
{
  	GPIO_InitTypeDef GPIO_InitStructure;                                                                                     
  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;			
  	GPIO_Init(GPIOA , &GPIO_InitStructure); 


  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;			
  	GPIO_Init(GPIOA , &GPIO_InitStructure); 

  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;			
  	GPIO_Init(GPIOA , &GPIO_InitStructure); 
}

void ADC_Configuration(void)
{
	ADC_InitTypeDef ADC_InitStructure;	

	RCC_ADCCLKConfig(RCC_PCLK2_Div4);	//配置ADC時鐘分頻

	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	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 = 1;
	ADC_Init(ADC1,&ADC_InitStructure);
	
	ADC_RegularChannelConfig(ADC1,ADC_Channel_8,1,ADC_SampleTime_55Cycles5);
	ADC_Cmd(ADC1,ENABLE);
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1));
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1));
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);


}


void RCC_Configuration(void)
{
	/* 定義枚舉類型變量 HSEStartUpStatus */
	ErrorStatus HSEStartUpStatus;

  	/* 復(fù)位系統(tǒng)時鐘設(shè)置*/
  	RCC_DeInit();
  	/* 開啟HSE*/
  	RCC_HSEConfig(RCC_HSE_ON);
  	/* 等待HSE起振并穩(wěn)定*/
  	HSEStartUpStatus = RCC_WaitForHSEStartUp();
	/* 判斷HSE起是否振成功,,是則進(jìn)入if()內(nèi)部 */
  	if(HSEStartUpStatus == SUCCESS)
  	{
    	/* 選擇HCLK(AHB)時鐘源為SYSCLK 1分頻 */
    	RCC_HCLKConfig(RCC_SYSCLK_Div1); 
    	/* 選擇PCLK2時鐘源為 HCLK(AHB) 1分頻 */
    	RCC_PCLK2Config(RCC_HCLK_Div1); 
    	/* 選擇PCLK1時鐘源為 HCLK(AHB) 2分頻 */
    	RCC_PCLK1Config(RCC_HCLK_Div2);
    	/* 設(shè)置FLASH延時周期數(shù)為2 */
    	FLASH_SetLatency(FLASH_Latency_2);
    	/* 使能FLASH預(yù)取緩存 */
    	FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    	/* 選擇鎖相環(huán)(PLL)時鐘源為HSE 1分頻,,倍頻數(shù)為9,則PLL輸出頻率為 8MHz * 9 = 72MHz */
    	RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
    	/* 使能PLL */ 
    	RCC_PLLCmd(ENABLE);
    	/* 等待PLL輸出穩(wěn)定 */
    	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    	/* 選擇SYSCLK時鐘源為PLL */
    	RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    	/* 等待PLL成為SYSCLK時鐘源 */
    	while(RCC_GetSYSCLKSource() != 0x08);
  	} 
  	/* 打開APB2總線上的GPIOA時鐘*/
  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOB|RCC_APB2Periph_ADC1, ENABLE);

	//RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
		
}

 
void USART_Configuration(void)
{
	USART_InitTypeDef USART_InitStructure;
	USART_ClockInitTypeDef USART_ClockInitStructure;

	USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
	USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
	USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;                                                                                                                                                      
	USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
	USART_ClockInit(USART1 , &USART_ClockInitStructure);

	USART_InitStructure.USART_BaudRate = 9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
	USART_Init(USART1,&USART_InitStructure);

 	USART_Cmd(USART1,ENABLE);
}


#if	 PRINTF_ON

int fputc(int ch,FILE *f)
{
	USART_SendData(USART1,(u8) ch);
	while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
	return ch;
}

#endif

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多