|
大致就是根据电脑发送的不同命令执行相关操作,并且每次把接收到的命令原封不动发回给电脑,作为接收到命令的标志,但串口调试助手接收不到发回的命令,单片机也没执行相关操作,目前我想解决串口调试助手接收不到发回的命令的这一问题,请大佬帮忙看看,程序中有部分函数是关于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); //串口接收监控
}
|
|