你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F105RB 通用定时器无法进入中断服务程序,急求帮助

[复制链接]
jczhou 提问时间:2018-12-7 20:51 /
STM32F105RB 通用定时器无法进入中断服务程序,一运行就进入HardFault_Handler<p>中断。第一次用STM32,这问题搞了两天没解决,求帮助!!
用TIM2做定时中断,代码如下:
/*STM32F105R8*/
#include "stm32f10x.h"
//#include "stm32f10x_it.c"

void NVIC_TIM2Configuration(void);
void TIM2_IRQHandler(void);


struct ADC
{
  uint16_t I_AD;
  uint16_t V_AD;
  uint16_t AD13;
  uint16_t RDXI;
}AD_C[400];


unsigned long int CNT,MM;
struct ADC *Pointor;
int main(void)
{
   //void NVIC_TIM3Configuration(void);
   //NVIC_TIM3Configuration();
   /****系统时钟*****/
   CNT=2000;
   while(CNT--);
   (RCC->CR) = (RCC->CR) | RCC_CR_HSEON;//使能外部振荡器
   CNT=2000;
   while(CNT--);  
   while(!((RCC->CR) & RCC_CR_HSERDY));//确认外部时钟
   (RCC->CFGR) = 0x0413640A;//PLL输出作为系统时钟;(AHB)SYSCLK不分频 ;(低速APB1)HCLK 2分频(输出24M);
                            //高速(APB2) 2分频(24M);ADC4分频(12M);HSE时钟作为PLL输入时钟,PLL输出72M
   (RCC->CFGR2) = 0x00000001;//PREDIV1对输入时钟2分频;HSE振荡器时钟作为PREDIV1的时钟源;
   (RCC->CR) = (RCC->CR) | RCC_CR_PLLON;//使能PLL
   CNT=2000;
   while(CNT--);
   while(!((RCC->CR) & RCC_CR_PLLRDY));//确认
   
   
   (RCC->CR) = (RCC->CR) & ~RCC_CR_HSION;//关闭HSI
   
    /****GPIO端口设置*****/
   (RCC->APB2ENR) = 0x0000003C;//端口A,B,C,D时钟使能
   (GPIOC->CRL) = (GPIOC->CRL) & 0xffff0000;//PC0,PC1,PC2,PC3设为(ADC12)模拟输入
   (GPIOA->CRL) = 0x4B444B33;//PA0,PA1设为通用推挽输出,PA2,PA6设为复用推挽输出,PA3复用输入   
   (GPIOA->CRH) = 0x44444434;
   (GPIOB->CRH) = 0x444444B4;
   
   //(GPIOA->ODR) |= 0X0200;//PA9置1
   
   NVIC_TIM2Configuration();   
   /****系统中断配置*****/
   /* NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
    SCB->AIRCR = 0x05FA0200;//采用中断分组模式2
    NVIC->ISER[0] |= 1<<TIM2_IRQn;//开启TIM2中断
    NVIC->IP[TIM2_IRQn] = 0x5 << ((TIM2_IRQn % 4)*8 + 4);//抢占优先级2,响应优先级2
   */
   //NVIC_SETPRIMASK();                       // Disable Interrupts  
   //NVIC_RESETPRIMASK();                     // Enable Interrupts
   
   /****TIM3产生500K输出信号*****/
   RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;//TIM3时钟开启
   TIM3->ARR=95;//设定计数器自动重装值
   TIM3->PSC=0;//不预分频
   TIM3->CCMR1|=6<<4;//CH1 PWM1模式
   TIM3->CCMR1|=1<<3;//CH1 预装载使能
   TIM3->CR1|=1<<4;//向下计数模式
   TIM3->CCER|=3<<0;//OC1输出使能
   TIM3->CCR1=47;//设定占空比50%
   TIM3->EGR|=1<<0;//初始化计数器
   TIM3->CR1|=1<<7;//ARPE使能 自动重装载预装载允许位
   TIM3->CR1|=1<<0;//使能定时器TIM3  
   //TIM3->DIER |= 0x0002;//TIM3_DIER_CC1IE;
   TIM3->SR = 0x0000;


   /****TIM4产生500uS定时*****/
   RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; //TIM4时钟开启  
   TIM4->ARR=6000;//设定计数器自动重装值
   TIM4->PSC=0;//不预分频
   TIM4->CCMR2|=3<<12;//CH4翻转模式
   TIM4->CCMR2|=1<<11;//CH4预装载使能
   TIM4->CR1|=1<<4;//向下计数模式
   TIM4->CCER|=3<<12;//OC4输出使能
   TIM4->CCR4=3000;//设定占空比50%
   //TIM4->DIER |= TIM_DIER_UIE;//允许TIM4中断更新
   TIM4->EGR|=1<<0;//初始化计数器
   TIM4->CR1|=1<<7;//ARPE使能 自动重装载预装载允许位
   TIM4->CR1|=1<<0;//使能定时器TIM4     
   TIM4->SR = 0x0000;
   
   
   /****TIM2定时*****/
   RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; //TIM2时钟开启  
   TIM2->ARR=950;//设定计数器自动重装值
   TIM2->PSC=0;//不预分频
   TIM2->CCMR1|=3<<4;//CH1翻转模式
   TIM2->CCMR1|=1<<3;//CH1预装载使能
   TIM2->CR1|=1<<4;//向下计数模式
   TIM2->CCER|=3<<0;//OC1输出使能
   TIM2->CCR1=475;//设定占空比50%
   //TIM2->DIER |= TIM_DIER_CC1IE;//允许捕获/比较1中断
   TIM2->DIER |= TIM_DIER_UIE;//允许TIM2中断更新
   //TIM2->EGR|=1<<0;//初始化计数器
   TIM2->SR = 0x0000;   
   TIM2->CR1|=1<<7;//ARPE使能 自动重装载预装载允许位
   TIM2->CR1|=1<<0;//TIM_CR1_CEN使能定时器TIM2     
   
   /****ADC设置*****/
   RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;//ADC1时钟开启
   ADC1->CR1 |= ADC_CR1_SCAN;//开启ADC1扫描模式
   //ADC1->CR2 |= ADC_CR2_TSVREFE;//启用温度传感器和VREFINT
   ADC1->CR2 |= ADC_CR2_EXTTRIG;//使用外部事件启动转换
   ADC1->CR2 = (ADC1->CR2 & ~ADC_CR2_EXTSEL) | 0X000A0000;//TIM4的CC4事件启动规则转换
   ADC1->CR2 |= ADC_CR2_DMA;//使用DMA
   ADC1->CR2 |= ADC_CR2_RSTCAL;//初始化校准寄存器
   ADC1->CR2 |= ADC_CR2_ADON;//把ADC从断电模式下唤醒(第一次写入“1”)
   ADC1->SQR1 |= 3<<20;//扫描转换4个规则通道
   ADC1->SQR3 = 11 | 12<<5 | 13<<10 | 10<<15;//ADC序列AD11,AD12,AD13,AD10
   ADC1->CR2 |= ADC_CR2_ADON;//启动转换
   ADC1->CR2 |= ADC_CR2_RSTCAL;//开启复位校准
   while(ADC1->CR2 & ADC_CR2_RSTCAL);//等待复位校准结束
   ADC1->CR2 |= ADC_CR2_CAL;//开AD位校准
   while(ADC1->CR2 & ADC_CR2_CAL);//等待AD校准结束
   
   
   /****DMA设置*****/
   RCC->AHBENR  |= RCC_AHBENR_DMA1EN;//DMA1时钟开启
   DMA1_Channel1->CCR |= 1<<12; //PL 通道优先级中
   DMA1_Channel1->CCR |= 1<<10; //MSIZE存储器数据宽度16位
   DMA1_Channel1->CCR |= 1<<8; //PSIZE外设数据宽度16位
   DMA1_Channel1->CCR |= 1<<7; //MINC执行存储器地址增量操作
   DMA1_Channel1->CCR |= 1<<5; //CURC执行循环操作
   DMA1_Channel1->CNDTR = 1600; //传输数量
   DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR;//外设地址
   DMA1_Channel1->CMAR = (uint32_t)&AD_C;//存储器起始地址
   DMA1_Channel1->CCR |= DMA_CCR1_EN;//开启DMA




   while(1)
   {
     //if(TIM3->SR & 0x0002) TIM3_IRQHandler();
   }
}


void TIM2_IRQHandler(void)
{
  TIM2->SR &= 0xFFFE; //清中断标志
  (GPIOA->ODR) ^= 0X0200;
  //while(1);
}


void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}


void NVIC_TIM2Configuration(void)//配置TIM2的优先级
{
        NVIC_InitTypeDef  NVIC_InitStructure;
        
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;


        NVIC_Init(&NVIC_InitStructure);
}

评分

参与人数 1 ST金币 +20 收起 理由
STMCU + 20

查看全部评分

收藏 评论7 发布时间:2018-12-7 20:51

举报

7个回答
tanic 回答时间:2018-12-10 11:17:52
直接把你的工程传上,这样贴代码很难看,太基础而且有需要很长的字才能说明白的一般不会有人回答。
一般都只能给你提供思路,解决问题还得靠自己。
13.png
答新手.jpg
wenyangzeng 回答时间:2018-12-8 11:10:53
本帖最后由 wenyangzeng 于 2018-12-8 11:46 编辑

楼主为何定义那个AD_C[400]数组结构,足足占用RAM12800字节的长度了,有必要设那么多吗?是否因此出现RAM溢出。

评分

参与人数 1ST金币 +4 蝴蝶豆 +2 收起 理由
STMCU + 4 + 2

查看全部评分

shenxiaolin_mai 回答时间:2018-12-10 09:27:19
你的定时器4的中断处理函数呢?如果开启了中断,但是没有中断处理函数是会进hardfult-err的

评分

参与人数 1ST金币 +4 蝴蝶豆 +2 收起 理由
STMCU + 4 + 2

查看全部评分

qunda 回答时间:2018-12-10 10:35:51
本帖最后由 qunda 于 2018-12-10 10:46 编辑

AD_C[400];是局部变量,进入中断时候这数组会进行压栈,可能会超过你的设置的堆栈, 不如把AD_C[400];定义成全局变量。

评分

参与人数 1ST金币 +3 蝴蝶豆 +2 收起 理由
STMCU + 3 + 2

查看全部评分

watershade 回答时间:2018-12-10 10:46:20
已经被代码绕晕。
给的应该只是一部分代码。中断文件怎么定义的,TIM3_IRQHandler再那里处理的?
sylar.z 回答时间:2018-12-10 15:57:50
本帖最后由 sylar.z 于 2018-12-10 16:01 编辑

使用TIM_ITConfig()使能你需要的中断。如:TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);

评分

参与人数 1ST金币 +2 蝴蝶豆 +2 收起 理由
STMCU + 2 + 2

查看全部评分

李康1202 回答时间:2018-12-10 20:12:06
看到一大堆寄存器顿时懵逼了
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版