自动产生的串口中断接收程序,支持缓冲区,比较经典的
来源:互联网 发布:imap端口 编辑:程序博客网 时间:2024/06/15 20:48
你的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
就急着处理,收的东西还没全呢,怎么处理啊,要想办法收全了再处理。建议你看看别人的串口接收中断处理代码。
最最最简单的办法,做个延时,等所有的字符都收齐了,再处理。或者开缓冲区,根据缓冲区的长度来判断是否都接收完毕。
下面是用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
![查看详细资料](http://www.ourdev.cn/static/image/common/userinfo.gif)
![](http://passport.ourdev.cn/uc_server/images/noavatar_middle.gif)
54
主题0
好友349
积分游客
- 莫元
- 349
- 发消息
4楼
|只看该作者
![](http://www.ourdev.cn/static/image/common/online_member.gif)
好复杂,头都大了,一定要开辟缓冲区么,我直接接收就不可以么?
1做个延时,等所有的字符都收齐了,再处理。 问题是怎么延时呢?可否简单介绍一下
2或者开缓冲区,根据缓冲区的长度来判断是否都接收完毕。 开辟缓冲区我有点思路,可以参考马老师书上的,但是根据缓冲区的长度我还不是很明白这句话,如果我能判断接收完毕后就好了,手机发送的是那么一大串字符!
本身就不是学习编程出身的,老师非让我做这个不做完不行啊!
1做个延时,等所有的字符都收齐了,再处理。 问题是怎么延时呢?可否简单介绍一下
2或者开缓冲区,根据缓冲区的长度来判断是否都接收完毕。 开辟缓冲区我有点思路,可以参考马老师书上的,但是根据缓冲区的长度我还不是很明白这句话,如果我能判断接收完毕后就好了,手机发送的是那么一大串字符!
本身就不是学习编程出身的,老师非让我做这个不做完不行啊!
回复
举报
lwking412
lwking412当前离线
- 注册时间
- 2008-4-15
- 最后登录
- 2012-3-20
- 在线时间
- 0 小时
- 阅读权限
- 1
- 积分
- 349
- 帖子
- 241
- 精华
- 0
- UID
- 28812
![查看详细资料](http://www.ourdev.cn/static/image/common/userinfo.gif)
![](http://passport.ourdev.cn/uc_server/images/noavatar_middle.gif)
54
主题0
好友349
积分游客
- 莫元
- 349
- 发消息
5楼
|只看该作者
![](http://www.ourdev.cn/static/image/common/online_member.gif)
Appcat
你好,可以邮件联系你么,我想知道如何做延时,实在没这方面的经验
希望可以发邮件和你请教!
你好,可以邮件联系你么,我想知道如何做延时,实在没这方面的经验
希望可以发邮件和你请教!
回复
举报
Appcat
Appcat当前在线
- 注册时间
- 2006-6-25
- 最后登录
- 2012-5-31
- 在线时间
- 271 小时
- 阅读权限
- 90
- 积分
- 3844
- 帖子
- 3458
- 精华
- 5
- UID
- 165346
![查看详细资料](http://www.ourdev.cn/static/image/common/userinfo.gif)
![](http://passport.ourdev.cn/uc_server/data/avatar/000/16/53/46_avatar_middle.jpg)
68
主题0
好友3844
积分论坛元老
- 莫元
- 3844
- 发消息
6楼
|只看该作者
![](http://www.ourdev.cn/static/image/common/online_member.gif)
手机发送的东西,总要有个上限吧,不可能是无限的吧,所以把你系统需要处理的最长长度+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进行需要的操作了
英文短信才几个字符啊?上面我贴的程序里边开了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进行需要的操作了
- 自动产生的串口中断接收程序,支持缓冲区,比较经典的
- 比较经典的中断串口接收方法
- 串口的中断和接收
- 比较经典的中断串口接口的方法
- 串口接收缓冲区的一点体会
- STM32的接收中断和发送中断同时使能会导致程序死在初始化串口那里。
- STC12C5A60S2 串口中断接收程序
- stm32的串口空闲中断接收数据
- stm32的串口空闲中断接收数据
- 串口中断接收的常见处理方法
- 串口中断结合定时器实现稳定可靠的串口接收
- STM32串口中断接收方式详细比较
- 串口中断接收方式详细比较
- STM32串口中断接收方式详细比较
- STM32串口中断接收方式详细比较
- 串口中断接收方式详细比较
- STM32串口中断接收方式详细比较
- STM32串口中断接收方式详细比较
- PostgreSQL的日志系统
- Oracle查询锁表sql,解除锁表sql
- objective-C中的接口与泛型
- 享元模式 理解深刻啊
- 微软企业库缓存
- 自动产生的串口中断接收程序,支持缓冲区,比较经典的
- sim300模块AT指令C语言定义源码
- 大数四则运算的C++实现
- Binder学习笔记---深入理解Android
- iphone 推送服务--Apple Push Notification Service
- 云计算正在改变IT行业的格局
- cocoa touch layer下面的几个点连载之--CoreGraphics
- iPhone读取和写入plist文件
- 2440裸机编程之十一 GPRS