您的位置:首页 > 其它

自动产生的串口中断接收程序,支持缓冲区,比较经典的

2012-05-31 18:41 274 查看
你的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精华0UID28812








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精华0UID28812








54

主题
0

好友
349

积分
游客

莫元349

发消息

5楼




发表于 2008-9-2 19:41:23
|只看该作者

Appcat

你好,可以邮件联系你么,我想知道如何做延时,实在没这方面的经验

希望可以发邮件和你请教!
回复

举报

Appcat

Appcat
当前在线
注册时间2006-6-25最后登录2012-5-31在线时间271 小时阅读权限90积分3844帖子3458精华5UID165346








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进行需要的操作了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: