打印
[STM32F4]

软件中断问题,附stm32f4 的IAR工程

[复制链接]
2278|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zchong|  楼主 | 2016-2-24 20:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zchong 于 2016-2-29 09:13 编辑

设计意图:由systick定时器产生每秒25600个中断,然后定时器中断中每256次通过软件中断产生一个中断,每5120次产生另外一个中断;
测试结果:
1、IAR,JLINK仿真状态下,5120点的那个软件中断产生的次数明显不对,256点的是正常的;
2、脱离仿真器,直接运行,结果是正确的;
搞不清状况了,大伙可以测试一下,代码如下:



static void  systick_init(void)
{
    RCC_ClocksTypeDef   rcc_clocks;
        uint32_t    cnts;

    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
   
        RCC_GetClocksFreq(&rcc_clocks);

        cnts = (uint32_t)rcc_clocks.HCLK_Frequency / 25600;

    if ((cnts - 1UL) > SysTick_LOAD_RELOAD_Msk) { while(1); }   /* Reload value impossible */

    SysTick->LOAD  = (uint32_t)(cnts - 1UL);                    /* set reload register */
    NVIC_SetPriority (SysTick_IRQn, 0);                         /* set Priority highest */
    SysTick->VAL   = 0;                                         /* Load the SysTick Counter Value */
    SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                     SysTick_CTRL_TICKINT_Msk   |
                     SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
        
}



static void EXTILine0_Config(void)
{
    EXTI_InitTypeDef   EXTI_InitStructure;
    NVIC_InitTypeDef   NVIC_InitStructure;

    /* Enable SYSCFG clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    /* Configure EXTI Line0 */
    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_Init(&EXTI_InitStructure);

    /* Enable and set EXTI Line0 Interrupt to the lowest priority */
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  Configures EXTI Line15 (connected to PG15 pin) in interrupt mode
  * @param  None
  * @retval None
  */
static void EXTILine13_15_Config(void)
{
    EXTI_InitTypeDef   EXTI_InitStructure;
    NVIC_InitTypeDef   NVIC_InitStructure;

    /* Enable SYSCFG clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  
    /* Configure EXTI Line13 */
    EXTI_InitStructure.EXTI_Line = EXTI_Line13;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_Init(&EXTI_InitStructure);
  
    /* Enable and set EXTI15_10 Interrupt to the lowest priority */
    NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);
}

static void exti_init(void)
{
    EXTILine0_Config();
   
    EXTILine13_15_Config();   
}


void period_init(void)
{
    /* Configures the priority grouping: pre-emption priority and subpriority */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
   
    /* Sample periodic interrupt config */
    systick_init();
   
   
    /* Externel interrupt init */
    exti_init();
}

/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  Main program
  * @param  None
  * @retval None
  */
int main(void)
{   
    /* Timer, cycle sampling init */
    period_init();
   
    /* Infinite loop */
    while (1)
    {        

    }
}


int32_t short_interrupt_trig_cnt = 0;
int32_t short_interrupt_cnt= 0;
int32_t long_interrupt_trig_cnt = 0;
int32_t long_interrupt_cnt= 0;

/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  Period sampling handler,512 pionts every cycle.
  * @param  None
  * @retval None
  */

void SysTick_Handler(void)
{
    static uint16_t counter = 0;
        
    counter++;
   
    /* 256 points,half cycle */
    if ((counter&0x00FF) == 0x00FF)
    {
        /* Generate software interrupt */
        EXTI_GenerateSWInterrupt(EXTI_Line0);
        short_interrupt_trig_cnt++;
    }  
   
    /* 5120 points,ten cycles */
    if (counter >= 5119)
    {
        counter = 0;
        /* Generate software interrupt */
        EXTI_GenerateSWInterrupt(EXTI_Line13);
        long_interrupt_trig_cnt++;
    }
   
}


/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  This function handles External line 0 interrupt request.
  * @param  None
  * @retval None
  */
void EXTI0_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line0) != RESET)
    {
        /* Clear the EXTI line 0 pending bit */
        EXTI_ClearITPendingBit(EXTI_Line0);
        
        short_interrupt_cnt++;
    }
}

/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  This function handles External lines 15 to 10 interrupt request.
  * @param  None
  * @retval None
  */
void EXTI15_10_IRQHandler(void)
{  
    if(EXTI_GetITStatus(EXTI_Line13) != RESET)
    {  
        /* Clear the EXTI line 13 pending bit */
        EXTI_ClearITPendingBit(EXTI_Line13);
        //delay(0x1);   
        long_interrupt_cnt++;
    }
}



   附上IAR工程,很方便移植到其它的STM32处理器上,感兴趣的可以测试一下!!  

cpu.zip

943.08 KB

沙发
zchong|  楼主 | 2016-2-25 12:26 | 只看该作者
求助啊

使用特权

评论回复
板凳
airwill| | 2016-2-25 13:07 | 只看该作者
仿真, 不应该有这样的问题哪
我怀疑你的观察和检查方法是不是有问题?

使用特权

评论回复
地板
zchong|  楼主 | 2016-2-25 18:03 | 只看该作者
airwill 发表于 2016-2-25 13:07
仿真, 不应该有这样的问题哪
我怀疑你的观察和检查方法是不是有问题?

看上面的代码就可以发现问题了
真正的中断产生次数远大于软件触发中断的次数
我用示波器也测试过io,的确是这样

使用特权

评论回复
5
E-Kaia| | 2016-2-25 18:20 | 只看该作者
仿真器下面调试中断程序是不是不太靠谱?

使用特权

评论回复
6
Bermanrep| | 2016-2-26 09:11 | 只看该作者
楼主能否说一下你是如何仿真的,如何确定256点是正确的啊

使用特权

评论回复
7
zchong|  楼主 | 2016-2-26 10:18 | 只看该作者
Bermanrep 发表于 2016-2-26 09:11
楼主能否说一下你是如何仿真的,如何确定256点是正确的啊

触发次数与实际中断产生次数一致就可认为是正确的

使用特权

评论回复
8
500days| | 2016-2-26 22:44 | 只看该作者
如果这款芯片没有软中断,就加不了操作系统了

使用特权

评论回复
9
lwsn| | 2016-2-27 20:40 | 只看该作者
楼主是怎么检查的,具体怎么操作的

使用特权

评论回复
10
zchong|  楼主 | 2016-2-28 22:04 | 只看该作者
lwsn 发表于 2016-2-27 20:40
楼主是怎么检查的,具体怎么操作的

两种方式:
1、软件中断触发的地方使用一个计数器,软件中断服务函数中使用一个计数器,看这两个计数器是否一致;
2、在方法1的计数器位置翻转IO,使用示波器测量。

使用特权

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

本版积分规则

50

主题

1746

帖子

4

粉丝