双飞燕泡茶 发表于 2013-2-20 10:52:35

用定时中断后进入不了接收中断

各位:新年好!
   我最近写了个程序,串口接收中断里改变一个flag,然后定时中断里查询这个flag,可我发现定时中断可以照常运行,而接收中断根本进不去,这个问题我一直在解决,可是一直没有搞定,前前后后大概有一个月了,现在是又急又没头绪,望各位路过这个帖子时能指点一二,不胜感激!

faw 发表于 2013-2-20 11:02:38

什么型号的单片机,用的什么编译器,程序代码等等,什么都没有,怎么解答?

双飞燕泡茶 发表于 2013-2-20 11:13:22

本帖最后由 双飞燕泡茶 于 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;//清零被呼叫标志
                        }                                     
       }                                                    
}

faw 发表于 2013-2-20 13:19:35

1.分步调试,不使用定时中断,只用接收中断,看看是否好用!判断检查硬件电路是否有问题

双飞燕泡茶 发表于 2013-2-20 13:40:42

faw 发表于 2013-2-20 13:19 static/image/common/back.gif
1.分步调试,不使用定时中断,只用接收中断,看看是否好用!判断检查硬件电路是否有问题 ...

硬件没问题,为了赶任务,同事给我一份程序,我改了后可以在定时中断里访问接收中断置位的flag,改过来能跑,
我发现这个问题就是因为我没用定时中断时进入了接收中断,而用定时中断时却进不了,

双飞燕泡茶 发表于 2013-2-20 16:48:48

问题好像找到了,是同事帮的忙,原因是定时中断溢出,把定时中断里的语句减少,或者加长定时中断,(本例可用time1)
页: [1]
查看完整版本: 用定时中断后进入不了接收中断