STM32的中斷NVIC——C裏面的全部調用都是久別重逢

我才發現,STM32的中斷向量表(interrupt vector table)是不用配置的!!!html

這和TI的芯片LM3S系列所用的函數庫不同,Ti的函數庫都須要在啓動文件startup.s中對中斷向量表進行配置。具體操做是把中斷服務函數的名字寫到對應的彙編代碼位置,名字就是中斷服務函數的入口地址。一旦發生中斷,則跳入到這個地址執行程序。git

而STM32的邏輯是把中斷向量表裏全部的中斷服務子函數名字給定,你須要用到哪一個中斷時,把這個函數名取來用就行。若是須要了解一下STM32的啓動過程和中斷向量表的做用,能夠查看[1]。編程

##ADC單通道採樣 如今須要一個ADC採樣程序,在中斷中讀取採樣的數據。函數式編程

<!-- lang: cpp -->
#include "stm32f2xx.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h> 

extern void Uart2Init(void);
float f1;
uint32_t ADCVal = 0;  
static void ADC_Configuration(void)
{
	ADC_InitTypeDef ADC_InitStructure;
	ADC_CommonInitTypeDef ADC_CommonInitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	/* Enable ADC3 clock */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	
	/* Configure ADC3 Channel 3 as analog input */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	/* ADC Common Init */
	ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div6;
	ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
	ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; 
	ADC_CommonInit(&ADC_CommonInitStructure); 
	
	/* ADC3 Configuration ------------------------------------------------------*/
	ADC_StructInit(&ADC_InitStructure);
	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; 
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_NbrOfConversion = 1;
	ADC_Init(ADC3, &ADC_InitStructure);
	
	/*Interrupt Configuration*/
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	NVIC_InitStructure.NVIC_IRQChannel  = ADC_IRQn;         //ADC1,ADC2,ADC3的全局中斷
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//先佔優先級0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority   = 1;   //從優先級
    NVIC_InitStructure.NVIC_IRQChannelCmd   = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    ADC_ITConfig(ADC3, ADC_IT_EOC, ENABLE);
	
/* ADC3 Regular Channel Config */
	ADC_RegularChannelConfig(ADC3, ADC_Channel_3, 1, ADC_SampleTime_56Cycles);
	
	/* Enable ADC3 */
	ADC_Cmd(ADC3, ENABLE);
	
	/* ADC3 regular Software Start Conv */ 
	ADC_SoftwareStartConv(ADC3);
    }

    void AdcDelay(void)
   {
	unsigned int i;
	for(i = 0; i < 6000000; i++);
    }

    void ADC_IRQHandler(void)
   { 
    int Status;
    Status = ADC_GetITStatus(ADC3, ADC_IT_EOC);                 //檢查指定的ADC中斷是否發生
    if(Status ==SET){             //若是發生中斷
    ADC_ClearITPendingBit(ADC1, ADC_IT_EOC); //清除中斷標誌位
	//進行轉換處理
    ADCVal = ADC_GetConversionValue(ADC3);
	/* convert to Voltage,  step = 0.8 mV */
	ADCVal = (uint32_t)(ADCVal * 0.8);  
	/* get digits to display */
	f1 = (float)ADCVal / 1000.0;
	printf("ADC input volage:%.2fV\n",f1);
    }
}

		
int main(void)
{
	Uart2Init();
	ADC_Configuration();
	printf("\n\rTest ADC..........\n\r");
	while(1)
	{
		AdcDelay();
	}
 }

這個裏面的ADC_IRQHandler就是來自startup_stm32fxx.s。函數

##printf重定向## 在開發板上確定沒法使用stdio庫中printf,這裏可以使用是由於它被重定向爲UART輸出了。具體方法見 [2]。ui

##久別重逢## 像這種由STM或者TI官方庫帶來的向函數式編程的轉化,寫的程序過一段時間很快就忘記用法了。若是換一個平臺又得從新熟悉。但萬碼雖殊,其理揆一。要知道,C語言的所用調用都是久別重逢。.net

##Reference## [1].http://www.amobbs.com/thread-5462931-1-1.html [2].http://blog.csdn.net/jiangjingui2011/article/details/7216693 [3].http://blog.csdn.net/lanmanck/article/details/8306045code

相關文章
相關標籤/搜索