你的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 255char rx_buffer0[RX_BUFFER_SIZE0];#if RX_BUFFER_SIZE0<256unsigned char rx_wr_index0,rx_rd_index0,rx_counter0;#elseunsigned int rx_wr_index0,rx_rd_index0,rx_counter0;#endif// This flag is set on USART0 Receiver buffer overflowbit rx_buffer_overflow0;// USART0 Receiver interrupt service routineinterrupt [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 8char tx_buffer0[TX_BUFFER_SIZE0];#if TX_BUFFER_SIZE0<256unsigned char tx_wr_index0,tx_rd_index0,tx_counter0;#elseunsigned int tx_wr_index0,tx_rd_index0,tx_counter0;#endif// USART0 Transmitter interrupt service routineinterrupt [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;}elseUDR0=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 255unsigned 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进行需要的操作了