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) 一般进入中断之后我就把全局中断关了(没有中断优先级的情况下)
中断处理完再打开全局中断 回复【1楼】JamesErik
一般进入中断之后我就把全局中断关了(没有中断优先级的情况下)
中断处理完再打开全局中断
-----------------------------------------------------------------------
AVR响应一个中断,进入中断服务前硬件会自动将全局中断关闭的。执行返回中断指令会自动开放全局中断的。
因此,如果你采用C编写中断代码,在代码中禁止和开放全局中断,引起是后面的开放全局中断,反而可能形成中断嵌套!
比如C的中断代码最后如下:
asm(sei); // 开放全局中断允许
}
从C的角度看,开了中断允许就中断返回了。其实不然,因为C编译器还要增加中断现场恢复的汇编指令,最后才是执行中断返回指令。这些你在C的角度是看不到的。
但如果在执行中断现场恢复的过程中,出现了中断请求,那么CPU就会响应了,形成中断嵌套!
真正嵌入式系统的高手,汇编一定精通,哪怕他只是用C编写代码。 回复【2楼】machao
-----------------------------------------------------------------------
我也有这种感受,看来我也要渐渐的熟悉汇编啊! 同感啊,汇编还是不能丢 从汇编的角度是最直接的了解硬件如何工作的,可以找到隐藏很深的BUG,而不是说一定要用汇编去编写系统程序。
有了汇编的基础,说明对硬件有清楚的了解,那么在用C编程的话,就知道应该如何正确的写代码。1楼的例子就是不熟悉硬件和汇编,画蛇添足,反而错了,得不到其说的效果。而且就是出了问题,都没处找原因。
页:
[1]