打印
[AVR单片机]

USART无法进入中断程序

[复制链接]
2669|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
我上面贴的程序就是纯洁的中断接收,可是就是进入不了中断程序啊,为什么呢? ...

总中断,串口中断都要打开吧...

使用特权

评论回复
5
kuangcheng100|  楼主 | 2014-6-9 14:23 | 只看该作者
ningling_21 发表于 2014-6-9 13:34
总中断,串口中断都要打开吧...

哎 测试过程中把总中断注释掉了,其实我都开了也是不行的。。。。

使用特权

评论回复
6
kuangcheng100|  楼主 | 2014-6-9 14:28 | 只看该作者
ningling_21 发表于 2014-6-9 13:34
总中断,串口中断都要打开吧...

额,不对,贴的代码还是有开全局中断的,只是用的是 sei();
而不是用SREG |=0x80;而已。。。。。。。。。。。。。。。

使用特权

评论回复
7
ningling_21| | 2014-6-9 15:02 | 只看该作者
kuangcheng100 发表于 2014-6-9 14:28
额,不对,贴的代码还是有开全局中断的,只是用的是 sei();
而不是用SREG |=0x80;而已。。。。。。。。。 ...

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

#define uchar unsigned char
#define uint  unsigned int
#define N     10

void uart0_init(void);
void uart1_init(void);
void uart0_send(uchar c);
void uart1_send(uchar c);
//void eep_to_pc(uchar eep_add);

uint sum_aver_adc;
uint sum_adc[10];
uchar k;
uint adc_rst;
uchar flag_adc_end;

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

PORTB = 0x00;//SPI接口
DDRB  = 0xff;

PORTC = 0x00; //总线高八位地址
DDRC  = 0xff;
PORTC=  0xFF;                        //设为输出口
DDRC  =0xFF;               
                 
PORTD = 0x00;//USART1接口
DDRD  = 0x00;

PORTE = 0x0f;//键盘口
DDRE  = 0xf0;

PORTF = 0x00;//LED口
DDRF  = 0xff;

PORTG = 0xff;
DDRG  = 0xff;
}
/***************串口0初始化********************/
void uart0_init(void)
{
UCSR0B = 0x00; //disable while setting baud rate
UCSR0A = 0x00;
UCSR0C = 0x06;
//UBRR0L = 0x47; //baud rate=115200
UBRR0L = 0x33;   //baud rate=9600
UBRR0H = 0x00; //
UCSR0B = 0x98;
}
/********************************************/
/********************************************/
/**************发送采用查询方式**************/
void uart0_send(uchar c)
{
  while( !(UCSR0A & (1<<UDRE0)) );
        UDR0=c;
}


/********************************************/
void main(void )
{
  uint  run_cnt=0;
  uchar i;
  CLI();
  port_init();
  uart0_init();

  SEI();
  flag_adc_end=0;
  for(i=0;i<8;i++)
  {
     uart0_send(0x55);
  }
  SEI();
  while(1)
  {
     
       
         run_cnt++;
         if(run_cnt>=60000)
         {
             run_cnt=0;
                 
                 PORTG^=BIT(4);         
         }
  }
}
/********************************************/
/********************************************/
/**************接收采用中断******************/
#pragma interrupt_handler uart0_rx_isr:19
void uart0_rx_isr(void)
{
uchar temp=0;

temp=UDR0;
      uart0_send(temp+1);
          
        PORTC^=BIT(7);
}

使用特权

评论回复
8
kuangcheng100|  楼主 | 2014-6-9 15:20 | 只看该作者
ningling_21 发表于 2014-6-9 15:02
用这个程序试试,可以进中断的

我用的是ATMEGA8L,不能直接照搬的,不过看你贴出的,和我贴的差不多啊,怎么你那边就可以,奇也怪哉!

使用特权

评论回复
9
ningling_21| | 2014-6-10 08:44 | 只看该作者
kuangcheng100 发表于 2014-6-9 15:20
我用的是ATMEGA8L,不能直接照搬的,不过看你贴出的,和我贴的差不多啊,怎么你那边就可以,奇也怪哉! ...

2方面原因,硬件或软件...

使用特权

评论回复
10
kuangcheng100|  楼主 | 2014-6-10 10:27 | 只看该作者
ningling_21 发表于 2014-6-10 08:44
2方面原因,硬件或软件...

谢谢咯,这两方面我也知道,就像问卦师,生什么孩子,他说,要嘛是男孩,要嘛是女孩。。。。。。话说,如果是外围的硬件,肯定没问题的,因为查询方式是可以的,单片机内部硬伤?可能性不大吧?

使用特权

评论回复
11
ningling_21| | 2014-6-10 12:35 | 只看该作者
kuangcheng100 发表于 2014-6-10 10:27
谢谢咯,这两方面我也知道,就像问卦师,生什么孩子,他说,要嘛是男孩,要嘛是女孩。。。。。。话说,如 ...

不要轻易怀疑芯片有问题...

使用特权

评论回复
12
mingsealtyj| | 2014-6-10 12:59 | 只看该作者
        个人感觉UCSRC设置有点问题
        UCSRC |=(1<<URSEL)|(3<<UCSZ0); //8位数据
        UCSRC &= ~((1<<UPM1)|(1<<UPM0)|(1<<USBS))|(1<<UCPOL);//异步 无校验 1个停止位

使用特权

评论回复
13
kuangcheng100|  楼主 | 2014-6-10 13:36 | 只看该作者
mingsealtyj 发表于 2014-6-10 12:59
个人感觉UCSRC设置有点问题
        UCSRC |=(1

可是我查询方式通讯是OK的啊,只是改成了中断后,连中断程序都进不了。。。

使用特权

评论回复
14
哈雷彗星| | 2014-6-23 17:23 | 只看该作者
我和楼主有同样的问题!  实在是郁闷

最近一直在找原因

使用特权

评论回复
15
le7524316| | 2015-5-10 22:29 | 只看该作者
哈雷彗星 发表于 2014-6-23 17:23
我和楼主有同样的问题!  实在是郁闷

最近一直在找原因

我也和楼上一模一样的原因,中断就是死活进不了,但是查询模式很稳定,就是接收中断进不了,全局和Re都开了,就是进不了中断程序求大神

使用特权

评论回复
16
moyansen| | 2015-5-21 23:22 | 只看该作者
我用Atmel Studio6.2编译器,ATMega16单片机与我公司的串口屏通信的一段程序,你可以参考一下
/*
* USART1.c
* Created: 2014/12/11 0:01:52
*  Author: XRDBEIJING
*/
#define  F_CPU   8000000UL //8M晶振
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define u8 unsigned char
#define u16 unsigned int
u8 RxD[20]={0};//接受缓冲区
u8 RXAA=0        //接受标志
u8 i=0;                //接收数据长度
// USART初始化
void Init_USART()
{
        UCSRB|=_BV(TXEN)|_BV(RXEN)|_BV(RXCIE);        //使能发送
        UCSRC|=_BV(URSEL)|_BV(UCSZ1)|_BV(UCSZ0);//8位数据位
        UBRRL=(F_CPU/19200/16-1)%256;
        UBRRH=(F_CPU/19200/16-1)/256;
}
//查询发送
void TxByte(u8 Byte)
{
        UDR=Byte;
        while(!(UCSRA&_BV(UDRE)));
}
//发送一个字
void TxWord(u16 Word)
{
        TxByte(Word/256);//发送高字节
        TxByte(Word%256);//发送低字节
}
// 主程序
int main()
{
        DDRD=0xf2;
        PORTD=0XFF;
        Init_USART();
        sei();
        while(1)
        {
                if (RxD[0]==0x78)
                {
                        //进行相应动作
                }
        }
}

//中断接收函数 例如接收一帧数据AA 78 0001 CC33C33C,  AA是帧头,CC33C33C是帧尾
ISR(USART_RXC_vect)
{
        u8 c;
        c=UDR;
        if(RXAA)
    {
        RxD[i] = RxD_buf;
        if((i>3)&&(RxD[i-3]==0xCC)&&(RxD[i-2]==0x33)&&(RxD[i-1]==0xC3)&&(RxD[i]==0x3C))        //帧尾用于判断结束接收数据帧
        {
           RXAA=0;
        }
        i++;
    }
    if(!RXAA && (c == 0xaa))        //帧头正确判断开始接收,接收标志RXAA置1
    {
        RXAA = 1;
        i = 0;
    }
}

使用特权

评论回复
17
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

粉丝