我才發現,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