aishiqi1992 发表于 2011-9-25 12:00:25

ICC编程又遇到了两个奇怪的问题了----中断问题和赋值问题。

ICC编程又遇到了两个奇怪的问题了--中断问题和赋值问题。


程序在最下面,出现了两个问题。

1.请看“////注意我1”和“////注意我3”
如果我把//注意3那一句注释掉,电脑串口就能接受到//注意1发送的数据,否则就接受不到。我就不明白了,难道T0服务开着就会使ADC中断服务关闭??怎么才能让T0和ADC中断同时使用啊?

2.请看“////注意我2”和“////注意我4”
如果我只在//注意我2写上这句,把mspeed发送给电脑是0XFFEC,如果我只在//注意我4上写上这句,把mspeed发送给电脑是0X00CD,怎么赋值语句在ADC中断服务程序就异常了??

希望能帮我解决一下,谢谢!







#include<iom8v.h>
#define sens 256
#define perigon 522000000
/////less than 2147483648
unsigned long angular2=0;
long adc;
unsigned char adth,adtl,count=0,adjok=0;
//int speed=0;
unsigned long temp;
long angular=0,speed=0;

int mspeed=0;
int sspeed=0;
unsigned int myt0cnt=0;
int setdir;
#define acce 2
#define maxspeed 50
#define fullspeedan 30


#define deaddelay 10


adinit()
{
//ADMUX=0xc0+1;
ADMUX=0x61;
ACSR=0x80;
ADCSRA=0xcc;
}
uinit()
{
UBRRL=51;
UCSRB|=0x88;
SREG|=0x80;

}

portinit()
{
DDRC=0;
PORTC=0x00;
DDRB=0x06;
PORTB=0x02;
DDRD=0xc0;
PORTD=0x80;
}

delay(){
unsigned int i;
for(i=0;i<100;i++);
}
sendchar(char ch)
{
while(!(UCSRA&0x20));
UDR=ch;}

adjust()
{SREG&=0x7f;
speed=0;
angular2=0;
count=0;
adjok=0;
SREG|=0x80;
}


#pragma interrupt_handler adcsvr:15
adcsvr()
{
adtl=ADCL;
adth=ADCH;

sendchar(adth);/////////////////////////////////////////////////////////注意我1
//sendchar(adtl);
/////mspeed=-50;///////////////////////////////////////////////////////注意我2

ADCSRA=0xcc;
adc=((adth<<8)+adtl);

if(adjok==0)
{
if(count<255)
{angular2=angular2+adc;
count++;
}
else
{
angular2=angular2+adc;
adjok=1;
speed=angular2;///256;
angular=0;////////////////
}
}

adc<<=8;
if((speed-adc>=sens)||(adc-speed>=sens))
{
angular=angular+adc-speed;
if(angular>perigon)angular-=perigon;
if(angular<0)angular+=perigon;

}
}

pwminit()
{
TCCR1A=0xA1;
TCCR1B=0x01;
}


t0init()
{
TCCR0=05;///1-5
TIMSK|=0x01;
TCNT0=acce;
}

#pragma interrupt_handler t0svr:10//////////////////////////////////////////注意我3
t0svr()
{
myt0cnt++;
if(myt0cnt>acce)
{
if(mspeed>sspeed)mspeed-=1;
if(mspeed<sspeed)mspeed+=1;
myt0cnt=0;
sendchar('a');
}

}


main()
{
intan;
int tmp;
int anoffset;
MCUCR=0x00;

portinit();
uinit();
adinit();
delay();
delay();
delay();
adjust();
t0init();
pwminit();

mspeed=-50;///////////////////////////////////////////////////////////////////注意我4

setdir=100;
while(1)
{


sendchar((mspeed>>8)&0xff);
sendchar(mspeed&0xff);

delay();



}

}


点击此处下载 ourdev_679470FNR38L.rar(文件大小:30K) (原文件名:tuoluoyi.rar)

JamesErik 发表于 2011-9-25 16:20:40

一般进入中断之后我就把全局中断关了(没有中断优先级的情况下)

中断处理完再打开全局中断

machao 发表于 2011-9-25 20:06:20

回复【1楼】JamesErik
一般进入中断之后我就把全局中断关了(没有中断优先级的情况下)
中断处理完再打开全局中断

-----------------------------------------------------------------------

AVR响应一个中断,进入中断服务前硬件会自动将全局中断关闭的。执行返回中断指令会自动开放全局中断的。

因此,如果你采用C编写中断代码,在代码中禁止和开放全局中断,引起是后面的开放全局中断,反而可能形成中断嵌套!

比如C的中断代码最后如下:

   asm(sei);    // 开放全局中断允许
}

从C的角度看,开了中断允许就中断返回了。其实不然,因为C编译器还要增加中断现场恢复的汇编指令,最后才是执行中断返回指令。这些你在C的角度是看不到的。

但如果在执行中断现场恢复的过程中,出现了中断请求,那么CPU就会响应了,形成中断嵌套!

真正嵌入式系统的高手,汇编一定精通,哪怕他只是用C编写代码。

aishiqi1992 发表于 2011-9-25 20:10:58

回复【2楼】machao
-----------------------------------------------------------------------

我也有这种感受,看来我也要渐渐的熟悉汇编啊!

walshao 发表于 2011-9-25 23:19:43

同感啊,汇编还是不能丢

machao 发表于 2011-9-25 23:46:14

从汇编的角度是最直接的了解硬件如何工作的,可以找到隐藏很深的BUG,而不是说一定要用汇编去编写系统程序。

有了汇编的基础,说明对硬件有清楚的了解,那么在用C编程的话,就知道应该如何正确的写代码。1楼的例子就是不熟悉硬件和汇编,画蛇添足,反而错了,得不到其说的效果。而且就是出了问题,都没处找原因。
页: [1]
查看完整版本: ICC编程又遇到了两个奇怪的问题了----中断问题和赋值问题。