打印
[ZLG-MCU]

求助:进不了systick中断

[复制链接]
5156|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ATmega32L|  楼主 | 2008-2-21 20:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "hw_types.h"
#include "srcsystick.h"
#include "srcsysctl.h"
#include "hw_ints.h"
#include "hw_nvic.h"
#include "srcinterrupt.h"
#include "srcgpio.h"
#include "hw_memmap.h"

#define PINS    GPIO_PIN_4

void SysTickISR(void)
{
static unsigned int temp=PINS;
      GPIOPinWrite(GPIO_PORTB_BASE,PINS,temp);
      temp=~temp;
}


int main(void)
{
      SysCtlClockSet(SYSCTL_SYSDIV_1|SYSCTL_USE_OSC|SYSCTL_OSC_MAIN|SYSCTL_XTAL_6MHZ);
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
      GPIODirModeSet(GPIO_PORTB_BASE,PINS,GPIO_DIR_MODE_OUT);
      GPIOPinWrite(GPIO_PORTB_BASE,PINS,PINS);

      SysTickPeriodSet(SysCtlClockGet()/1000-1);
      SysTickIntRegister(SysTickISR);
      SysTickEnable();
      SysTickIntEnable();
      IntMasterEnable();

      while(1);

}



不知道哪里有问题,总是进不了SYSTICK中断。
KEIL 3.05A

相关帖子

沙发
zlgarm| | 2008-2-22 12:05 | 只看该作者

在中断表中有没有填写"SysTickISR"?

在中断表中有没有填写"SysTickISR"?

(zlgarm_ZSG)

使用特权

评论回复
板凳
hotpower| | 2008-2-22 15:52 | 只看该作者

哈哈~~~楼主整天迷糊~~~

使用特权

评论回复
地板
hotpower| | 2008-2-22 15:59 | 只看该作者

哈哈~~~都是楼主的"IAR 可以不用setup.c"的高见造成~~~

使用特权

评论回复
5
ATmega32L|  楼主 | 2008-2-22 16:06 | 只看该作者

没必要把SysTickISR填写到中断向量表里

在中断表中有没有填写"SysTickISR"?
没有。

既然调用SysTickIntRegister(SysTickISR),就没必要把SysTickISR填写到中断向量表里。


void
SysTickIntRegister(void (*pfnHandler)(void))
{
    //
    // Register the interrupt handler, returning an error if an error occurs.
    //
    IntRegister(FAULT_SYSTICK, pfnHandler);

    //
    // Enable the SysTick interrupt.
    //
    HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_INTEN;
}




void
IntRegister(unsigned long ulInterrupt, void (*pfnHandler)(void))
{
    unsigned long ulIdx;

    //
    // Check the arguments.
    //
    ASSERT(ulInterrupt < NUM_INTERRUPTS);

    //
    // Make sure that the RAM vector table is correctly aligned.
    //
    ASSERT(((unsigned long)g_pfnRAMVectors & 0x000003ff) == 0);

    //
    // See if the RAM vector table has been initialized.
    //
    if(HWREG(NVIC_VTABLE) != (unsigned long)g_pfnRAMVectors)
    {
        //
        // Copy the vector table from the beginning of FLASH to the RAM vector
        // table.
        //
        for(ulIdx = 0; ulIdx < NUM_INTERRUPTS; ulIdx++)
        {
            g_pfnRAMVectors[ulIdx] = (void (*)(void))HWREG(ulIdx * 4);
        }

        //
        // Point NVIC at the RAM vector table.
        //
        HWREG(NVIC_VTABLE) = (unsigned long)g_pfnRAMVectors;
    }

    //
    // Save the interrupt handler.
    //
    g_pfnRAMVectors[ulInterrupt] = pfnHandler;
}



启动时,默认中断向量表里面的前4个中断向量有用。
当程序启动完毕后调用IntRegister,会将在FLASH区里面的中断向量表复制到RAM中,并且将要注册的中断地址写道相应的中断向量里,与中断向量之前的值无关。

使用特权

评论回复
6
hotpower| | 2008-2-22 16:08 | 只看该作者

哈哈~~~晕呀~~~你自己玩吧...厉害可就是不"晕醒"

使用特权

评论回复
7
ATmega32L|  楼主 | 2008-2-22 16:53 | 只看该作者

用CrossWorks可以了

用CrossWorks编译就可以了
怀疑kiel3.05a有问题或者是我用的DriverLib库文件不对。


#include "hw_ints.h"
#include "hw_memmap.h"
#include "hw_types.h"
#include "src/gpio.h"
#include "src/sysctl.h"

#define PINS    (GPIO_PIN_4|GPIO_PIN_5)

void delay(int d)
{
  for( ; d; --d);
}

void SysTickISR(void)
{static int i=0;
   if(++i>=1000)
   {
   i=0;
      GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_5,~GPIOPinRead(GPIO_PORTB_BASE,GPIO_PIN_5));
   }
}

int main(void)
{
IntMasterDisable();
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_6MHZ);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    GPIODirModeSet(GPIO_PORTB_BASE, PINS, GPIO_DIR_MODE_OUT);
    
    SysTickIntRegister(SysTickISR);
    SysTickPeriodSet(SysCtlClockGet()/1000);
    SysTickEnable();
    
    SysTickIntEnable();
    IntMasterEnable();

    while(1)
    {
       GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_4,GPIO_PIN_4);
       delay(200000);
       GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_4,~GPIO_PIN_4);
       delay(200000);
    }
    return 0;
}

用crossworks编译得到elf,再用KEIL软件仿真,可以正常进入systick中断。

但是用keil编译后软件仿真总是有问题。


相关链接:https://bbs.21ic.com/upfiles/img/20082/2008222165319884.rar

使用特权

评论回复
8
zlgmcu| | 2008-2-22 16:57 | 只看该作者

一般请不要使用中断注册,这会导致运行效率严重下降

所以,还是用启动文件为好。

(zlgmcu_wdx)

使用特权

评论回复
9
ATmega32L|  楼主 | 2008-2-22 16:57 | 只看该作者

这个程序在CrossWorks下也可以

这个程序在CrossWorks下也可以,
Keil是咋回事就是不行呢?


#include "hw_types.h"
#include "srcsystick.h"
#include "srcsysctl.h"
#include "hw_ints.h"
#include "hw_nvic.h"
#include "srcinterrupt.h"
#include "srcgpio.h"
#include "hw_memmap.h"

#define PINS    GPIO_PIN_4

void SysTickISR(void)
{
static unsigned int temp=PINS;
      GPIOPinWrite(GPIO_PORTB_BASE,PINS,temp);
      temp=~temp;
}


int main(void)
{
      SysCtlClockSet(SYSCTL_SYSDIV_1|SYSCTL_USE_OSC|SYSCTL_OSC_MAIN|SYSCTL_XTAL_6MHZ);
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
      GPIODirModeSet(GPIO_PORTB_BASE,PINS,GPIO_DIR_MODE_OUT);
      GPIOPinWrite(GPIO_PORTB_BASE,PINS,PINS);

      SysTickPeriodSet(SysCtlClockGet()/1000-1);
      SysTickIntRegister(SysTickISR);
      SysTickEnable();
      SysTickIntEnable();
      IntMasterEnable();

      while(1);

}

使用特权

评论回复
10
zlgmcu| | 2008-2-22 17:06 | 只看该作者

Cross用的是GCC编译器,操作方便些

GCC编译器操作方便,能够自动搞定。但编译生成的代码效率低。
Keil和IAR的编译器效率高,但中断入口必须要在启动文件里手工设定。

(zlgmcu_wdx)

使用特权

评论回复
11
ATmega32L|  楼主 | 2008-2-22 17:13 | 只看该作者

中断注册严重降低效率不同意

中断注册严重降低效率不同意。


1.中断注册只是一个小函数,只有第一次注册时,才复制所有中断向量表到RAM里,以后再注册不会复制中断向量表。
2.如果中断向量表已经注册,则中断响应速度是一样的。
(没发现哪里有说中断向量表在RAM里面或者在FLASH里面中断相应速度不同,即使不同,也应该是RAM比Flahs快)
3.使用中断注册灵活性更强,并且可以不必理会启动文件。
(我的目的是完全不要启动文件,不过IAR软件仿真不能仿真中断,
目前尚不知道完全不要启动文件是否有问题)

使用特权

评论回复
12
hotpower| | 2008-2-22 18:14 | 只看该作者

哈哈~~~在工控中俺认为中断向量表还是在FLASH中心安~~~

可以看出Cortex M3的中断体系和MCU有多么相似~~~

使用特权

评论回复
13
hhtek| | 2008-2-22 18:34 | 只看该作者

可能是编译器的问题

我在把用ICC AVR做的程序往cotex m3上移植,发现一个现象!

只有两个 .c文件
a.c中有函数 void mc(void){;}
b.c中可以直接调用 a.c中的函数,而且不需要extern申明

的确比较“厉害”!!!!

但是我试过的其他很多c编译器,必须extern一下,不然不能编译的

使用特权

评论回复
14
hotpower| | 2008-2-23 00:28 | 只看该作者

俺不喜欢g_pfnRAMVectors,俺喜欢g_pfnVectors~~~

哈哈~~~看看图还是有趣的~~~这个"联络图"够清晰的吧~~~

记得俺在ARM7核的LPC213X上折腾了半天就是想把类似的
g_pfnRAMVectors改成g_pfnVectors.

这倒好,Cortex M3给你不折腾的机会你还要反折腾~~~~

哈哈~~~服了楼主了~~~

使用特权

评论回复
15
ATmega32L|  楼主 | 2008-2-23 07:54 | 只看该作者

多谢。

多谢。


__root const uVectorEntry g_pfnVectors[] @ "INTVEC" =
{
    { .ulPtr =(uint32) __segment_end("CSTACK") },
//是__segment_end("CSTACK")还是__segment_end("CSTACK")+1
    __program_start,   //如何让程序识别__program_start,             
    NmiSR,                                         FaultISR,                              
请问:
1.如何让程序识别__program_start,
2.最初加载堆栈指针是__segment_end("CSTACK")还是__segment_end("CSTACK")+1
(CORTEX-M3堆栈是空堆栈还是满堆栈?)

使用特权

评论回复
16
hotpower| | 2008-2-24 02:24 | 只看该作者

中断向量的首项应该是栈顶地址

例如:
unsigned int stack_base[STACK_SIZE];
....

ISR_VECTOR_TABLE vector_table_at_0
{
  stack_base + sizeof(stack_base);
//......
};

使用特权

评论回复
17
ATmega32L|  楼主 | 2008-2-24 10:38 | 只看该作者

说明CORTEX-m3应该是空减堆栈。

stack_base + sizeof(stack_base);
应该是&stack_base[STACK_SIZE];

&stack_base[STACK_SIZE]是数组最后一个元素的下一个地址。

说明CORTEX-m3应该是空减堆栈。


使用特权

评论回复
18
zlgarm| | 2008-2-24 21:27 | 只看该作者

不建议把程序复制到RAM中运行

不建议在CORTEX-M3中,把程序复制到RAM中运行,原因有二:
1)安全问题.
2)速度问题. Cortex-M3的FLASH同时使用指令总线(INTRUCTION BUS)和数据总线(DATA BUS), 每条指令都可在同一时钟下使用这两条总线. 而RAM使用系统总线(SYSTEM BUS), 它和指令总线,数据总线不能在同一时钟内使用的.任何品牌的CORTEX-M3都如此,这是ARM公司规定的.
  例如: LDR R0 [0X20000180], 如果在FLASH中,由于LUMINARY的FLASH是单周期的, 只需要一个时钟就完成; 如果在RAM中,首先用系统总线读指令,然后用数据总线读0X200000180中的数据, 要2个时钟. 
  所以FLASH中的指令比RAM的指令快得多! 

(zlgarm_zsg)

使用特权

评论回复
19
xwj| | 2008-2-24 21:50 | 只看该作者

呵呵,很多事情都不能光凭经验就一概而论啊

“把程序复制到RAM中运行”,这对于RAM速度可以跑得远远快于FLASH速度,并且在指令流水线做了相应优化的芯片却是能把速度显著提高,这是勿庸置疑的。

但是!
对于Cortex-M3,
一则因为其内核速度有限,而FLASH又做了优化,设计上RAM速度和访问FLASH速度时一样的
二则由于其指令总线和数据总线(可同时访问),而RAM中运行却需要2次访问,结果程序放FLASH里反而比放RAM里快一倍!


因此,很多事情都不能光凭经验就一概而论哦,多读读资料还是有必要的:-)

使用特权

评论回复
20
hotpower| | 2008-2-24 22:57 | 只看该作者

学习了~~~

使用特权

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

本版积分规则

144

主题

376

帖子

0

粉丝