找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1560|回复: 2
打印 上一主题 下一主题
收起左侧

学习UART串口通信的例程,单片机好像没有接受到电脑发送的命令

[复制链接]
跳转到指定楼层
楼主
大致就是根据电脑发送的不同命令执行相关操作,并且每次把接收到的命令原封不动发回给电脑,作为接收到命令的标志,但串口调试助手接收不到发回的命令,单片机也没执行相关操作,目前我想解决串口调试助手接收不到发回的命令的这一问题,请大佬帮忙看看,程序中有部分函数是关于LCD1602的,他们的原形在另一个.c文件中,由于无关且就没贴出来
单片机源程序如下:
/******UART.c的程序******/
#include "reg52.h"

bit flagFrame = 0;//用于判断命令是否接收完成的标志
bit flagTxd = 0;//字节发送完成的标志
unsigned char cntRxd = 0;//计数接收到多少字节
unsigned char bufRxd[32];//接收缓冲区

extern void UartAction(unsigned char *buf,unsigned char len);
/**波特率配置函数**/
void ConfigUART(unsigned char baud)
{
        SCON =  0x50;
        TMOD &= 0x0f;
        TMOD |= 0x20;
        TH1 = 256 - (11059200/12/32)/baud;;
        TL1 = TH1;
        ET1 = 0;
        ES = 1;
        TR1 = 1;
}
/**UART读取函数,在判断完命令接收完成后使用,将读取到的数据从bufRxd中取出**/
unsigned char UartRead(unsigned char *buf,unsigned char len)
{
        unsigned char i;
        if(len > cntRxd)
        {
                 len = cntRxd;
        }
        for(i = 0;i < len;i++)
        {
                *buf++ = bufRxd[ i];
        }
        cntRxd = 0;
        return len;
}
/**命令监测函数,用于监测命令是否接收完成,在中断中使用**/
void UartRxMonitor(unsigned char ms)
{
        static unsigned char cntbkp;//数据接收字节备份值,30ms接收字节与备份值不变,即认为命令接收完成
        static unsigned char idletmr;
        if(cntRxd > 0)
        {
                if(cntbkp != cntRxd)
                {
                        cntbkp = cntRxd;
                        idletmr = 0;
                }
                else
                {
                        if(idletmr < 30)
                        idletmr+=ms;
                        if(idletmr >= 30)
                        flagFrame = 1;
                }        
        }
        else
        {
                cntbkp = 0;
        }
}
/**将接收到的原原本本发送回去,作为接收到了的标志**/
void UartWrite(unsigned char *buf,unsigned char len)
{
        while(len--)
        {
                flagTxd = 0;
                SBUF = *buf++;
                while(!flagTxd);
        }
}

void UartDriver()
{
        unsigned char len;
        unsigned char buf[40];

        if(flagFrame)
        {
                flagFrame = 0;
                len = UartRead(buf,sizeof(buf));
                UartAction(buf,len);        
        }
}
/**UART中断函数**/
void InterruptUART() interrupt 4
{
        if(RI)
        {
                RI = 0;
                if(cntRxd < sizeof(bufRxd))
                bufRxd[cntRxd++] = SBUF;
        }
        if(TI)
        {
                TI = 0;
                flagTxd = 1;               
        }
}


/******main.c的程序******/
#include "reg52.h"
sbit BUZZ = P2^5;

bit flagBuzzOn = 0;
unsigned char T0RH = 0;
unsigned char T0RL = 0;

void ConfigTimer0(unsigned int ms);

extern void ConfigUART(unsigned char baud);
extern unsigned char UartRead(unsigned char *buf,unsigned char len);
extern void UartRxMonitor(unsigned char ms);
extern void UartWrite(unsigned char *buf,unsigned char len);
extern void UartDriver();
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
extern void LcdAreaClear(unsigned char x, unsigned char y, unsigned char len);
extern void InitLcd1602();

void main()
{
        EA = 1;
        ConfigTimer0(1);
        ConfigUART(9600);
        InitLcd1602();
        LcdShowStr(0, 0, "Welcome to 51");
        while(1)
        {
                UartDriver();
        }
}
/**命令比较函数,将接收的命令与现有的命令进行比较**/
bit CmpMemory(unsigned char *ptr1,unsigned char *ptr2,unsigned char len)
{
        while(len--)
        {
                if(*ptr1++ != *ptr2++)
                {
                        return 0;        
                }
        }
        return 1;        
}
/**根据接收到的命令执行不同的操作**/
void UartAction(unsigned char *buf,unsigned char len)
{
        unsigned char i;
        unsigned char code cmd0[] = "buzz on";
        unsigned char code cmd1[] = "buzz off";
        unsigned char code cmd2[] = "showstr ";
        unsigned char code cmdlen[] = {
         sizeof(cmd0)-1,sizeof(cmd1)-1,sizeof(cmd2)-1
        };
        unsigned char *cmdPtr[] = {&cmd0[0],&cmd1[0],&cmd2[0]};
        for(i = 0;i < 3;i++)
        {
                if(len >= cmdlen[ i])
                {
                        if(CmpMemory(buf,cmdPtr[ i],cmdlen[ i]))
                        {
                                break;
                        }
                }        
        }
        switch(i)
        {
        case(0):
                flagBuzzOn = 1;
                break;
        case(1):
                flagBuzzOn = 0;
                break;
        case(2):
                buf[len] = '\0';
                LcdShowStr(0,0,buf+cmdlen[2]);
                i = len-cmdlen[2];
                if(i < 16)
                {
                        LcdAreaClear(i,0,16-i);
                }
                break;
        default:
                UartWrite("erro.\r\n",sizeof("erro.\r\n")-1);
                return;
    }
        buf[len++] = '\r';
        buf[len++] = '\n';
        UartWrite(buf,len);
}

void ConfigTimer0(unsigned int ms)
{
unsigned long tmp; //临时变量

tmp = 11059200 / 12; //定时器计数频率
tmp = (tmp * ms) / 1000; //计算所需的计数值
tmp = 65536 - tmp; //计算定时器重载值
tmp = tmp + 33; //补偿中断响应延时造成的误差
T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
T0RL = (unsigned char)tmp;
TMOD &= 0xF0; //清零 T0 的控制位
TMOD |= 0x01; //配置 T0 为模式 1
TH0 = T0RH; //加载 T0 重载值
TL0 = T0RL;
ET0 = 1; //使能 T0 中断
TR0 = 1; //启动 T0
}
/**在中断中调用UartRxMonitor(ms)函数,来记录没有接收到新命令的时间,超过30ms就认为命令已经接收完整**/
void InterruptTimer0() interrupt 1
{
TH0 = T0RH; //重新加载重载值
TL0 = T0RL;
if (flagBuzzOn) //执行蜂鸣器鸣叫或关闭
BUZZ = ~BUZZ;
else
BUZZ = 1;
UartRxMonitor(1); //串口接收监控
}

10.30.png (54.49 KB, 下载次数: 32)

10.30.png

屏幕截图 2021-10-30 165052.png (62.99 KB, 下载次数: 41)

屏幕截图 2021-10-30 165052.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:624769 发表于 2021-10-30 19:06 | 只看该作者
你先做最基本的

单片机每隔 0.5秒 给单片机发送 一个 ‘A'       这个过程叫 “调通”, 当你可以收到了。做下一步。
只要单片机收到  电脑发来数据, 就给 电脑 发一个 ‘B' , 这个过程叫 '联动'。

做完上面这两步,你再捉摸上面你发出来的程序。
回复

使用道具 举报

板凳
ID:401564 发表于 2021-10-30 23:29 | 只看该作者
STC的下载器有现成的串口代码,可以直接复制使用
先写一个简单的串口发送函数,只给电脑发送一个数据就行了
通过之后才写别的代码
而不是像现在这样,一下把整个程序都写完了才开始调试,出了问题都不知道在哪里找
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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