打印

30岁自学单片机,定时器中断进不了,跪求指点!!!!!

[复制链接]
1948|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
                                           /**********************************************************
* 文件名         : 流水灯.c
* 作者           :
* 版本号         : V1.0
* 日期           :
* 功能                         :用定时器中断实现开发板上的4个LED按顺序每隔1S打开一个,第5S全部熄灭,循环。
                   然后按下K1程序停止,蜂鸣器滴一声,再按下K1程序继续执行。
                                   按下K2全灭,再按下K2全亮。
***********************************************************/

#include "stm32f10x.h"



/* LED1 -> PB8        ,        LED2 -> PB9 , LED3 -> PE0 , LED4 -> PE1*/
#define LED1_OFF GPIO_SetBits(GPIOB , GPIO_Pin_8);
#define LED1_ON GPIO_ResetBits(GPIOB , GPIO_Pin_8);
#define LED2_OFF GPIO_SetBits(GPIOB , GPIO_Pin_9);
#define LED2_ON GPIO_ResetBits(GPIOB , GPIO_Pin_9);
#define LED3_OFF GPIO_SetBits(GPIOE , GPIO_Pin_0);
#define LED3_ON GPIO_ResetBits(GPIOE , GPIO_Pin_0);
#define LED4_OFF GPIO_SetBits(GPIOE , GPIO_Pin_1);
#define LED4_ON GPIO_ResetBits(GPIOE , GPIO_Pin_1);

void GPIO_Config(void);        //定义端口配置函数
void RCC_Configuration(void); //定义时钟配置函数
void Timer_Comfig(void); //定义定时器配置函数
void EXTI_Config(void);
void NVIC_Config(void);        //嵌套中断配置函数
void TIM2_IRQHandler(void);//定义定时器中断服务函数

unsigned char i=0;

void delay_ms(u16 nms) //滴答定时器非中断方式延迟nms函数
{
u32 temp;
SysTick->LOAD = 9000*nms;
SysTick->VAL=0X00;//清空计数器
SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
do
{
temp=SysTick->CTRL;//读取当前倒计数值
}
while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
SysTick->CTRL=0x00; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}

/*************************************************
函数: void RCC_Configuration(void)
功能: 复位和时钟控制配置
参数: 无
返回: 无
**************************************************/

void RCC_Configuration(void)
{
    ErrorStatus HSEStartUpStatus;        //定义外部高速晶体启动状态枚举变量
    /* RCC system reset(for debug purpose) */
    RCC_DeInit();        //复位外设RCC寄存器重设为缺省值

    /* Enable HSE */
    RCC_HSEConfig(RCC_HSE_ON); //打开外部高速晶振

    /* Wait till HSE is ready */
    HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待HSE起振

    if(HSEStartUpStatus == SUCCESS) //外部高速时钟已经准备好
    {
        /* Enable Prefetch Buffer */
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //使能预取指缓存
        //开启FLASH预读缓冲功能,加速FLASH的读取。所有程序中必须的用法.位置:RCC初始化子函数里面,时钟起振之后

        /* Flash 2 wait state */
        FLASH_SetLatency(FLASH_Latency_2);          //flash操作的延时,设置代码延时值为2个延时周期

        /* HCLK = SYSCLK */
        RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置AHB时钟(HCLK)等于系统时钟

        /* PCLK2 = HCLK */
        RCC_PCLK2Config(RCC_HCLK_Div1); //设置高速AHB时钟(PCLK2)APB2时钟等于HCLK ,即72MHZ

        /* PCLK1 = HCLK/2 */
        RCC_PCLK1Config(RCC_HCLK_Div2);        //设置低俗AHB时钟(PCLK1) APB1时钟等于HCLK/2,即36MHZ,因为有手册知APB1时钟最大不超过36MHZ

        /* PLLCLK = 8MHz * 9 = 72 MHz */
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //设置PLL输入时钟等于HSE时钟频率
        //设置PLL的倍频系数为PLL输入时钟X9        ,即HSE*9=8MHZ*9=72MHZ
        /* Enable PLL */
        RCC_PLLCmd(ENABLE);        //使能锁相环

        /* Wait till PLL is ready */
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)         //检查指定的RCC标志位设置与否
        {
        }

        /* Select PLL as system clock source */
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //设置PLL作为系统时钟

        /* Wait till PLL is used as system clock source */
        while(RCC_GetSYSCLKSource() != 0x08)  //返回用作系统时钟的时钟源 0X08代表PLL作为系统时钟
        {
        }
    }
}

/*************************************************
函数: void Timer_Config(void)
功能: 定时器配置
参数: 无
返回: 无
**************************************************/

void Timer_Config(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;//定义TIM_TimeBaseStructure结构体类型
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE); //使能定时器的时钟

    TIM_DeInit(TIM2); //用于复位TIM2定时器,使之进入初始状态


    TIM_TimeBaseStructure.TIM_Period=2000;                                                         //自动重装载寄存器周期的值(计数值)
    //累计 TIM_Period个频率后产生一个更新或者中断
    TIM_TimeBaseStructure.TIM_Prescaler= (36000 - 1);                                //时钟预分频数   例如:时钟频率=72MHZ/(时钟预分频+1)
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;                         //采样分频
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;                 //向上计数模式

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);         //        把 TIM_TimeBaseInitStruct 中的每一个参数按缺省值填入
    TIM_ClearFlag(TIM2, TIM_FLAG_Update);                                                        //清除溢出中断标志
    //TIM_PrescalerConfig(TIM2,0x8C9F,TIM_PSCReloadMode_Immediate);        //时钟分频系数36000,所以定时器时钟为2K
    //TIM_ARRPreloadConfig(TIM2, DISABLE);                                                        //禁止ARR预装载缓冲器
    TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //使能TIM2中断

    TIM_Cmd(TIM2, ENABLE);                                                                                        //开启时钟

}

/*************************************************
函数: voidEXTI_Config(void)
功能: 中断配置
参数: 无
返回: 无
**************************************************/

void EXTI_Config(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2); // 选择GPIO管脚PE2用作外部中断线路2
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);// 选择GPIO管脚PE3用作外部中断线路3
EXTI_ClearITPendingBit(EXTI_Line3);        //清除中断线3的中断标志位
EXTI_ClearITPendingBit(EXTI_Line2);        //清除中断线2的中断标志位
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//设置EXTI线路为中断请求模式
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising; //设置输入线路上升沿为中断请求
EXTI_InitStructure.EXTI_Line=EXTI_Line2| EXTI_Line3;  //选择待使能或者失能的外部线路为中断线2和3
EXTI_InitStructure.EXTI_LineCmd=ENABLE;         //定义选中线路状态为使能状态
EXTI_Init(&EXTI_InitStructure);        //根据EXTI_InitStruct 中指定的参数初始化外设 EXTI寄存器
}




/*************************************************
函数: void NVIC_Config(void)
功能: 嵌套中断配置
参数: 无
返回: 无
**************************************************/


void NVIC_Config(void)//嵌套中断配置
{

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel=EXTI2_IRQn; //选择外部中断线2 中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//主优先级占0位
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; //次优先级占0位
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能选中的中断通道
NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct 中指定的参数初始化外设 NVIC寄存器

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel=EXTI3_IRQn; //选择外部中断线3 中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//主优先级占1位
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; //次优先级占1位
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能选中的中断通道
NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct 中指定的参数初始化外设 NVIC寄存器


NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);         //选择优先级组2,先占优先级2 位 ,从优先级2 位      
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;   //选择TIM2全局中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//主优先级占2位
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;   //次优先级占2位
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能选中的中断通道
NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct 中指定的参数初始化外设 NVIC寄存器
               
}



/*************************************************
函数: void TIM2_IRQHandler(void)
功能: 定时器中断服务函数
参数: 无
返回: 无
**************************************************/

void TIM2_IRQHandler(void)
{
    if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET )         //查询TIM2中断源的中断是否到来
    {
        TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);   //清除 TIM2 的中断待处理位
        i++;
        if(i>5) i=0;
    }
}


/*******************************************************************************
* Function Name  : EXTI2_IRQHandler
* Description    : This function handles External interrupt Line 2 request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/


void EXTI2_IRQHandler(void)
{

unsigned char a=1;        //定义按键次数并赋初值
if(EXTI_GetITStatus(EXTI_Line2)!=RESET)
{
EXTI_ClearITPendingBit(EXTI_Line2);
if(a==1)
{
a++;
GPIO_ResetBits(GPIOB , GPIO_Pin_0);         //蜂鸣器动作
delay_ms(10);
GPIO_SetBits(GPIOB , GPIO_Pin_0);
while(1);
}
if(a==2)
{
delay_ms(10);
a=0;
}
}
}


/*******************************************************************************
* Function Name  : EXTI3_IRQHandler
* Description    : This function handles External interrupt Line 3 request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void EXTI3_IRQHandler(void)
{
unsigned char b=1;
if(EXTI_GetITStatus(EXTI_Line3)!=RESET)
{
EXTI_ClearITPendingBit(EXTI_Line3);

if(b==1)
{  
delay_ms(10);
b++;
LED1_OFF;
            LED2_OFF;
            LED3_OFF;
            LED4_OFF;
                        while(1);
}
if(b==2)
{
b=0;
LED1_ON;
            LED2_ON;
            LED3_ON;
            LED4_ON;
                        while(1);

}

}
}


/*************************************************
函数: void GPIO_Configuration(void)
功能: GPIO配置
参数: 无
返回: 无
**************************************************/

void GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure; //声明结构 初始化结构

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |
                           RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE); //设置外设前调用该函数使能它的时钟

//         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    /* LED1 -> PB8        ,        LED2 -> PB9 , LED3 -> PE0 , LED4 -> PE1*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 |GPIO_Pin_9;        //给引脚PIN赋值
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //最高输出速度为50MHz
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
    GPIO_Init(GPIOB, &GPIO_InitStructure); //调用该函数初始化外设GPIO

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOE, &GPIO_InitStructure);
}


/*************************************************
函数: int main(void)
功能: main主函数
参数: 无
返回: 无
**************************************************/

int main(void)
{
    SystemInit(); //初始化整个系统
    Timer_Config();
   EXTI_Config();
    GPIO_Config();
   NVIC_Config();

    LED1_OFF;
    LED2_OFF;
    LED3_OFF;
    LED4_OFF;
    while (1)
    {
         switch(i)
        {
        case 1:
            LED1_ON;
            break;
        case 2:
            LED2_ON;
            break;
        case 3:
            LED3_ON;
            break;
        case 4:
            LED4_ON;
            break;
        case 5:
            LED1_OFF;
            LED2_OFF;
            LED3_OFF;
            LED4_OFF;
            break;
        default:
            break;
        }
    }
}







相关帖子

沙发
阿南| | 2013-5-26 17:34 | 只看该作者
先把程序简化来测试中断,会容易发现问题些。

使用特权

评论回复
板凳
huangxz| | 2013-5-26 17:53 | 只看该作者
TIM_DeInit(TIM2); //用于复位TIM2定时器,使之进入初始状态 去掉试试

使用特权

评论回复
地板
huangxz| | 2013-5-26 23:24 | 只看该作者
可以进,没问题 啊

使用特权

评论回复
5
arm_debug_yj| | 2013-5-29 13:05 | 只看该作者
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2); // 选择GPIO管脚PE2用作外部中断线路2
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);// 选择GPIO管脚PE3用作外部中断线路3
GPIOE的P2,P3在GPIO_Config函数中没有配置成输入的属性

使用特权

评论回复
6
@渐行渐远@| | 2013-5-29 23:34 | 只看该作者
可以串口打印一下,检查哪里出的问题!

使用特权

评论回复
7
jy02326166| | 2013-5-31 00:05 | 只看该作者
STM32啊~

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

0

粉丝