打印
[ZLG-ARM]

十万火急请教高手easyarm2104uart0不能进中断接收

[复制链接]
1991|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xxg2005|  楼主 | 2007-5-27 09:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位高手给小弟看下easyarm2104 uart0中断接收程序为何不能进中断?
我用ISP下载到flash可以运行,但easyarm2104重新复位后就不能运行了,为何?请教!!
target.c
/**---------------------------------------------------------------------------------------
**文   件   名: target.c
**描        述: lpc210x(飞利浦的ARM)目标板特殊的代码,包括异常处理程序和目标板初始化程序
**              每个工程应当具有这个文件的拷贝,用户根据程序的需要修改本文件。
**注        意:本文件必须以ARM(32位代码)方式编译,否则,必须更改init.s和vector.s文件
**              别的C代码不必使用ARM(32位代码)方式编译
********************************************************************************************************/

#define IN_TARGET
#include "config.h"

/*********************************************************************************************************
** 函数名称: IRQ_Exception
** 功能描述: 中断异常处理程序,用户根据需要自己改变程序
**
** 输 入: 无
**
** 输 出: 无
**         
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
void __irq IRQ_Exception(void)
{
 //  VICVectAddr = 0x00;                   // 这一句替换为自己的代码
}

/*********************************************************************************************************
** 函数名称: FIQ_Exception
** 功能描述: 快速中断异常处理程序,用户根据需要自己改变程序
**           
** 输 入: 无
**
** 输 出: 无
**         
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
void FIQ_Exception(void)
{
    while(1);                   // 这一句替换为自己的代码
}

/*********************************************************************************************************
** 函数名称: TargetInit
** 功能描述: 目标板初始化代码,在需要的地方调用,根据需要改变
** 输 入: 无
**
** 输 出: 无
**         
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
void TargetInit(void)
{
    /* 添加自己的代码 */
}

/*********************************************************************************************************
** 函数名称: TargetResetInit
** 功能描述: 调用main函数前目标板初始化代码,根据需要改变,不能删除
** 输 入: 无
**
** 输 出: 无
**         
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
void TargetResetInit(void)
{

    /* 设置系统各部分时钟 */
/*    PLLCON = 1;
#if ((Fcclk / 4) / Fpclk) == 1
    VPBDIV = 0;
#endif

#if ((Fcclk / 4) / Fpclk) == 2
    VPBDIV = 2;
#endif

#if ((Fcclk / 4) / Fpclk) == 4
    VPBDIV = 1;
#endif

#if (Fcco / Fcclk) == 2
    PLLCFG = ((Fcclk / Fosc) - 1) | (0 << 5);
#endif
#if (Fcco / Fcclk) == 4
    PLLCFG = ((Fcclk / Fosc) - 1) | (1 << 5);
#endif
#if (Fcco / Fcclk) == 8
    PLLCFG = ((Fcclk / Fosc) - 1) | (2 << 5);
#endif
#if (Fcco / Fcclk) == 16
    PLLCFG = ((Fcclk / Fosc) - 1) | (3 << 5);
#endif
    PLLFEED = 0xaa;
    PLLFEED = 0x55;
    while((PLLSTAT & (1 << 10)) == 0);
    PLLCON = 3;
    PLLFEED = 0xaa;
    PLLFEED = 0x55;
*/  
    
    /* 设置存储器加速模块 */
    MAMCR = 2;        //MAMCR 8u2 00-MAM 功能被禁止、01-MAM功能部分使能、10-MAM功能完全使能
    /* MAMTIM 8u3
    000=0-保留
    001=1-一段时间内只有 1 个处理器时钟(cclk)用于 MAM 取指。
    010=2-一段时间内只有 2 个处理器时钟(cclk)用于 MAM 取指。
    011=3-一段时间内只有 3 个处理器时钟(cclk)用于 MAM 取指。
    100=4-一段时间内只有 4 个处理器时钟(cclk)用于 MAM 取指。
    101=5-一段时间内只有 5 个处理器时钟(cclk)用于 MAM 取指。
    110=6-一段时间内只有 6 个处理器时钟(cclk)用于 MAM 取指。
    111=7-一段时间内只有 7 个处理器时钟(cclk)用于 MAM 取指。
     */
#if Fcclk < 20000000
    MAMTIM = 1;
#else
#if Fcclk < 40000000
    MAMTIM = 2;
#else
    MAMTIM = 3;
#endif
#endif
       
    /* 初始化VIC */
     VICIntEnClr = 0xffffffff; //关闭所有中断
     VICVectAddr = 0;//默认向量地址寄存器
     VICIntSelect = 0;//1:对应的中断请求分配为FIQ。0:对应的中断请求分配为IRQ。

    /* 添加自己的代码 */

}

/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

Init.s
;**--------------文件信息--------------------------------------------------------------------------------
;**文   件   名: Init.s
;**创   建   人: 陈明计
;**最后修改日期: 2003年7月1日
;**描        述: lpc210x初始化代码,每个工程应当有独立的初始化代码,一般不需要改动
;**              特殊情况应当在这个文件上修改而来   
;********************************************************************************************************/

;引入的外部标号在这声明
    IMPORT  __main                          ;C语言主程序入口 
    IMPORT  InitStack                       ;初始化堆栈
    IMPORT  TargetResetInit                 ;目标板基本初始化
    
;给外部使用的标号在这声明
    EXPORT  Reset
    EXPORT __rt_div0
    EXPORT __user_initial_stackheap

;段声明
    CODE32
    AREA    Init,CODE,READONLY
    
;/*********************************************************************************************************
;** 函数名称: Reset
;** 功能描述: 复位入口
;** 
;** 输 入: 无
;**
;** 输 出: 无
;**         
;** 全局变量: 无
;** 调用模块: 无
;********************************************************************************************************/
Reset
        BL      InitStack               ;初始化堆栈
        BL      TargetResetInit         ;目标板基本初始化
                                        ;跳转到c语言入口
        B       __main


;/*********************************************************************************************************
;** 函数名称: __user_initial_stackheap 
;** 功能描述: 库函数初始化堆和栈,不能删除
;** 
;** 输 入: 参考库函数手册
;**
;** 输 出: 参考库函数手册
;**         
;** 全局变量: 无
;** 调用模块: 无
;********************************************************************************************************/
__user_initial_stackheap    
    LDR   r0,=bottom_of_heap
    MOV   pc,lr

;/*********************************************************************************************************
;** 函数名称: __rt_div0
;** 功能描述: 整数除法除数为0错误处理函数,替代原始的__rt_div0减少目标代码大小
;** 
;** 输 入: 参考库函数手册
;**
;** 输 出: 无
;**         
;** 全局变量: 无
;** 调用模块: 无
;********************************************************************************************************/
__rt_div0

        B       __rt_div0

;/* 分配堆空间 */
        AREA    Myheap, DATA, NOINIT, ALIGN=2
bottom_of_heap     SPACE   256  ;库函数的堆空间

    END
;/*********************************************************************************************************
;**                            End Of File
;********************************************************************************************************/

vectors.s
;**--------------文件信息--------------------------------------------------------------------------------
;**文   件   名: vectors.s
;**描        述: lpc210x异常向量入口及异常向量与c语言代码的接口,包括初始化堆栈的代码
;********************************************************************************************************/

;定义堆栈的大小
USR_STACK_LEGTH     EQU         64
SVC_STACK_LEGTH     EQU         0
FIQ_STACK_LEGTH     EQU         16
IRQ_STACK_LEGTH     EQU         64
ABT_STACK_LEGTH     EQU         0
UND_STACK_LEGTH     EQU         0


;引入的外部标号在这声明
    IMPORT  FIQ_Exception                   ;快速中断异常处理程序
; //   IMPORT  IRQ_Exception
    IMPORT  Reset

;给外部使用的标号在这声明
    EXPORT  InitStack
    EXPORT  Vectors


    CODE32

    AREA    Startup,CODE,READONLY

;中断向量表
Vectors
        LDR     PC, ResetAddr
        LDR     PC, UndefinedAddr
        LDR     PC, SWI_Addr
        LDR     PC, PrefetchAddr
        LDR     PC, DataAbortAddr
        DCD     0xb9205f80
        LDR     PC, [PC, #-0xff0]
        LDR     PC, FIQ_Addr

ResetAddr           DCD     Reset
UndefinedAddr       DCD     Undefined
SWI_Addr            DCD     SoftwareInterrupt
PrefetchAddr        DCD     PrefetchAbort
DataAbortAddr       DCD     DataAbort
Nouse               DCD     0
IRQ_Addr            DCD     0  ;  //IRQ_Exception
FIQ_Addr            DCD     FIQ_Handler

;未定义指令
Undefined
        B       Undefined

;软中断
SoftwareInterrupt
        B       SoftwareInterrupt

PrefetchAbort
        B       PrefetchAbort

;取数据中止
DataAbort
        B       DataAbort


;快速中断
FIQ_Handler
        STMFD   SP!, {R0-R3, LR}
        BL      FIQ_Exception
        LDMFD   SP!, {R0-R3, LR}
        SUBS    PC,  LR,  #4

;/*********************************************************************************************************
;** 函数名称: InitStack
;** 功能描述: 初始化堆栈
;** 输 入:   无
;** 输 出 :  无
;** 全局变量: 无
;** 调用模块: 无
;********************************************************************************************************/
InitStack    
        MOV     R0, LR   ;保存程序返回值,bx指令会将pc复制给lr=r14,pc=r15

;设置管理模式堆栈
        MSR     CPSR_c, #0xd3 ;模式切换,管理模式
        LDR     SP, StackSvc
;设置中断模式堆栈
        MSR     CPSR_c, #0xd2 ;模式切换,中断模式
        LDR     SP, StackIrq
;设置快速中断模式堆栈
        MSR     CPSR_c, #0xd1 ;模式切换,快速中断模式
        LDR     SP, StackFiq
;设置中止模式堆栈
        MSR     CPSR_c, #0xd7 ;模式切换,异常中止模式
        LDR     SP, StackAbt
;设置未定义模式堆栈
        MSR     CPSR_c, #0xdb ;模式切换,未定义模式
        LDR     SP, StackUnd
;设置系统模式堆栈
        MSR     CPSR_c, #0x5f ;模式切换,系统模式
        LDR     SP, StackUsr

        MOV     PC, R0   ;断点返回

StackUsr           DCD     UsrStackSpace + (USR_STACK_LEGTH - 1) * 4
StackSvc           DCD     SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4
StackIrq           DCD     IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
StackFiq           DCD     FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4
StackAbt           DCD     AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4
StackUnd           DCD     UndtStackSpace + (UND_STACK_LEGTH - 1)* 4


;/* 分配堆栈空间 */
        AREA    MyStacks, DATA, NOINIT, ALIGN=2
UsrStackSpace      SPACE   USR_STACK_LEGTH * 4  ;用户(系统)模式堆栈空间
SvcStackSpace      SPACE   SVC_STACK_LEGTH * 4  ;管理模式堆栈空间
IrqStackSpace      SPACE   IRQ_STACK_LEGTH * 4  ;中断模式堆栈空间
FiqStackSpace      SPACE   FIQ_STACK_LEGTH * 4  ;快速中断模式堆栈空间
AbtStackSpace      SPACE   ABT_STACK_LEGTH * 4  ;中止义模式堆栈空间
UndtStackSpace     SPACE   UND_STACK_LEGTH * 4  ;未定义模式堆栈

    END
;/*********************************************************************************************************
;**                            End Of File
;********************************************************************************************************/


 uart0.h
#ifndef __UART0_H__
#define __UART0_H__

extern void UartInit(void);            // 串口初始化
extern void SendSerialchar(uchar ch);  // 通过串口发数据 


#endif //__UART0_H__



uart0.c

#include "includes.h"


// 串口发送一个字符--查询方式
void SendSerialchar(uchar ch)
{  
    U0THR = ch;
    while((U0LSR & 0x40) == 0);
}


// 串口接收数据--中断方式
void __irq IRQ_UART0(void)
{
    uchar ucTemp,ucRcvData;
    
    ucTemp = U0IIR & 0x0F;
    switch(ucTemp)
    {
    case 0x04:
    ucRcvData = U0RBR;         // 读取接收缓存器数据
    SendSerialchar(ucRcvData); // 将数据回传给PC
    VICVectAddr0 = 0x00;         // 通过读取U0IIR来清除中断
    break;
    }
}


// 串口初始化
void UartInit(void)

    U0LCR = 0x83;  // 使能访问除数锁存
    U0DLM = 0x00;  // 波特率设置9600,
    U0DLL = 0x12;  
    U0LCR = 0x03;  // 禁止访问除数锁存,8数据位1停止位无奇偶校验
  
    U0IER = 0x01;  // 使能接收中断
    U0FCR = 0x01;  // 使能FIFO,RX触发选择00,1字节    
    VICIntSelect = 0x00000000;   //所有中断为IRQ中断 
    VICVectCntl0 = 0x26;
    VICVectAddr0 = (uint)IRQ_UART0; // 向量地址  
    VICIntEnable = 0x00000040;      // 使能uart0向量
}


main.c
#include  "includes.h"
extern  UartInit(void);            // 串口初始化
extern  SendSerialchar(uchar ch);  // 通过串口发数据


/****************************************************************************
* 名称:DelayNS()
* 功能:长软件延时
* 入口参数:dly        延时参数,值越大,延时越久
* 出口参数:无
****************************************************************************/
void  DelayNS(uint32  dly)
{
   uint32  i;

   for(; dly>0; dly--) 
      for(i=0; i<50000; i++);
}


/****************************************************************************
* 名称:main()
* 功能:控制LED闪烁
****************************************************************************/
int  main(void)
{
    PINSEL0 = 0x00000005;         // 设置p0.13,p0.14引脚连接uart0
    PINSEL1 = 0x00000000;
                                 // uart0初始化
    VICIntEnClr = 0xffffffbf;    // 打开中断uart0中断

    UartInit();
    while(1)
    {
        
    }
    return 0;
}

上面是关键的程序代码,感觉是 中断向量没设置好,麻烦哪位给看一下啊!!



相关帖子

沙发
cszhaoqm| | 2007-5-27 11:37 | 只看该作者

贴一个修改过的SmartARM2200的UART0例程,ARM向计算机发回收到数

// 不知道为什么,复制过来的中文注释成乱码了,只好删除了

#include  "config.h" 

#define MAX_LEN     1024
#define MIN_LEN     20
#define FIFO_USED   1      

uint8  rcv_buf[MAX_LEN];
uint16 rcv_head;
uint16 rcv_tail;

void SendByte(uint8 data)
{
    U0THR = data;
    while( (U0LSR&0x20)==0 );
}

void   __irq IRQ_UART0(void)
{
    uint8 i;
    switch(U0IIR&0x0F)     
    {
        case 0x0c:
        case 0x04:
        {
            while((U0LSR & 0x01) != 0)
            {
                if(rcv_tail < MAX_LEN)
                {
                    rcv_buf[rcv_tail++] = U0RBR;
                }
            }
//          SendByte((uint8)rcv_tail);      
            break;
        }
#if FIFO_USED
        case 0x02:
            i = 0;
            while(1)
            {
                if(rcv_head >= rcv_tail)
                {
                    U0IER = U0IER & (~0x02);
                    break;
                }
                
                U0THR = rcv_buf[rcv_head++];
                
                if((i++) >= 16)
                {
                    break;
                }
            }
            break;
#endif
        default:
            break;
    }    
    VICVectAddr = 0x00;                     
}               

uint8 UART0Init(uint32 bps)
{
    uint16 Fdiv;
    
    PINSEL0 = (PINSEL0 & 0xfffffff0) | 0x05;    

    U0LCR = 0x80;                               
    Fdiv = (Fpclk / 16) / bps;                  
    U0DLM = Fdiv / 256;                         
    U0DLL = Fdiv % 256;                     
    U0LCR = 0x03;                               
                                                
    U0FCR = 0xC7;                               
    U0IER = 0x01;                               
    
    return 1;


int  main(void)
{
    uint16  i;
        
    UART0Init(115200);                   
  
    VICIntSelect = 0x00000000;             
    VICVectCntl0 = 0x26;                 
    VICVectAddr0 = (int)IRQ_UART0;       
    VICIntEnable|= (1<<6);               
   
    rcv_head = 0;
    rcv_tail = 0;                    

    while(1)                          
    {
#if FIFO_USED
        if((rcv_tail - rcv_head) > MIN_LEN)
        {
            SendByte(rcv_buf[rcv_head++]);
            U0IER|= 0x02;
        }
#else            
        if(rcv_tail > MIN_LEN)
        {
            for(i=0;i<rcv_tail;i++)
            {
                SendByte(rcv_buf);
            }
//          SendByte((uint8)rcv_tail);     
            rcv_tail = 0;
        }
#endif      
    }
    return(0);
}

使用特权

评论回复
板凳
xxg2005|  楼主 | 2007-5-27 13:12 | 只看该作者

好的 学习了 谢谢阁下。

抄下来好好看看好好研究,谢谢楼上!!!

使用特权

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

本版积分规则

1

主题

2

帖子

0

粉丝