[AVR单片机] USART无法进入中断程序

[复制链接]
3149|16
 楼主| kuangcheng100 发表于 2014-6-7 18:42 | 显示全部楼层 |阅读模式
问题如题,各种中断程序的形式都试了就是进入不了中断。代码:
#include<avr/common.h>
#include<avr/io.h>
#include<avr/interrupt.h>
#include<util/delay.h>
#include<stdio.h>

unsigned char aaa,sendata[10],icount = 0;

void delay_ms (unsigned int time)
{
  unsigned int i;
  for (i=0;i<time;i++)
  {
          
  }
         
}

//#pragma interrupt_handler uart_rx_isr:14
//void uart_rx_isr(void)
SIGNAL(_VECTOR(13))
{  
        cli();
        PORTB = 0x00;
        if(icount<4)  
        {   
                sendata[icount]=UDR;//每次接受4个字符   
                icount++;  
        }  
        else     
        {   
                icount=0;
                sendchar(sendata);     
        }  
        sei();
}

void usart_init(void)
{
   unsigned char i;
   PORTD = 0XFF;
   DDRD = 0X02;   //TX设置为输出
   UCSRB = 0x00; //disable while setting baud rate
   UCSRA = 0x02; //倍速发送
   UCSRC = 0x06; //异步/禁止奇偶校验/1停止位/8位数据
   UBRRL = 0x0c; //set baud rate lo
   UBRRH = 0x00; //set baud rate hi
   UCSRB = 0x98; //接收中断使能/接收、发送使能
   //SREG |= 0x80;  //开全局中断
   for (i=0;i<10;i++)
   {
           sendata[i]=0;
   }
                                    
}

void usart_putc(unsigned char data)
{
        while ( !( UCSRA & (1<<UDRE)) );
        UDR = data;
}
  
unsigned char usart_getc(void)
{
        while ( !(UCSRA & (1<<RXC)) );

        return UDR;
}

void sendchar(char *s)
{
        while(*s)
        {
                usart_putc(*s);
                s++;
        }
}

void main(void)
{
       
        unsigned char getdata[10],i;
        DDRB = 0xff;
        usart_init();
        sei();
        PORTB = 0x01;
        while(1)
        {   
                //while ( !(UCSRA & (1<<RXC)) );
        //aaa = UDR;
//
                //if (aaa == "V" || aaa == 0x56)
                //{
                        //sendchar("0X0327");
                        //sendchar("@_@");
                        //usart_putc(0X0D );
                        //usart_putc(0X0A );
                //}
                //if (aaa == "T" || aaa == 0X54)
                //{
                        //sendchar("0X001EC08A2747");
                        //sendchar("@_@");
                        //usart_putc(0X0D );
                        //usart_putc(0X0A );
                //}
               
        }
}

代码中的查询可以接收到数据,但是,如果查询没注释掉,一开中断,查询方式也接收不大数据了。。。
请高手不吝看下,问题在哪啊
ningling_21 发表于 2014-6-9 11:31 | 显示全部楼层
中断和查询本来就是矛盾的...

最好发送用查询,接收用中断....
 楼主| kuangcheng100 发表于 2014-6-9 13:07 | 显示全部楼层
ningling_21 发表于 2014-6-9 11:31
中断和查询本来就是矛盾的...

最好发送用查询,接收用中断....

我上面贴的程序就是纯洁的中断接收,可是就是进入不了中断程序啊,为什么呢?
ningling_21 发表于 2014-6-9 13:34 | 显示全部楼层
kuangcheng100 发表于 2014-6-9 13:07
我上面贴的程序就是纯洁的中断接收,可是就是进入不了中断程序啊,为什么呢? ...

总中断,串口中断都要打开吧...
 楼主| kuangcheng100 发表于 2014-6-9 14:23 | 显示全部楼层
ningling_21 发表于 2014-6-9 13:34
总中断,串口中断都要打开吧...

哎 测试过程中把总中断注释掉了,其实我都开了也是不行的。。。。
 楼主| kuangcheng100 发表于 2014-6-9 14:28 | 显示全部楼层
ningling_21 发表于 2014-6-9 13:34
总中断,串口中断都要打开吧...

额,不对,贴的代码还是有开全局中断的,只是用的是 sei();
而不是用SREG |=0x80;而已。。。。。。。。。。。。。。。
ningling_21 发表于 2014-6-9 15:02 | 显示全部楼层
kuangcheng100 发表于 2014-6-9 14:28
额,不对,贴的代码还是有开全局中断的,只是用的是 sei();
而不是用SREG |=0x80;而已。。。。。。。。。 ...

用这个程序试试,可以进中断的
  1. //ICC-AVR application builder
  2. // Target : M128
  3. // Crystal: 11059200
  4. #include <iom128v.h>
  5. #include <macros.h>

  6. #define uchar unsigned char
  7. #define uint  unsigned int
  8. #define N     10

  9. void uart0_init(void);
  10. void uart1_init(void);
  11. void uart0_send(uchar c);
  12. void uart1_send(uchar c);
  13. //void eep_to_pc(uchar eep_add);

  14. uint sum_aver_adc;
  15. uint sum_adc[10];
  16. uchar k;
  17. uint adc_rst;
  18. uchar flag_adc_end;

  19. /******************端口初始化***************************/
  20. void port_init(void)
  21. { //端口设置
  22. PORTA = 0x00;//LCD口,总线低八位地址
  23. DDRA  = 0x00;

  24. PORTB = 0x00;//SPI接口
  25. DDRB  = 0xff;

  26. PORTC = 0x00; //总线高八位地址
  27. DDRC  = 0xff;
  28. PORTC=  0xFF;                        //设为输出口
  29. DDRC  =0xFF;               
  30.                  
  31. PORTD = 0x00;//USART1接口
  32. DDRD  = 0x00;

  33. PORTE = 0x0f;//键盘口
  34. DDRE  = 0xf0;

  35. PORTF = 0x00;//LED口
  36. DDRF  = 0xff;

  37. PORTG = 0xff;
  38. DDRG  = 0xff;
  39. }
  40. /***************串口0初始化********************/
  41. void uart0_init(void)
  42. {
  43. UCSR0B = 0x00; //disable while setting baud rate
  44. UCSR0A = 0x00;
  45. UCSR0C = 0x06;
  46. //UBRR0L = 0x47; //baud rate=115200
  47. UBRR0L = 0x33;   //baud rate=9600
  48. UBRR0H = 0x00; //
  49. UCSR0B = 0x98;
  50. }
  51. /********************************************/
  52. /********************************************/
  53. /**************发送采用查询方式**************/
  54. void uart0_send(uchar c)
  55. {
  56.   while( !(UCSR0A & (1<<UDRE0)) );
  57.         UDR0=c;
  58. }


  59. /********************************************/
  60. void main(void )
  61. {
  62.   uint  run_cnt=0;
  63.   uchar i;
  64.   CLI();
  65.   port_init();
  66.   uart0_init();

  67.   SEI();
  68.   flag_adc_end=0;
  69.   for(i=0;i<8;i++)
  70.   {
  71.      uart0_send(0x55);
  72.   }
  73.   SEI();
  74.   while(1)
  75.   {
  76.      
  77.        
  78.          run_cnt++;
  79.          if(run_cnt>=60000)
  80.          {
  81.              run_cnt=0;
  82.                  
  83.                  PORTG^=BIT(4);         
  84.          }
  85.   }
  86. }
  87. /********************************************/
  88. /********************************************/
  89. /**************接收采用中断******************/
  90. #pragma interrupt_handler uart0_rx_isr:19
  91. void uart0_rx_isr(void)
  92. {
  93. uchar temp=0;

  94. temp=UDR0;
  95.       uart0_send(temp+1);
  96.           
  97.         PORTC^=BIT(7);
  98. }
 楼主| kuangcheng100 发表于 2014-6-9 15:20 | 显示全部楼层
ningling_21 发表于 2014-6-9 15:02
用这个程序试试,可以进中断的

我用的是ATMEGA8L,不能直接照搬的,不过看你贴出的,和我贴的差不多啊,怎么你那边就可以,奇也怪哉!
ningling_21 发表于 2014-6-10 08:44 | 显示全部楼层
kuangcheng100 发表于 2014-6-9 15:20
我用的是ATMEGA8L,不能直接照搬的,不过看你贴出的,和我贴的差不多啊,怎么你那边就可以,奇也怪哉! ...

2方面原因,硬件或软件...
 楼主| kuangcheng100 发表于 2014-6-10 10:27 | 显示全部楼层
ningling_21 发表于 2014-6-10 08:44
2方面原因,硬件或软件...

谢谢咯,这两方面我也知道,就像问卦师,生什么孩子,他说,要嘛是男孩,要嘛是女孩。。。。。。话说,如果是外围的硬件,肯定没问题的,因为查询方式是可以的,单片机内部硬伤?可能性不大吧?
ningling_21 发表于 2014-6-10 12:35 | 显示全部楼层
kuangcheng100 发表于 2014-6-10 10:27
谢谢咯,这两方面我也知道,就像问卦师,生什么孩子,他说,要嘛是男孩,要嘛是女孩。。。。。。话说,如 ...

不要轻易怀疑芯片有问题...
mingsealtyj 发表于 2014-6-10 12:59 | 显示全部楼层
        个人感觉UCSRC设置有点问题
        UCSRC |=(1<<URSEL)|(3<<UCSZ0); //8位数据
        UCSRC &= ~((1<<UPM1)|(1<<UPM0)|(1<<USBS))|(1<<UCPOL);//异步 无校验 1个停止位
 楼主| kuangcheng100 发表于 2014-6-10 13:36 | 显示全部楼层
mingsealtyj 发表于 2014-6-10 12:59
个人感觉UCSRC设置有点问题
        UCSRC |=(1

可是我查询方式通讯是OK的啊,只是改成了中断后,连中断程序都进不了。。。
哈雷彗星 发表于 2014-6-23 17:23 | 显示全部楼层
我和楼主有同样的问题!  实在是郁闷

最近一直在找原因
le7524316 发表于 2015-5-10 22:29 | 显示全部楼层
哈雷彗星 发表于 2014-6-23 17:23
我和楼主有同样的问题!  实在是郁闷

最近一直在找原因

我也和楼上一模一样的原因,中断就是死活进不了,但是查询模式很稳定,就是接收中断进不了,全局和Re都开了,就是进不了中断程序求大神
moyansen 发表于 2015-5-21 23:22 | 显示全部楼层
我用Atmel Studio6.2编译器,ATMega16单片机与我公司的串口屏通信的一段程序,你可以参考一下
  1. /*
  2. * USART1.c
  3. * Created: 2014/12/11 0:01:52
  4. *  Author: XRDBEIJING
  5. */
  6. #define  F_CPU   8000000UL //8M晶振
  7. #include <avr/io.h>
  8. #include <avr/interrupt.h>
  9. #include <util/delay.h>
  10. #define u8 unsigned char
  11. #define u16 unsigned int
  12. u8 RxD[20]={0};//接受缓冲区
  13. u8 RXAA=0        //接受标志
  14. u8 i=0;                //接收数据长度
  15. // USART初始化
  16. void Init_USART()
  17. {
  18.         UCSRB|=_BV(TXEN)|_BV(RXEN)|_BV(RXCIE);        //使能发送
  19.         UCSRC|=_BV(URSEL)|_BV(UCSZ1)|_BV(UCSZ0);//8位数据位
  20.         UBRRL=(F_CPU/19200/16-1)%256;
  21.         UBRRH=(F_CPU/19200/16-1)/256;
  22. }
  23. //查询发送
  24. void TxByte(u8 Byte)
  25. {
  26.         UDR=Byte;
  27.         while(!(UCSRA&_BV(UDRE)));
  28. }
  29. //发送一个字
  30. void TxWord(u16 Word)
  31. {
  32.         TxByte(Word/256);//发送高字节
  33.         TxByte(Word%256);//发送低字节
  34. }
  35. // 主程序
  36. int main()
  37. {
  38.         DDRD=0xf2;
  39.         PORTD=0XFF;
  40.         Init_USART();
  41.         sei();
  42.         while(1)
  43.         {
  44.                 if (RxD[0]==0x78)
  45.                 {
  46.                         //进行相应动作
  47.                 }
  48.         }
  49. }

  50. //中断接收函数 例如接收一帧数据AA 78 0001 CC33C33C,  AA是帧头,CC33C33C是帧尾
  51. ISR(USART_RXC_vect)
  52. {
  53.         u8 c;
  54.         c=UDR;
  55.         if(RXAA)
  56.     {
  57.         RxD[i] = RxD_buf;
  58.         if((i>3)&&(RxD[i-3]==0xCC)&&(RxD[i-2]==0x33)&&(RxD[i-1]==0xC3)&&(RxD[i]==0x3C))        //帧尾用于判断结束接收数据帧
  59.         {
  60.            RXAA=0;
  61.         }
  62.         i++;
  63.     }
  64.     if(!RXAA && (c == 0xaa))        //帧头正确判断开始接收,接收标志RXAA置1
  65.     {
  66.         RXAA = 1;
  67.         i = 0;
  68.     }
  69. }
hsb.siq 发表于 2015-5-25 12:23 | 显示全部楼层
本帖最后由 hsb.siq 于 2015-5-25 12:26 编辑

//串行接收结束中断服务程序
//#pragma interrupt_handler uart0_rx_isr:12
//void uart0_rx_isr(void)
//SIGNAL(SIG_UART_RECV)
//SIGNAL(SIG_UART_RECV)// USART 接收完成
ISR(USART_RXC_vect)
中断函数的问题,这几个只有下面词句能用。
不知为什么,高手们可以解释下么?
从编译的中断地址跳转就可以看得到,
您需要登录后才可以回帖 登录 | 注册

本版积分规则

29

主题

72

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部