TI中文支持网
TI专业的中文技术问题搜集分享网站

C6747进入中断服务函数中回不去主函数那里继续执行了

程序的流程是定时器事件引发edma3传输,传输完成产生edma3中断,中断完成后会在

如题。调试信息如下,能够进入中断,但是中断后回不去main函数继续执行了.

 程序如下

/*
* main.c
*/
#include <stdio.h>
#include <c6x.h>
#include "C6747.h"
#include "C6747_gpio.h"
#include "edma3.h"
#include "edma3cc.h"

#define ChannelNum 10 //对应的是参数集的Num,事件10,定时器12输出中断
#define QueenNum 0

Int16 flag = 0;
Uint32 delay_length = 0;
Uint16 source[100], dest[100];
Int16 sample_size = 2;
Int16 sample_count = 100;

extern cregister unsigned int IER,IFR,CSR,ICR,ISTP,ISR;

//函数声明

//DSP 中断初始化
void InterruptInit(void)
{
//初始化 DSP 中断控制器
CSR &= 0xfffe; //关全局中断
asm( " NOP 2 " );

INTmux1 = 0x8; //指定定时器产生的edma3中断到中断4
ISTP = 0x11800000; //重置中断向量表到L2RAM中
ICR = 0xffff; //清除所有等待的中断
ISR = 0x0000; //清除等待的中断
IER = 0xffff; //使能中断4-15
CSR = CSR | 0x1; //使能DSP全局中断
}

void delay(delay_length)
{
Uint32 i;
for(i = 0; i<delay_length; i++);
}

//定时器初始化
void TimerInit(void)
{
TIMER0_TGCR = 0x00000015; //采用双32位定时器退出复位
TIMER0_TIM12 = 0;
TIMER0_TIM34 = 0; //计数寄存器timer counter register0
TIMER0_PRD12 = 0x016E3600;//设定的周期值timer period register
TIMER0_PRD34 = 0;
TIMER0_INTCLSTAT = 0x00000003; //开定时器12中断
TIMER0_REL12 = 0x016E3600;
TIMER0_TRC = 0X00000050; // 计数达到设定周期值后,定时器12重新开始
// 计数器到设定值后,脉冲两个周期
}

void VarInit()
{
Int16 i;
for( i = 0; i < 100; i++)
{
source[i] = i;
dest[i] = 0;
}
}

void main(void)
{
C6747_init();//初始化C6747核
InterruptInit();
VarInit();
TimerInit();
EdmaInit();
SetupEdma(source, dest, sample_size, sample_count, ParamNumber, ChannelTcc);
EdmaEnableChannel(ChannelNum, QueenNum);
EdmaIntEnable(ChannelNum);//将通道分配到影子寄存器1中
GPIO_DIR23 = 0; //设置IO为输出
for(;;)
{
if(flag == 1)
{
GPIO_OUT_DATA23 = 0x0800;
delay(0xfffff0);
GPIO_OUT_DATA23 = 0x0000;
delay(0xfffff0);
flag = 0;
}
}
}

edma3.c中的程序如下

/*
* edma3.c
*
* Created on: 2019年1月23日
* Author: DELL
*/
#include "C6747.h"
#include "edma3cc.h"
#include "edma3.h"

//extern void intcVectorTable(void);
#define CSL_EDMA3CC_0_REGS (0x01C00000u)
static CSL_Edma3ccRegsOvly edmaCcRegs = (CSL_Edma3ccRegsOvly)CSL_EDMA3CC_0_REGS;
//extern cregister unsigned int CSR;
//extern Int16 flag;

void EdmaInit()
{
edmaCcRegs->ECR = 0xffffffff; // clear events 0 -> 31
edmaCcRegs->SECR = 0xffffffff; // clear secondary events 0 -> 31
edmaCcRegs->IECR = 0xffffffff; // disable all interrupts
edmaCcRegs->ICR = 0xffffffff; // clear all pending interrupts
}

void SetupEdma(Uint16 *src, Uint16 *dst, Uint32 sample_size, Uint32 sample_count, Int16 ParamNum, Uint16 TCC)
{
CSL_Edma3ccParamSetRegs param;

// 1. setup channel PaRAM slot
param.OPT = (TCC << 12) | (1 << 20) | (1 << 2); // transfer complete interrupt enabled
param.SRC = (Uint32)src;
param.A_B_CNT = (sample_count << 16) | (sample_size); // actual format: BCNT|ACNT,此处,ACNT为4,BCNT为1
param.DST = (Uint32)dst; //dst:SPIDAT1
param.SRC_DST_BIDX = (sample_size << 16) | (sample_size);//actual format: DSTBIDX|SCRBIDX
param.LINK_BCNTRLD = (0 << 16) | ( 0xffff ); // actual format: BCNTRLD|LINK
param.SRC_DST_CIDX = (200 << 16) | (200); // actual format: DSTCIDX|SRCCIDX
param.CCNT = 1;
EdmaWritePaRAM(ParamNum, &param);
}

void EdmaWritePaRAM(Int16 ParamNum, CSL_Edma3ccParamSetRegs *ptrParamInfo)
{
edmaCcRegs->PARAMSET[ParamNum].OPT = ptrParamInfo->OPT;
edmaCcRegs->PARAMSET[ParamNum].SRC = ptrParamInfo->SRC;
edmaCcRegs->PARAMSET[ParamNum].A_B_CNT = ptrParamInfo->A_B_CNT;
edmaCcRegs->PARAMSET[ParamNum].DST = ptrParamInfo->DST;
edmaCcRegs->PARAMSET[ParamNum].SRC_DST_BIDX = ptrParamInfo->SRC_DST_BIDX;
edmaCcRegs->PARAMSET[ParamNum].LINK_BCNTRLD = ptrParamInfo->LINK_BCNTRLD;
edmaCcRegs->PARAMSET[ParamNum].SRC_DST_CIDX = ptrParamInfo->SRC_DST_CIDX;
edmaCcRegs->PARAMSET[ParamNum].CCNT = ptrParamInfo->CCNT;
}

void EdmaEnableChannel(Int16 channelNumber, Int16 QueueNumber)
{
int mask;

edmaCcRegs->EMCR = 1 << channelNumber;
edmaCcRegs->SECR = 1 << channelNumber;

QueueNumber &= 1; // only 0 or 1 are valid

mask = 0x07 << (4 * (channelNumber & 0x07) );

edmaCcRegs->DMAQNUM[channelNumber >> 3] &= ~mask;
edmaCcRegs->DMAQNUM[channelNumber >> 3] |= QueueNumber << (4 * (channelNumber & 0x07) );

edmaCcRegs->EESR = 1 << channelNumber;
}

void EdmaIntEnable(Int16 intNum)
{
edmaCcRegs->IESR = 1 << intNum;
edmaCcRegs->DRA[0].DRAE &= ~(1 << intNum); //DRAE0的intNum位清0
edmaCcRegs->DRA[1].DRAE |= 1 << intNum; //DRAE1的intNum位置1
}

void EdmaIntClear(Uint16 Tcc)
{
edmaCcRegs->ICR = 1 << Tcc;
}

interrupt void LEDEDMAINT()
{
CSR &= 0xfffe; //关中断GIE = 0
while( edmaCcRegs->IPR )
{
EdmaIntClear(ChannelTcc);
flag = 1;
}
TIMER0_INTCLSTAT |= 0x00000002; //清除中断标志位
CSR |= 0x1;
}

zhang yuexin:

如果进了中断之后按F5一步步调试是可以回到主函数继续执行的。好奇怪啊,是我没开什么东西吗?

Shine:

回复 zhang yuexin:

进不了main函数的话,程序在哪里执行?跑飞了?

zhang yuexin:

回复 Shine:

变成了0x00000000,不太明白为什么

Shine:

回复 zhang yuexin:

加大堆栈试试。

Tony Tang:

zhang yuexininterrupt void LEDEDMAINT(){ CSR &= 0xfffe; //关中断GIE = 0 while( edmaCcRegs->IPR ) { EdmaIntClear(ChannelTcc); flag = 1; } TIMER0_INTCLSTAT |= 0x00000002; //清除中断标志位 CSR |= 0x1;}

ISR不需要做全局中断的开关,在进入ISR时CPU自动就做了。

赞(0)
未经允许不得转载:TI中文支持网 » C6747进入中断服务函数中回不去主函数那里继续执行了
分享到: 更多 (0)