找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2508|回复: 1
收起左侧

stm32串口不够用,求GPIO模拟串口程序

[复制链接]
ID:396134 发表于 2018-9-10 17:37 | 显示全部楼层 |阅读模式
本人最近在做一个项目,串口不够用,想用俩个io口进行模拟一个串口的功能
回复

使用道具 举报

ID:387733 发表于 2018-9-11 08:16 | 显示全部楼层
下面是很详细的51系列模拟串口的程序,可供参考或移植


/*************        本程序功能说明        **************

                                测试说明

        本例程是使用STC系列MCU做的模拟串口。用户根据自己的时钟和波特率自行设置后编译下载。
       
        使用串口助手向MCU发送数据,MCU收到后原样返回给PC。
       
        本例程使用资源: Timer0中断.

*/

#include "config.h"


/***************************************************************************/

typedef bit BOOL;
typedef unsigned char         uchar;
typedef unsigned int         uint;

#define Timer0_Reload                (65536 - MAIN_Fosc / BaudRate / 3)
#define D_RxBitLenth        9                //9: 8 + 1 stop
#define D_TxBitLenth        9                //9: 1 stop bit

sbit RXB = P3^0;                //define UART TX/RX port
sbit TXB = P3^1;

uchar  data TBUF,RBUF;
uchar  data TDAT,RDAT;
uchar  data TCNT,RCNT;        //发送和接收检测 计数器(3倍速率检测)
uchar  data TBIT,RBIT;        //发送和接收的数据计数器
uchar  data t, r;
uchar  data buf[16];

bit  TING,RING;        //正在发送或接收一个字节
bit  REND;                 //接收完的标志位

#define        RxBitLenth        9        //8个数据位+1个停止位
#define        TxBitLenth        9        //8个数据位+1个停止位

//-----------------------------------------
//UART模块的初始变量        initial UART module variable
void UART_INIT()
{
      TING = 0;
      RING = 0;
      REND = 0;
      TCNT = 0;
      RCNT = 0;
}

void main()
{
        InternalRAM_enable();
//        ExternalRAM_enable();

        Timer0_1T();
        Timer0_AsTimer();
        Timer0_16bitAutoReload();
        Timer0_Load(Timer0_Reload);
        Timer0_InterruptEnable();
        Timer0_Run();
        EA = 1;                                        //打开总中断                                       

        UART_INIT();                                //UART模块的初始变量

        while (1)
        {
                if (REND)                                //如果接收完,把接收到的值存入接收buff
                {
                        REND = 0;
                        buf[r++ & 0x0f] = RBUF;
                }

                if(!TING)                //发送空闲
                {
                        if (t != r)        //有要发送的数据
                        {
                                TBUF = buf[t++ & 0x0f];
                                TING = 1;
                        }
                }
        }
}


//-----------------------------------------
//定时器0中断程序for UART 以波特率3倍的速度采样判断 开始位               

void tm0(void) interrupt 1
{

        if (RING)
        {
                if (--RCNT == 0)                                  //接收数据以定时器的1/3来接收
                {
                        RCNT = 3;                                 //重置接收计数器  接收数据以定时器的1/3来接收
                                
                        if (--RBIT == 0)                          //接收完一帧数据
                        {
                                RBUF = RDAT;            //存储数据到缓冲区       
                                RING = 0;               //停止接收                       
                                REND = 1;               //接收完成标志设置       
                        }
                        else
                        {
                                RDAT >>= 1;                          //把接收的单b数据 暂存到 RDAT(接收缓冲)
                                if (RXB) RDAT |= 0x80;       //shift RX data to RX buffer
                        }
                }
        }

        else if (!RXB)                //判断是不是开始位 RXB=0;
        {
                RING = 1;       //如果是则设置开始接收标志位         set start receive flag
                RCNT = 4;       //初始化接收波特率计数器               initial receive baudrate counter
                RBIT = RxBitLenth;       //初始化接收的数据位数(8个数据位+1个停止位)   
        }

        if (TING)                        //发送开始标志位   judge whether sending
        {
                if (--TCNT == 0)                        //发送数据以定时器的1/3来发送
                {
                        TCNT = 3;                                //重置发送计数器   reset send baudrate counter
                        if (TBIT == 0)                        //发送计数器为0 表明单字节发送还没开始
                        {
                                TXB = 0;                        //发送开始位                                             send start bit
                                TDAT = TBUF;                //把缓冲的数据放到发送的buff               
                                TBIT = TxBitLenth;        //发送数据位数 (8数据位+1停止位)       
                        }
                        else                                        //发送计数器为非0 正在发送数据
                        {
                                if (--TBIT == 0)        //发送计数器减为0 表明单字节发送结束
                                {
                                        TXB = 1;                //送停止位数据
                                        TING = 0;                //发送停止位                            stop send
                                }
                                else
                                {
                                        TDAT >>= 1;                //把最低位送到 CY(益处标志位) shift data to CY
                                        TXB = CY;                //发送单b数据                                write CY to TX port
                                }
                        }
                }
        }
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表