软件模拟串口程序模块
我用过的感觉比较好的软件模拟串口程序.使用方法见程序中详细说明.
多谢大家测试并指教. 我帮你贴出来
/******************************************************
使用方法:
1.在"MR_macro.h"中正确填入MCU类型及MCU主频参数
2.正确设定TX及RX引脚配置宏定义
3.确定DELAY_TX参数:
a.改宏定义#define UART_DEBUG X为 #define UART_DEBUG 1(准备调用TX_BD())
b.在main()中的端口init()后加入TX_BD());while();语句,编译并烧录
c.串行助手中若收到0x41 则其后数字即为可用的DELAY_TX值(尽量取中间值)。
4.确定DELAY_RX参数:
a.改宏定义#define UART_DEBUG X为 #define UART_DEBUG 2(准备调用RX_BD())
b.在#define DELAY_TX 0x?? 宏定义中填入上步中获得的正确值
c.在main()中的端口init()后加入RX_BD());while();语句,编译并烧录
d.串行助手以10mS为间隔时间不停发'A'(0x41),
收到的非0数字即为可用的DELAY_RX值(尽量取中间值)。
5.从调试模式改回正常使用模式:
a.改宏定义#define UART_DEBUG X为 #define UART_DEBUG 3(准备正常模式使用)
b.将上述正确的DELAY_TX及DELAY_RX值填入宏定义中
c.去掉main()中用于调试的TX_BD());while();或RX_BD());while();语句.
******************************************************/
#include "MR_macro.h"
#include "DataType.h"
#include "UART_IO.h"
//**************串口程序*********
//TX及RX引脚配置:
#define UARTPORT PORTD
#define UARTDDR DDRD
#define UARTPIN PIND
#define RXPIN PD2
#define TXPIN PD3
uchar delay_tx;
uchar delay_rx;
#define UART_DEBUG 2//1:TX_DEBUG 2:RX_DEBUG 3:NORMAL
#if UART_DEBUG==1
#define DELAY_TX delay_tx
#define DELAY_RX 0x14
#elif UART_DEBUG==2
#define DELAY_TX 0xcc//调用TX_DB()获得的正确值填入些
#define DELAY_RX delay_rx
#elif UART_DEBUG==3
//常用TX,RX参数列表:
// 1M 0x11 0x14
// 2M
// 4M 0x5d 0x68
// 6M
// 8M 0xcc 0xde
//12M
//16M
//20M
#define DELAY_TX 0xcc//调用TX_DB()获得的正确值填入些
#define DELAY_RX 0xde//调用RX_DB()获得的正确值填入些
#endif
//******IO模拟串口子程序声明********
static void wait(uchar time);//延时等待程序
void v_putchar(uchar data);//发送单个字节
uchar v_getchar(void);//接收单个字节
void v_puts(uchar *str);//发送字符串
void TX_DB(void);
void RX_DB(void);
//********子程序定义***********
void TX_DB(void)
{
//***************DELAY_TX确定程序**************
//串行助手中若收到0x41 则其后数字即为可用的DELAY_TX值。
//取尽量踞中间的值,有利于通信的稳定性
for(delay_tx=0;delay_tx<0xff;delay_tx++)
{v_putchar('A');
wait(0xff);
v_putchar(delay_tx);
wait(0xff);
}
}
void RX_DB(void)
{
/***************DELAY_RX确定程序**************/
//确定好DELAY_TX后才可确定DELAY_RX
//串行助手以10mS为间隔时间不停发'A'(0x41), 收到的非0数字即为可用的DELAY_RX值。
//取尽量踞中间的值,有利于通信的稳定性
for(delay_rx=1;delay_rx<0xff;delay_rx++)
{
if(v_getchar()==0x41) v_putchar(delay_rx);
else v_putchar(0);
}
}
void wait(uchar time)//延时等待程序
{uchar i;
for(i=0;i<time;i++);
}
//uchar delay_tx,delay_rx;//正常程序中要用DELAY_TX及DELAY_RX替换
void v_putchar(uchar data)//发单字节程序
{uchar i;
for(i=0;i<10;i++)
{if(i==0) UARTPORT&=~(1<<TXPIN);//第一次发起始位(发送脚拉低)
else if(i<9)
{if(data&0x01) UARTPORT|=(1<<TXPIN);//待发位为高,置高发送脚
else UARTPORT&=~(1<<TXPIN);//待发位为低,置低发送脚
data>>=1;//准备发下一位
}
else UARTPORT|=(1<<TXPIN);//最后发停止位
wait(DELAY_TX);//发送位延时(正常程序中要用DELAY_TX替换)
}
}
uchar v_getchar(void)//接收单字节程序
{uchar i;
uchar data;
while(UARTPIN&(1<<RXPIN));//等待起始位(若用中断方式则要删除此行)
for(i=0;i<9;i++)//接收8位数据和1位停止位
{wait(DELAY_RX);//接收位延时(正常程序中要用DELAY_RX替换)
if(i==8) break;//停止位跳出(不放入数据中)
data>>=1;//准备接收下一位
if(UARTPIN&(1<<RXPIN)) data|=0x80;//接收位为高,置高数据位
else data&=0x7f;//接收位为低,置低数据位
}
return data;//返回接收到的数据
}
void v_puts(uchar *str)//发送字符串
{
do
{
v_putchar(*str);//发送当前字符
if(*str==0xff) break;//所有字符串最后一个数据必须为0xff,发完0xff数据则结束发送
++str;//准备发下一个字符
}while(1);
}
//****************************************/
#ifndef _UART_IO_H
#define _UART_IO_H
extern unsigned char delay_tx;
extern unsigned char delay_rx;
//******IO模拟串口子程序********
extern void v_putchar(uchar data);//发送单个字节
extern uchar v_getchar(void);//接收单个字节
extern void v_puts(uchar *str);//发送字符串
extern void TX_DB(void);
extern void RX_DB(void);
//*************************************/
#endif
下来看看 感谢楼主分享,收藏备用了 STC有现成的软件包,随你移植到任何MCU,我曾经移植到STM8,很好用 谢谢楼主分享,先学习下 谢谢楼主分享,先学习下 软件延时的?
不好吧 感谢分享,琢磨研究 IO口模拟串口接收代码弄不好,刚好是需要的,谢谢楼主分享 谢谢楼主,收藏备用。 {:victory:}{:victory:}{:victory:} xyz2008 发表于 2016-2-17 08:45
STC有现成的软件包,随你移植到任何MCU,我曾经移植到STM8,很好用
多谢提醒! xyz2008 发表于 2016-2-17 08:45
STC有现成的软件包,随你移植到任何MCU,我曾经移植到STM8,很好用
STC的模拟串口要用到硬件定时器吗?
这个代码实用性较差,
软件延时;
接收函数一直等待,占资源 本帖最后由 amigenius 于 2016-2-17 17:17 编辑
用软件延时,惨不忍睹,如果你的系统没有中断且只发送几个字节,还凑合,有中断的话,误码率不知会有多高,而且还是阻塞发送和接收,CPU就在等待中度过。兄弟起码用个定时中断来处理一下吧。我另外开个贴发个用定时中断的模拟串口吧,用起来除了占一点点cpu,其余和硬件串口一样,不过当然没有硬件DMA,呵呵。
软件UART:http://www.amobbs.com/thread-5643873-1-1.html
页:
[1]