共2条
1/1 1 跳转至页
UCOS,II,PWM 在UCOS-II中PWM中断和定时器0之间中断断嵌套方面的问题,

问
以下参照一个zlg提供的例子,我配置如下:
void VICInit(void)
{
extern void IRQ_Handler(void);
extern void Timer0_Handler(void);
extern void PWMMR_Handler(void);
VICIntEnClr = 0xffffffff;
VICDefVectAddr = (uint32)IRQ_Handler;
VICVectAddr0= (uint32)PWMMR_Handler;//PWMMR优先级比Timer0高
VICVectCntl0 = (0x20 | 0x08);
VICIntEnable = 1 << 8;
VICVectAddr1 = (uint32)Timer0_Handler;
VICVectCntl1 = (0x20 | 0x04);
VICIntEnable = 1 << 4;
}
问题是:因为我的pwm频率高,有如下可能性:
(1)在PWMMR中断服务程序里,如果Timer0中断发生,会不会有中断嵌套可能;
(2)在Timer0中断服务程序里,如果PWMMR中断发生,会不会有中断嵌套可能;
第二种可能我觉得应该有,问题是第一种情形有吗????
答 1: zlg的一个例子:void UART0_Exception(void)
{
uint8 IIR, temp, i;
VICIntEnClr = (1 << 6) | (1 << 4);
VICVectAddr = 0; // 通知中断控制器中断结束
OS_ENTER_CRITICAL();
OS_EXIT_CRITICAL();
while(((IIR = U0IIR) & 0x01) == 0)
{ /* 有中断未处理完 */
switch (IIR & 0x0e)
{
case 0x02: /* THRE中断 */
for (i = 0; i < UART0_FIFO_LENGTH; i++) /* 向发送FIFO填充数据 */
{
if (QueueRead(&temp, UART0SendBuf) == QUEUE_OK)
{
U0THR = temp;
}
else
{
U0IER = U0IER & (~0x02); /* 队列空,则禁止发送中断 */
}
}
break;
case 0x04: /* 接收数据可用 */
OSSemPost(Uart0Sem); /* 通知接收任务 */
U0IER = U0IER & (~0x01); /* 禁止接收及字符超时中断 */
break;
case 0x06: /* 接收线状态 */
temp = U0LSR;
break;
case 0x0c: /* 字符超时指示 */
OSSemPost(Uart0Sem); /* 通知接收任务 */
U0IER = U0IER & (~0x01); /* 禁止接收及字符超时中断 */
break;
default :
break;
}
}
VICIntEnable = (1 << 6) | (1 << 4);
}
void Timer0_Exception(void)
{
VICIntEnClr = 1 << 4;
VICVectAddr = 0; // 通知中断控制器中断结束
OS_ENTER_CRITICAL();
OS_EXIT_CRITICAL();
T0IR = 0x01;
OSTimeTick();
VICIntEnable = 1 << 4;
}
void VICInit(void)
{
extern void IRQ_Handler(void);
extern void Timer0_Handler(void);
extern void UART0_Handler(void);
VICIntEnClr = 0xffffffff;
VICDefVectAddr = (uint32)IRQ_Handler;
VICVectAddr14 = (uint32)UART0_Handler;
VICVectCntl14 = (0x20 | 0x06);
VICIntEnable = 1 << 6;
VICVectAddr15 = (uint32)Timer0_Handler;
VICVectCntl15 = (0x20 | 0x04);
VICIntEnable = 1 << 4;
}
/************************************************************/
请问下周公:
OS_ENTER_CRITICAL();开启之后,马上就OS_EXIT_CRITICAL();中断还怎么嵌套啊。。。。。没有懂这里
答 2: 为什么就没有人愿意回答一下周公能提供一个完整的中断嵌套例子给我么
或者那位xdjm 愿意,我也真心感谢啊。。。。
我在前后台pwm实现了所要去的功能(直线插补),当然我PWM使用了PWM中断了。不然也就没有必要使用了中断嵌套,
答 3: OS_EXIT_CRITICAL是退出临界区的意思,即开中断 答 4: hehe我搞反了,但为什么 OS_ENTER_CRITICAL();马上就OS_EXIT_CRITICAL();
因为关中断后,马上就开中断,还不如就直接开中断得了。。。
还有,,
就拿以下来说:
void Timer0_Exception(void)
{
(1) VICIntEnClr = 1 << 4;
VICVectAddr = 0; // 通知中断控制器中断结束
OS_ENTER_CRITICAL();
OS_EXIT_CRITICAL();
T0IR = 0x01;
OSTimeTick();
VICIntEnable = 1 << 4;
}
(1)句的时候中断时禁止的吗???? 答 5: 没有人做中断嵌套吗。。。。顶起哦 答 6: 要用FIQ中断才行的!! 答 7: re:sixpower 我调了几天了。都要疯了。。感觉遇到鬼了。
我的目的是用PWM 中PWMMR2控制x轴 PWMMR4控制y轴,
很奇怪的是,我单独用走x轴,程序可以走,
但是,单独走y轴,程序就跑飞,
我现在还没有调试x,y都走(走斜线这种情况);
因为走x轴和y轴方法一样,
我仔细对照程序,没有发现不对的。。
我以为是命名的问题,结果也排除,
干脆我把走x的PWMMR2 放到走y这里来试试,结果还是不行,
于是我又重新把PWMMR2 放回走x轴,结果,x轴也不是刚才的目标。现在只能
中断三十次。。奇怪啊。。搞这行怎么这样子。。。
答 8: 只是一个很简单的中断嵌套啊。。。在前后台上,我已经都做好了。。。。。。
为什么放到ucos-ii中就不行了呢。。
ucos-ii还是能嵌套256个中断,我晕啊。。
谁能帮帮我啊。。。 答 9: 我的中断嵌套写法参照zlg的例子,见上面例子。void UART0_Exception(void)
{
uint8 IIR, temp, i;
VICIntEnClr = (1 << 6) | (1 << 4);
VICVectAddr = 0; // 通知中断控制器中断结束
OS_ENTER_CRITICAL();
我的中断服务函数
OS_EXIT_CRITICAL();
VICIntEnable = (1 << 6) | (1 << 4);
}
void Timer0_Exception(void)
{
VICIntEnClr = 1 << 4;
VICVectAddr = 0; // 通知中断控制器中断结束
OS_ENTER_CRITICAL();
OS_EXIT_CRITICAL();
T0IR = 0x01;
OSTimeTick();
VICIntEnable = 1 << 4;
}
以下是我的写法:
void VICInit(void)
{
extern void IRQ_Handler(void);
extern void Timer0_Handler(void);
extern void PWMMR24_Handler(void);
VICIntEnClr = 0xffffffff;
VICDefVectAddr = (uint32)IRQ_Handler;
VICVectAddr14 = (uint32)UART0_Handler;
VICVectCntl14 = (0x20 | 0x08);
VICIntEnable = 1 << 8;
VICVectAddr15 = (uint32)Timer0_Handler;
VICVectCntl15 = (0x20 | 0x04);
VICIntEnable = 1 << 4;
}
答 10: 失误把
void UART0_Exception(void)
{
uint8 IIR, temp, i;
VICIntEnClr = (1 << 6) | (1 << 4);
VICVectAddr = 0; // 通知中断控制器中断结束
OS_ENTER_CRITICAL();
我的中断服务函数
OS_EXIT_CRITICAL();
VICIntEnable = (1 << 6) | (1 << 4);
}
/*********************************************************/
改为:
void PWMMR24_Exception(void)
{
VICIntEnClr = (1 << 8) | (1 << 4);
VICVectAddr = 0; // 通知中断控制器中断结束
OS_ENTER_CRITICAL();
我的中断服务函数
OS_EXIT_CRITICAL();
VICIntEnable = (1 << 8) | (1 << 4);
}
答 11: 一般用中断嵌套的不多,所以研究这个的人也少了。尽量将中断服务程序弄短。 答 12: 中断服务程序很短的。。只能插补50步左右,,应该是我的中断嵌套没有对头,
周公能不能帮我看看下,,,,,,,,,,, 答 13: to xianfei520我原来也遇到你的问题!
后来发现不能用PWM中断.
最后T1用FIQ 中断就可以了,
PWM可达10K,T1中断用2.4K.
/*************************************
** 函数名称: FIQ_Exception
** 功能描述: 快速中断异常处理程序,用户根据需要自己改变程序
********************************************/
void FIQ_Exception(void)
{
INT32U i;
extern void PWM(void);
i=VICFIQStatus;
T1IR = 0xff;
T1MR0 += (Fpclk / 2400);
PWM();
}
VICIntSelect = 0x00000000; // 设置所有通道为IRQ中断
VICIntSelect =1 << 5;
VICIntEnClr = 0xffffffff;
VICDefVectAddr = (uint32)IRQ_Handler;
VICVectAddr1 = (uint32)Timer0_Handler;
VICVectCntl1 = (0x20 | 0x04);
VICIntEnable = 1 << 4;
T0IR = 0xffffffff;
T0TC = 0;
T0PR = 0;
T0PC= 0;
T0TCR = 0x01;
T0MCR = 0x01;
T0MR0 = (Fpclk / OS_TICKS_PER_SEC);
// VICVectAddr2 = (uint32)Timer1_Handler;
VICVectAddr2 = (uint32)FIQ_Exception;
VICVectCntl2 = (0x20 | 0x05);
VICIntEnable = 1 << 5;
T1IR = 0xffffffff;
T1TC = 0;
T1TCR = 0x01;
T1MCR = 0x01;
T1MR0 = (Fpclk / 4800 );
VICVectCntl0 = (0x20 | 0x08); // PWM通道分配到IRQ slot 3
// VICVectAddr0 = (uint32)PWM_Handler;
VICVectAddr0 = (uint32)FIQ_Exception;
// VICIntEnable = 1 << 8; // 使能PWM中断
OS_EXIT_CRITICAL();
}
答 14: 多谢sixpower;;;;;可是我的PWM中断都做好了。。难道真的不行这样做吗,,
周公发句话吧,,,,,,,,这样中断嵌套行不???
有一事不明白,在UCOS-II中,time0作为时钟中断,
那加入其他的中断都有可能发生中断嵌套的啊,
就拿EINT0中断来说,(当把key1 配置为EITN0)可能你刚按key1的时候,time0
正在发生中断呢。那不就是中断嵌套吗 。。不知道我这样理解对不???? 答 15: 不甘心自己的心血,终于有些眉目了今天下午突然心血来潮,一个三个if语句,适合每种if的情况就分别执行,
我把最复杂的一个if给删掉,调试的时候,(当然不调试此种方法)
结果发现其余的两种,即单独走x轴或者是单独走y轴都正常了。
怪事,我估计是空间问题,,可是我看了编译的情况,还有很多剩的空间啊。。
郁闷,,,还没有整理好。。等整理好之后一并拿来给大家讨论。。。。
答 16: pwm最好别用中断~~~ 答 17: 有一点你要明白OS_ENTER_CRITICAL();后是不能用中断了,也就不能中断嵌套了 答 18: 关注中!!要把成功经验和大家分享啊!! 答 19: 个人无回天之力,请大家帮忙,分析原因我的具体的做法就是上面一贴那样说的。真郁闷的郁闷,
只要我屏蔽掉那个不使用的if{},程序就对了。把这个不使用的if{}加上,
程序就不对了。这里可以肯定的是我的中断嵌套是对的,不然分别走就不对了。我把各自的编译时候的资料给传上来。
LineInterpolation(0,0,568056,0);这是我插补x轴的数据;
LineInterpolation(0,0,0,50000); 这是我插补y轴的数据;
LineInterpolation(0,0,500,50000); 这种x,y都插补的数据没有做。
还有一问题:不知道大家见过没有,我单步运行 y = y+1;初始时y=0;
可这句之后y就是0x40000004;怎么回事啊,是不是bug啊,
第一幅图是没有if{}的编译数据
void VICInit(void)
{
extern void IRQ_Handler(void);
extern void Timer0_Handler(void);
extern void PWMMR_Handler(void);
VICIntEnClr = 0xffffffff;
VICDefVectAddr = (uint32)IRQ_Handler;
VICVectAddr0= (uint32)PWMMR_Handler;//PWMMR优先级比Timer0高
VICVectCntl0 = (0x20 | 0x08);
VICIntEnable = 1 << 8;
VICVectAddr1 = (uint32)Timer0_Handler;
VICVectCntl1 = (0x20 | 0x04);
VICIntEnable = 1 << 4;
}
问题是:因为我的pwm频率高,有如下可能性:
(1)在PWMMR中断服务程序里,如果Timer0中断发生,会不会有中断嵌套可能;
(2)在Timer0中断服务程序里,如果PWMMR中断发生,会不会有中断嵌套可能;
第二种可能我觉得应该有,问题是第一种情形有吗????
答 1: zlg的一个例子:void UART0_Exception(void)
{
uint8 IIR, temp, i;
VICIntEnClr = (1 << 6) | (1 << 4);
VICVectAddr = 0; // 通知中断控制器中断结束
OS_ENTER_CRITICAL();
OS_EXIT_CRITICAL();
while(((IIR = U0IIR) & 0x01) == 0)
{ /* 有中断未处理完 */
switch (IIR & 0x0e)
{
case 0x02: /* THRE中断 */
for (i = 0; i < UART0_FIFO_LENGTH; i++) /* 向发送FIFO填充数据 */
{
if (QueueRead(&temp, UART0SendBuf) == QUEUE_OK)
{
U0THR = temp;
}
else
{
U0IER = U0IER & (~0x02); /* 队列空,则禁止发送中断 */
}
}
break;
case 0x04: /* 接收数据可用 */
OSSemPost(Uart0Sem); /* 通知接收任务 */
U0IER = U0IER & (~0x01); /* 禁止接收及字符超时中断 */
break;
case 0x06: /* 接收线状态 */
temp = U0LSR;
break;
case 0x0c: /* 字符超时指示 */
OSSemPost(Uart0Sem); /* 通知接收任务 */
U0IER = U0IER & (~0x01); /* 禁止接收及字符超时中断 */
break;
default :
break;
}
}
VICIntEnable = (1 << 6) | (1 << 4);
}
void Timer0_Exception(void)
{
VICIntEnClr = 1 << 4;
VICVectAddr = 0; // 通知中断控制器中断结束
OS_ENTER_CRITICAL();
OS_EXIT_CRITICAL();
T0IR = 0x01;
OSTimeTick();
VICIntEnable = 1 << 4;
}
void VICInit(void)
{
extern void IRQ_Handler(void);
extern void Timer0_Handler(void);
extern void UART0_Handler(void);
VICIntEnClr = 0xffffffff;
VICDefVectAddr = (uint32)IRQ_Handler;
VICVectAddr14 = (uint32)UART0_Handler;
VICVectCntl14 = (0x20 | 0x06);
VICIntEnable = 1 << 6;
VICVectAddr15 = (uint32)Timer0_Handler;
VICVectCntl15 = (0x20 | 0x04);
VICIntEnable = 1 << 4;
}
/************************************************************/
请问下周公:
OS_ENTER_CRITICAL();开启之后,马上就OS_EXIT_CRITICAL();中断还怎么嵌套啊。。。。。没有懂这里
答 2: 为什么就没有人愿意回答一下周公能提供一个完整的中断嵌套例子给我么
或者那位xdjm 愿意,我也真心感谢啊。。。。
我在前后台pwm实现了所要去的功能(直线插补),当然我PWM使用了PWM中断了。不然也就没有必要使用了中断嵌套,
答 3: OS_EXIT_CRITICAL是退出临界区的意思,即开中断 答 4: hehe我搞反了,但为什么 OS_ENTER_CRITICAL();马上就OS_EXIT_CRITICAL();
因为关中断后,马上就开中断,还不如就直接开中断得了。。。
还有,,
就拿以下来说:
void Timer0_Exception(void)
{
(1) VICIntEnClr = 1 << 4;
VICVectAddr = 0; // 通知中断控制器中断结束
OS_ENTER_CRITICAL();
OS_EXIT_CRITICAL();
T0IR = 0x01;
OSTimeTick();
VICIntEnable = 1 << 4;
}
(1)句的时候中断时禁止的吗???? 答 5: 没有人做中断嵌套吗。。。。顶起哦 答 6: 要用FIQ中断才行的!! 答 7: re:sixpower 我调了几天了。都要疯了。。感觉遇到鬼了。
我的目的是用PWM 中PWMMR2控制x轴 PWMMR4控制y轴,
很奇怪的是,我单独用走x轴,程序可以走,
但是,单独走y轴,程序就跑飞,
我现在还没有调试x,y都走(走斜线这种情况);
因为走x轴和y轴方法一样,
我仔细对照程序,没有发现不对的。。
我以为是命名的问题,结果也排除,
干脆我把走x的PWMMR2 放到走y这里来试试,结果还是不行,
于是我又重新把PWMMR2 放回走x轴,结果,x轴也不是刚才的目标。现在只能
中断三十次。。奇怪啊。。搞这行怎么这样子。。。
答 8: 只是一个很简单的中断嵌套啊。。。在前后台上,我已经都做好了。。。。。。
为什么放到ucos-ii中就不行了呢。。
ucos-ii还是能嵌套256个中断,我晕啊。。
谁能帮帮我啊。。。 答 9: 我的中断嵌套写法参照zlg的例子,见上面例子。void UART0_Exception(void)
{
uint8 IIR, temp, i;
VICIntEnClr = (1 << 6) | (1 << 4);
VICVectAddr = 0; // 通知中断控制器中断结束
OS_ENTER_CRITICAL();
我的中断服务函数
OS_EXIT_CRITICAL();
VICIntEnable = (1 << 6) | (1 << 4);
}
void Timer0_Exception(void)
{
VICIntEnClr = 1 << 4;
VICVectAddr = 0; // 通知中断控制器中断结束
OS_ENTER_CRITICAL();
OS_EXIT_CRITICAL();
T0IR = 0x01;
OSTimeTick();
VICIntEnable = 1 << 4;
}
以下是我的写法:
void VICInit(void)
{
extern void IRQ_Handler(void);
extern void Timer0_Handler(void);
extern void PWMMR24_Handler(void);
VICIntEnClr = 0xffffffff;
VICDefVectAddr = (uint32)IRQ_Handler;
VICVectAddr14 = (uint32)UART0_Handler;
VICVectCntl14 = (0x20 | 0x08);
VICIntEnable = 1 << 8;
VICVectAddr15 = (uint32)Timer0_Handler;
VICVectCntl15 = (0x20 | 0x04);
VICIntEnable = 1 << 4;
}
答 10: 失误把
void UART0_Exception(void)
{
uint8 IIR, temp, i;
VICIntEnClr = (1 << 6) | (1 << 4);
VICVectAddr = 0; // 通知中断控制器中断结束
OS_ENTER_CRITICAL();
我的中断服务函数
OS_EXIT_CRITICAL();
VICIntEnable = (1 << 6) | (1 << 4);
}
/*********************************************************/
改为:
void PWMMR24_Exception(void)
{
VICIntEnClr = (1 << 8) | (1 << 4);
VICVectAddr = 0; // 通知中断控制器中断结束
OS_ENTER_CRITICAL();
我的中断服务函数
OS_EXIT_CRITICAL();
VICIntEnable = (1 << 8) | (1 << 4);
}
答 11: 一般用中断嵌套的不多,所以研究这个的人也少了。尽量将中断服务程序弄短。 答 12: 中断服务程序很短的。。只能插补50步左右,,应该是我的中断嵌套没有对头,
周公能不能帮我看看下,,,,,,,,,,, 答 13: to xianfei520我原来也遇到你的问题!
后来发现不能用PWM中断.
最后T1用FIQ 中断就可以了,
PWM可达10K,T1中断用2.4K.
/*************************************
** 函数名称: FIQ_Exception
** 功能描述: 快速中断异常处理程序,用户根据需要自己改变程序
********************************************/
void FIQ_Exception(void)
{
INT32U i;
extern void PWM(void);
i=VICFIQStatus;
T1IR = 0xff;
T1MR0 += (Fpclk / 2400);
PWM();
}
VICIntSelect = 0x00000000; // 设置所有通道为IRQ中断
VICIntSelect =1 << 5;
VICIntEnClr = 0xffffffff;
VICDefVectAddr = (uint32)IRQ_Handler;
VICVectAddr1 = (uint32)Timer0_Handler;
VICVectCntl1 = (0x20 | 0x04);
VICIntEnable = 1 << 4;
T0IR = 0xffffffff;
T0TC = 0;
T0PR = 0;
T0PC= 0;
T0TCR = 0x01;
T0MCR = 0x01;
T0MR0 = (Fpclk / OS_TICKS_PER_SEC);
// VICVectAddr2 = (uint32)Timer1_Handler;
VICVectAddr2 = (uint32)FIQ_Exception;
VICVectCntl2 = (0x20 | 0x05);
VICIntEnable = 1 << 5;
T1IR = 0xffffffff;
T1TC = 0;
T1TCR = 0x01;
T1MCR = 0x01;
T1MR0 = (Fpclk / 4800 );
VICVectCntl0 = (0x20 | 0x08); // PWM通道分配到IRQ slot 3
// VICVectAddr0 = (uint32)PWM_Handler;
VICVectAddr0 = (uint32)FIQ_Exception;
// VICIntEnable = 1 << 8; // 使能PWM中断
OS_EXIT_CRITICAL();
}
答 14: 多谢sixpower;;;;;可是我的PWM中断都做好了。。难道真的不行这样做吗,,
周公发句话吧,,,,,,,,这样中断嵌套行不???
有一事不明白,在UCOS-II中,time0作为时钟中断,
那加入其他的中断都有可能发生中断嵌套的啊,
就拿EINT0中断来说,(当把key1 配置为EITN0)可能你刚按key1的时候,time0
正在发生中断呢。那不就是中断嵌套吗 。。不知道我这样理解对不???? 答 15: 不甘心自己的心血,终于有些眉目了今天下午突然心血来潮,一个三个if语句,适合每种if的情况就分别执行,
我把最复杂的一个if给删掉,调试的时候,(当然不调试此种方法)
结果发现其余的两种,即单独走x轴或者是单独走y轴都正常了。
怪事,我估计是空间问题,,可是我看了编译的情况,还有很多剩的空间啊。。
郁闷,,,还没有整理好。。等整理好之后一并拿来给大家讨论。。。。
答 16: pwm最好别用中断~~~ 答 17: 有一点你要明白OS_ENTER_CRITICAL();后是不能用中断了,也就不能中断嵌套了 答 18: 关注中!!要把成功经验和大家分享啊!! 答 19: 个人无回天之力,请大家帮忙,分析原因我的具体的做法就是上面一贴那样说的。真郁闷的郁闷,
只要我屏蔽掉那个不使用的if{},程序就对了。把这个不使用的if{}加上,
程序就不对了。这里可以肯定的是我的中断嵌套是对的,不然分别走就不对了。我把各自的编译时候的资料给传上来。
LineInterpolation(0,0,568056,0);这是我插补x轴的数据;
LineInterpolation(0,0,0,50000); 这是我插补y轴的数据;
LineInterpolation(0,0,500,50000); 这种x,y都插补的数据没有做。
还有一问题:不知道大家见过没有,我单步运行 y = y+1;初始时y=0;
可这句之后y就是0x40000004;怎么回事啊,是不是bug啊,
第一幅图是没有if{}的编译数据
共2条
1/1 1 跳转至页
回复
打赏帖 | |
---|---|
【STM32F769】AI之与本地deepseek对接被打赏50分 | |
Buck电路工作在CCM模式下电感电流的计算公式是什么?被打赏5分 | |
buck电路工作原理被打赏5分 | |
基于MSPM0L1306的MODBUS-RTU协议通讯实验被打赏100分 | |
我想要一部加热台+多合一调试工具被打赏18分 | |
每周了解几个硬件知识+485硬件知识分享被打赏10分 | |
【换取手持数字示波器】树莓派PICO调试器官方固件本地化部署实践被打赏24分 | |
【换取手持数字示波器】分享一个KEIL无法识别CMSIS-DAP调试器的解决办法被打赏20分 | |
【换取手持数字示波器】分享一个自制的ArduinoNano扩展板底板被打赏23分 | |
【换取手持示波器】树莓派PICOW网页烟花被打赏18分 |