STM32的中断NVIC——C里面的所有调用都是久别重逢

我才发现,STM32的中断向量表(interrupt vector table)是不用配置的!!!

这和TI的芯片LM3S系列所用的函数库不一样,Ti的函数库都需要在启动文件startup.s中对中断向量表进行配置。具体操作是把中断服务函数的名字写到对应的汇编代码位置,名字就是中断服务函数的入口地址。一旦发生中断,则跳入到这个地址执行程序。

而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]。

##久别重逢## 像这种由STM或者TI官方库带来的向函数式编程的转化,写的程序过一段时间很快就忘记用法了。如果换一个平台又得重新熟悉。但万码虽殊,其理揆一。要知道,C语言的所用调用都是久别重逢。

##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/8306045

转载于:https://my.oschina.net/lvyi/blog/202384

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值