你的mega128的串口接收程序写的有问题,和什么模块都无关。串口中断是每收到一个字符就会产生一次的,所以你不要看到中断了 就急着处理,收的东西还没全呢,怎么处理啊,要想办法收全了再处理。建议你看看别人的串口接收中断处理代码。 最最最简单的办法,做个延时,等所有的字符都收齐了,再处理。或者开缓冲区,根据缓冲区的长度来判断是否都接收完毕。 下面是用CVAVR自动产生的串口中断接收程序,支持缓冲区,比较经典的: #include <mega128.h> #define RXB8 1 #define TXB8 0 #define UPE 2 #define OVR 3 #define FE 4 #define UDRE 5 #define RXC 7 #define FRAMING_ERROR (1<<FE) #define PARITY_ERROR (1<<UPE) #define DATA_OVERRUN (1<<OVR) #define DATA_REGISTER_EMPTY (1<<UDRE) #define RX_COMPLETE (1<<RXC) // USART0 Receiver buffer #define RX_BUFFER_SIZE0 255 char rx_buffer0[RX_BUFFER_SIZE0]; #if RX_BUFFER_SIZE0<256 unsigned char rx_wr_index0,rx_rd_index0,rx_counter0; #else unsigned int rx_wr_index0,rx_rd_index0,rx_counter0; #endif // This flag is set on USART0 Receiver buffer overflow bit rx_buffer_overflow0; // USART0 Receiver interrupt service routine interrupt [USART0_RXC] void usart0_rx_isr(void) { char status,data; status=UCSR0A; data=UDR0; if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) { rx_buffer0[rx_wr_index0]=data; if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0; if (++rx_counter0 == RX_BUFFER_SIZE0) { rx_counter0=0; rx_buffer_overflow0=1; }; }; } #ifndef _DEBUG_TERMINAL_IO_ // Get a character from the USART0 Receiver buffer #define _ALTERNATE_GETCHAR_ #pragma used+ char getchar(void) { char data; while (rx_counter0==0); data=rx_buffer0[rx_rd_index0]; if (++rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0; #asm("cli") --rx_counter0; #asm("sei") return data; } #pragma used- #endif // USART0 Transmitter buffer #define TX_BUFFER_SIZE0 8 char tx_buffer0[TX_BUFFER_SIZE0]; #if TX_BUFFER_SIZE0<256 unsigned char tx_wr_index0,tx_rd_index0,tx_counter0; #else unsigned int tx_wr_index0,tx_rd_index0,tx_counter0; #endif // USART0 Transmitter interrupt service routine interrupt [USART0_TXC] void usart0_tx_isr(void) { if (tx_counter0) { --tx_counter0; UDR0=tx_buffer0[tx_rd_index0]; if (++tx_rd_index0 == TX_BUFFER_SIZE0) tx_rd_index0=0; }; } #ifndef _DEBUG_TERMINAL_IO_ // Write a character to the USART0 Transmitter buffer #define _ALTERNATE_PUTCHAR_ #pragma used+ void putchar(char c) { while (tx_counter0 == TX_BUFFER_SIZE0); #asm("cli") if (tx_counter0 || ((UCSR0A & DATA_REGISTER_EMPTY)==0)) { tx_buffer0[tx_wr_index0]=c; if (++tx_wr_index0 == TX_BUFFER_SIZE0) tx_wr_index0=0; ++tx_counter0; } else UDR0=c; #asm("sei") } #pragma used- #endif 回复 举报 lwking412 lwking412 当前离线 注册时间 2008-4-15 最后登录 2012-3-20 在线时间 0 小时 阅读权限 1 积分 349 帖子 241 精华 0 UID 28812 54 主题 0 好友 349 积分 游客 莫元 349 发消息 4楼 发表于 2008-9-2 19:27:55 | 只看该作者 好复杂,头都大了,一定要开辟缓冲区么,我直接接收就不可以么? 1做个延时,等所有的字符都收齐了,再处理。 问题是怎么延时呢?可否简单介绍一下 2或者开缓冲区,根据缓冲区的长度来判断是否都接收完毕。 开辟缓冲区我有点思路,可以参考马老师书上的,但是根据缓冲区的长度我还不是很明白这句话,如果我能判断接收完毕后就好了,手机发送的是那么一大串字符! 本身就不是学习编程出身的,老师非让我做这个不做完不行啊! 回复 举报 lwking412 lwking412 当前离线 注册时间 2008-4-15 最后登录 2012-3-20 在线时间 0 小时 阅读权限 1 积分 349 帖子 241 精华 0 UID 28812 54 主题 0 好友 349 积分 游客 莫元 349 发消息 5楼 发表于 2008-9-2 19:41:23 | 只看该作者 Appcat 你好,可以邮件联系你么,我想知道如何做延时,实在没这方面的经验 希望可以发邮件和你请教! 回复 举报 Appcat Appcat 当前在线 注册时间 2006-6-25 最后登录 2012-5-31 在线时间 271 小时 阅读权限 90 积分 3844 帖子 3458 精华 5 UID 165346 68 主题 0 好友 3844 积分 论坛元老 苹果猫 莫元 3844 发消息 6楼 发表于 2008-9-2 19:44:08 | 只看该作者 手机发送的东西,总要有个上限吧,不可能是无限的吧,所以把你系统需要处理的最长长度+1做为缓冲区长度总可以吧。其实 英文短信才几个字符啊?上面我贴的程序里边开了255个字符,绝对够用了。 仔细看看上面的程序,里边有一个变量rx_counter0,这个就是关键所在。你在主程序里边判断rx_counter0是否不为零,如果 不为零,说明串口已经有东西进来了,计算一下你的波特率和最大长度,做一个延时,保证串口缓冲区能够收到所有字符,然后 取出整个缓冲区,你的完整短信已经在里边了,该怎么处理就怎么处理了。 #define MAX_BUF_LENS 255 unsigned char buf[MAX_BUF_LENS], i //初始化,首先清空串口缓冲区,防止残留的字符干扰 while (rx_counter0) getchar(); memset(buf, 0, MAX_BUF_LENS); ...................... //自己做循环,检测rx_counter0是否不为零 while (!rx_counter0); //延时100毫秒,具体多少需要自己算,这个时间宜长不宜短 delay_ms(100); i = 0; while (rx_counter0) { buf = getchar(); i++; } //到这里,串口过来的短信已经完整的存放在buf中了,你可以对buf进行需要的操作了