用定时中断后进入不了接收中断
各位:新年好!我最近写了个程序,串口接收中断里改变一个flag,然后定时中断里查询这个flag,可我发现定时中断可以照常运行,而接收中断根本进不去,这个问题我一直在解决,可是一直没有搞定,前前后后大概有一个月了,现在是又急又没头绪,望各位路过这个帖子时能指点一二,不胜感激! 什么型号的单片机,用的什么编译器,程序代码等等,什么都没有,怎么解答? 本帖最后由 双飞燕泡茶 于 2013-2-20 11:17 编辑
faw 发表于 2013-2-20 11:02 static/image/common/back.gif
什么型号的单片机,用的什么编译器,程序代码等等,什么都没有,怎么解答? ...
AVR mega8 用的是ICC,
程序代码我给个简化的:
#include "iom8v.h"
#include<macros.h>
#define fosc 8000000 //晶振8MHZ
#define baud 9600 //波特率定义
#define uchar unsigned char
#define uint unsigned int
unsigned char i=0,counter=0;
unsigned char flag=0;
unsigned char receive_cnt=0;
unsigned char my={0,0,0,0,0,0,0};
unsigned char my0={0xc0,0xa8,0xff,0xf3,0xf4,0xf5,0xf6};//0xf3,0xf4,
//1us延时函数
void delay_1us(void)
{
asm("nop");
}
//N us延时函数
void delay_nus(unsigned int n)
{
unsigned int j=0;
for (j=0;j<n;j++)
delay_1us();
}
void uart0_init(void)
{
UCSRB = 0x00;
UCSRA = 0x00;
UCSRC |= (1<<URSEL)|(1 << UCSZ1)|(1 << UCSZ0); //异步,数据格式8,N,1
UBRRL=(fosc/16/(baud+1))%256; //设置波特率寄存器
UBRRH=(fosc/16/(baud+1))/256;
UCSRB |= (1 << RXCIE)|(1 << TXEN)|(1 << RXEN); //接收中断使能,发送接收使能
}
void uart0_send(unsigned char i)
{
while(!(UCSRA&(1<<UDRE))); //只有数据寄存器为空时才能发送数据
UDR=i;
}
/*************发送数组函数*************/
void usart_shuzu_send(unsigned char arry[])
{
//unsigned char i=0;
for(i=0;i<7;i++)
{
while(!(UCSRA&BIT(UDRE)));
UDR=arry;
}
}
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x3D; //set count 25ms
TCCR0 = 0x05; //start timer
}
void init_devices(void)
{
CLI();
DDRB=0X00;
PORTB=0X00;
PORTC=0XFF;
DDRC=0XFF ;
PORTD=0X00; //USART的发送接收端口分别为PD0和PD1 //0x04
DDRD|=(1<<PD1)|(1 << PD4);
timer0_init();
MCUCR = 0x00;
GICR= 0x00;
TIMSK = 0x01;
SREG=0x80;
}
void main(void)
{
init_devices();
uart0_init();
while(1){
;
}
}
#pragma interrupt_handler USART_RXC_vect:12
void USART_RXC_vect(void)
{
uchar udr;
udr=UDR;//读取接收到的数值
PORTD|=(1<<PD4);
switch(receive_cnt)//判断是第几次中断
{
case 0: //第一次
my=udr;//记录接收值
if(my!=0x08) receive_cnt=0;break;
case 1://第二次,能执行到此处说明第一次接收到的为0X08
my=udr;//记录接收值
if(my!=0x11) receive_cnt=0;break;
case 2: //第三次,能执行到此处说明第二次接收到的为0X11
my=udr;//记录接收值
if(my!=0x01) receive_cnt=0;
else if(my==0x01){flag=1;} break;
default://>=3次,说明前三次依次为0x08 0x11 ,0x01,以后正常接收
{
my=udr;//记录当前接收值
if(receive_cnt==7) receive_cnt=0;//清零接收中断计数
}
}
}
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
SREG=0x80;
TCNT0 = 0x3D;
if(++counter>=10)
{
counter=0;
if(flag==1)
{
usart_shuzu_send(my0);
flag=0;//清零被呼叫标志
}
}
} 1.分步调试,不使用定时中断,只用接收中断,看看是否好用!判断检查硬件电路是否有问题 faw 发表于 2013-2-20 13:19 static/image/common/back.gif
1.分步调试,不使用定时中断,只用接收中断,看看是否好用!判断检查硬件电路是否有问题 ...
硬件没问题,为了赶任务,同事给我一份程序,我改了后可以在定时中断里访问接收中断置位的flag,改过来能跑,
我发现这个问题就是因为我没用定时中断时进入了接收中断,而用定时中断时却进不了,
问题好像找到了,是同事帮的忙,原因是定时中断溢出,把定时中断里的语句减少,或者加长定时中断,(本例可用time1)
页:
[1]