资讯详情

STM32F103R8T6的定时器使用问题

现在在做一个定时器的测试程序,要用定时器2定时1秒,中断中翻转IO口,改变指示灯状态。以下是我的程序:

#define ENCODER_TIM_PERIOD (u16) 13999

#define TIMx_ChannelTIM2_IRQn

#define TIMx_PRE_EMPTION_PRIORITY 0

#define TIMx_SUB_PRIORITY 1

///

//u8 Port[1];//PCA9554D的端口

u8 act[5][10]A,B,C,共补电容器投切状态。

u8 counter;//计数变量用于临时程序试验。

GPIO_InitTypeDef GPIO_InitStructure;

/* Private function prototypes -----------------------------------------------*/

void Switch_Twel(u8 flag );//正负12V转换和关闭输出电压prototypes

u8 Relay_Drive(u8 X,u8 Z);

void Relay_ALL_Leave(void);///切断所有电容器。

/

/* Private functions ---------------------------------------------------------*/

void Delay100ms(void)

{

u32 cnt=0x00020000;

while(cnt--);//延时105ms

}

void GPIO_Ini(void)

{

/* GPIOA/GPIOB Periph clock enable */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);

// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

__NOP();

/* Configure PA8,PA0 ,PA12 in output pushpull mode *////指示灯控制

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_0|GPIO_Pin_12;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOA, &GPIO_InitStructure);

__NOP();

/* Configure PB11,PB10 in output pushpull mode ,正负12V的电源转换

*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_10;

//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_10;//positive and negive 12voltage output

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOB, &GPIO_InitStructure);

__NOP();

GPIO_ResetBits(GPIOA,GPIO_Pin_12);//双向可控硅的所有驱动输入均为低电平。

GPIO_SetBits(GPIOA,GPIO_Pin_8);//关闭指示灯。

}

void timer2_Init(void)

{

TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;

NVIC_InitTypeDef NVIC_InitStructure;

/* TIM2clock source enable */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

NVIC_InitStructure.NVIC_IRQChannel = TIMx_Channel;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

/* Timer configuration in Encoder mode */

TIM_DeInit(TIM2);

TIM_TimeBaseStructure.TIM_Prescaler = 1999;// APB2=72M 72M/(71 1)=1M

TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD;//count 100 reset to 0

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit(TIM2 , &TIM_TimeBaseStructure);

//使能预装载

TIM_ARRPreloadConfig(TIM2, ENABLE);

//TIM_GenerateEvent(TIM1, TIM_EventSource_Update);

// Clear all pending interrupts

TIM_ClearFlag(TIM2 , TIM_FLAG_Update);

TIM_ClearITPendingBit(TIM2 , TIM_IT_Update);

//enable interrupt

TIM_ITConfig(TIM2 , TIM_IT_Update, ENABLE);

//TIM_Cmd(TIM1, ENABLE);

TIM_Cmd(TIM2,ENABLE);

//TIM_CtrlPWMOutputs(TIM1, ENABLE);

}

int main(void)

{

/*!< At this stage the microcontroller clock setting is already configured,

this is done through SystemInit() function which is called from startup

file (startup_stm32f10x_xx.s) before to branch to application main.

To reconfigure the default setting of SystemInit() function, refer to

system_stm32f10x.c file

*/

SystemInit(); // 使用外部8MHZ的晶振,系统时钟改为56MHZ,高速外围56,低俗28MHZ。

GPIO_Ini();

//I2C_EE_Init();

//PCA9554D_Init();//initialize the PCA9554D as the output ,and all output hign level.

timer2_Init();

//u32 cnt=0x0009ffff;

while (1)

{;}

}

现在的问题是,一旦操作程序进入中断文件中的硬件错误部分:

void HardFault_Handler(void)

{

__IO u32 ReturnAddr;

ReturnAddr = __get_MSP();

ReturnAddr = *(u32 *)(ReturnAddr 32);

/* Go to infinite loop when Hard Fault exception occurs */

while (1)

{

}

}

p>单步执行,发现在timer2_Init();里面执行TIM_Cmd(TIM2,ENABLE);之后,在

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)

{

/* Check the parameters */

assert_param(IS_TIM_ALL_PERIPH(TIMx));

assert_param(IS_FUNCTIONAL_STATE(NewState));

if (NewState != DISABLE)

{

/* Enable the TIM Counter */

TIMx->CR1 |= TIM_CR1_CEN;  }

else

{

/* Disable the TIM Counter */

TIMx->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN));

}

}

当返回主程序的时候出错。不知道是为什么。

我是刚开始学习STM32F103R8T6,也是第一次接触STM单片机。希望版主、做过的朋友,帮我找找问题,看看怎么回事。十分感谢!

void TIM2_IRQHandler(void)

{

if(TIM_GetFlagStatus(TIM2,TIM_IT_Update)!=RESET)

{

// __NOP();

// GPIO_ResetBits(GPIOA,GPIO_Pin_8);

//GPIOA->BRR  = 0x00000100;

// __NOP();

//IO翻转

GPIO_WriteBit(GPIOA,GPIO_Pin_8,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_8)));

//Clear the interrupt pending flag

// TIM_ClearFlag(TIM2, TIM_FLAG_Update);

// TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

TIM_ClearFlag(TIM2 , TIM_FLAG_Update);

TIM_ClearITPendingBit(TIM2 , TIM_IT_Update);

}

}

上面是我的定时器2的定时1S中断程序,但是根本就没有被执行。

昨天下午测试的时候(之前已经发现问题出在定时器2上,使能之后就出硬件故障的错误),在下载仿真里,直接GO,发现程序还能运行一小会。

网上查找资料,看CM3的权威指南,有以下几种说法:

1,数组访问越界;

2,非法硬件操作;

解决方法有以下几种:

A,断掉仿真器给目标板供电的;

B,加大堆栈空间的;

C,调整优先级的;

D,添加.S启动文件;

E,初始化之前,要先关闭全局总中断,初始化之后,再打开。

要说明的是,我的仿真器是STM32F051的探索套件上自带的STLINK仿真器,没有给目标板供电,因此A不成立;

加大堆栈空间我测试过了,没有效果,并且看RAM空间和.MAP文件,显示堆栈空间使用地址是0-4,没有超出范围;

第三个,我的程序里面只有一个中断,没有优先级的问题冲突;

第四个,我确实没有添加。s文件,但是我认为这个。s文件是自动调用的,理由是在不初始化定时器2时,其他的程序可以正常执行;

第五个,这个有点可能,可能是我没有使能全局中断,但是这个还没找到在哪里,我再去查查看看。但是看库里自带的例程,里面同样没有打开全局中断这句话。所以说只是可能。

补充一下,我仿真调试之后,在RAM的堆栈空间里面,看到要执行的语句地址是

0x20000A74,里面是值也是这个值;这个地址附近有个值是0x00000001;SR值为正常,但是LR却指向0xFFFFFFF1.

补充:我的向量表在系统初始化里面,映射到了0x08000000FLASH之后。

请遇到过相同问题或由类似解决经验的大虾帮帮我这个初学者,十分感谢!

标签: 1r8电容

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台