[AVR单片机] 很简单的USART程序怎么就调不出来呢? GCC编译器的

[复制链接]
5514|15
 楼主| lanlinhong 发表于 2008-9-25 11:19 | 显示全部楼层 |阅读模式
串口助手发送数据,mega16接收然后改变PORTA 
问题表现为PORTA始终为初始化的值0xff,似乎不能发生中断 
若改用软件查询则可以实现预期效果 


#include <avr/io.h> 
#include <avr/delay.h> 
#include <avr/interrupt.h> 
volatile unsigned char flag_rxc;        //串口接收完成标志 
//接收完成中断服务程序 
ISR(USART_RXC_vect){ 
        flag_rxc = 1;                                        //置位接收完成标志等待主程序处理 
        } 
//初始化 
void init(void){ 
//IO口初始化 
        DDRA  = 0xff;                        //PA输出0 
        PORTA = 0x00; 
        DDRC  = 0xff;                        //PC输出0 
        PORTC = 0x00; 
        DDRB  = 0x10;                        //PB7~5用于ISP,PB4输出0,PB3~1输入且上拉使能 
        PORTB = 0x0f; 
        DDRD  = 0x0c;                        //PD7~4输入且上拉使能,PD3~2输出0,PD1~0用于USART 
        PORTD = 0xf0; 
//串口初始化 
//UCSRA:   RXC | TXC |UDRE | FE  | DOR | PE  | U2X |MPCM 
//UCSRB:  RXCIE|TXCIE|UDRIE|RXEN |TXEN |UCSZ2|RXB8 |TXB8 
//UCSRC:  URSEL|UMSEL|UPM1 |UPM0 |USBS |UCSZ1|UCSZ0|UCPOL 
        UCSRB = 0x00;                        //禁止中断,禁止发送接收数据 
        UCSRA = 0x00;                        //正常波特率,接收器正常接收 
        UCSRC = 0x86;                        //异步模式,8位数据位,1位停止位,无效验位 
        UBRRL = 0x47;                        //波特率9600 
        UBRRH = 0x00;                        //115200:0x0003,19200:0x0017,9600:0x002f,4800:0x005f,2400:0x00bf 
        UCSRB = 0x90;                        //允许RXC中断,允许接收 
        sei();                                        //开全局中断 
        } 
// 
int main(void){ 
        init();                                        //初始化 
        PORTA=0xff; 
        _delay_ms(1000); 
        while(1){                                //主循环 
                if(flag_rxc){ 
                        PORTA=0x08; 
                        } 
                } 
        return 0; 
        } 
coldra 发表于 2008-9-25 11:26 | 显示全部楼层

中断函数名

winavr中我常用例如SIGNAL(SIG_USART_RECV)的形式
 楼主| lanlinhong 发表于 2008-9-25 14:04 | 显示全部楼层

SIGNAL(SIG_USART_RECV)

试过SIGNAL(SIG_USART_RECV)还是不成功,应该试进不了中断的问题
John_Lee 发表于 2008-9-25 15:23 | 显示全部楼层

要读UDR

在isr中要把UDR读走,或者把禁止RXCIE,否则,中断将一直发生(isr刚返回又进入)。看看datasheet:

Bit 7 – RXC: USART Receive Complete
This flag bit is set when there are unread data in the receive buffer and cleared when the receive
buffer is empty (i.e., does not contain any unread data). If the Receiver is disabled, the receive
buffer will be flushed and consequently the RXC bit will become zero. The RXC Flag can be
used to generate a Receive Complete interrupt (see description of the RXCIE bit).
coldra 发表于 2008-9-25 15:36 | 显示全部楼层

楼上正解

 楼主| lanlinhong 发表于 2008-9-25 15:56 | 显示全部楼层

4楼分析得有道理,确实存在没有读数据操作的错误,但
我定义全局变量unsigned char rx_data;
中断程序改
ISR(USART_RXC_vect){ 
        rx_data=UCSRA;//读标志
        rx_data=UDR;//读数据
        flag_rxc = 1;//置位接收完成标志等待主程序处理
        } 
故障依然。

我把 PORTA=0x08;插入ISR(USART_RXC_vect){ },用串口助手发送数据到单片机,PORTA就应该等于0x80,但是也达不到预期效果
coldra 发表于 2008-9-25 16:04 | 显示全部楼层

软件仿真没问题了

 楼主| lanlinhong 发表于 2008-9-25 16:25 | 显示全部楼层

中断入口ISR(USART_RXC_vect)会有问题吗,好多人用SIGNAL(SIG_USART_RECV)
John_Lee 发表于 2008-9-25 18:01 | 显示全部楼层

SIGNAL已经过时了,推荐用ISR

SIG_* 也过时了,推荐用 *_vect。
 楼主| lanlinhong 发表于 2008-9-26 09:11 | 显示全部楼层

ISR(USART_RXC_vect) 这个应该可以用吧
John_Lee 发表于 2008-9-26 12:26 | 显示全部楼层

dump出来看看

avr-objdump -S elf文件 > lss

生成的 lss 是个文本文件,把它贴上来看看。
 楼主| lanlinhong 发表于 2008-9-26 13:49 | 显示全部楼层

是生成汇编吗,生成汇编文件的Makefile文件怎么写?
John_Lee 发表于 2008-9-27 12:40 | 显示全部楼层

不用动makefile

直接在命令提示符下输入:avr-objdump -S 输入文件名 > 输出文件名 就可以了。“输入文件名是经编译链接后得到的文件,是elf格式的,通常文件的后缀为.elf。输出文件名随便给一个就行,这个文件是要被创建的。执行后,把这个输出文件的内容贴上来。
 楼主| lanlinhong 发表于 2008-9-27 21:48 | 显示全部楼层

-

问题已解决,configuration options里器件设置不对导致中断进不去
谢谢John_Lee,也谢谢各位
pyy1234 发表于 2010-11-12 08:47 | 显示全部楼层
到底哪里设置不对啊
crazyleen 发表于 2010-11-18 15:14 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

44

帖子

0

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