|
大致就是根據(jù)電腦發(fā)送的不同命令執(zhí)行相關(guān)操作,并且每次把接收到的命令原封不動發(fā)回給電腦,作為接收到命令的標(biāo)志,但串口調(diào)試助手接收不到發(fā)回的命令,單片機也沒執(zhí)行相關(guān)操作,目前我想解決串口調(diào)試助手接收不到發(fā)回的命令的這一問題,請大佬幫忙看看,程序中有部分函數(shù)是關(guān)于LCD1602的,他們的原形在另一個.c文件中,由于無關(guān)且就沒貼出來
屏幕截圖 2021-10-30 165052.png (62.99 KB, 下載次數(shù): 45)
下載附件
2021-10-30 16:53 上傳
單片機源程序如下:
/******UART.c的程序******/
#include "reg52.h"
bit flagFrame = 0;//用于判斷命令是否接收完成的標(biāo)志
bit flagTxd = 0;//字節(jié)發(fā)送完成的標(biāo)志
unsigned char cntRxd = 0;//計數(shù)接收到多少字節(jié)
unsigned char bufRxd[32];//接收緩沖區(qū)
extern void UartAction(unsigned char *buf,unsigned char len);
/**波特率配置函數(shù)**/
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讀取函數(shù),在判斷完命令接收完成后使用,將讀取到的數(shù)據(jù)從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;
}
/**命令監(jiān)測函數(shù),用于監(jiān)測命令是否接收完成,在中斷中使用**/
void UartRxMonitor(unsigned char ms)
{
static unsigned char cntbkp;//數(shù)據(jù)接收字節(jié)備份值,30ms接收字節(jié)與備份值不變,即認為命令接收完成
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;
}
}
/**將接收到的原原本本發(fā)送回去,作為接收到了的標(biāo)志**/
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中斷函數(shù)**/
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();
}
}
/**命令比較函數(shù),將接收的命令與現(xiàn)有的命令進行比較**/
bit CmpMemory(unsigned char *ptr1,unsigned char *ptr2,unsigned char len)
{
while(len--)
{
if(*ptr1++ != *ptr2++)
{
return 0;
}
}
return 1;
}
/**根據(jù)接收到的命令執(zhí)行不同的操作**/
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; //定時器計數(shù)頻率
tmp = (tmp * ms) / 1000; //計算所需的計數(shù)值
tmp = 65536 - tmp; //計算定時器重載值
tmp = tmp + 33; //補償中斷響應(yīng)延時造成的誤差
T0RH = (unsigned char)(tmp>>8); //定時器重載值拆分為高低字節(jié)
T0RL = (unsigned char)tmp;
TMOD &= 0xF0; //清零 T0 的控制位
TMOD |= 0x01; //配置 T0 為模式 1
TH0 = T0RH; //加載 T0 重載值
TL0 = T0RL;
ET0 = 1; //使能 T0 中斷
TR0 = 1; //啟動 T0
}
/**在中斷中調(diào)用UartRxMonitor(ms)函數(shù),來記錄沒有接收到新命令的時間,超過30ms就認為命令已經(jīng)接收完整**/
void InterruptTimer0() interrupt 1
{
TH0 = T0RH; //重新加載重載值
TL0 = T0RL;
if (flagBuzzOn) //執(zhí)行蜂鳴器鳴叫或關(guān)閉
BUZZ = ~BUZZ;
else
BUZZ = 1;
UartRxMonitor(1); //串口接收監(jiān)控
}
|
|