登录  | 立即注册

游客您好!登录后享受更多精彩

扫一扫,访问微社区

QQ登录

只需一步,快速开始

开启左侧

[寒假笔记] 一个串口例程

[复制链接]
发表于 2022-2-12 22:53:00 | 显示全部楼层 |阅读模式
学习笔记
学习科目: 51单片机
学习安排: 理解一个串口例程
开始时间: 2022-02-10
结束时间: 2022-02-12
此程序对我来说有些不好理解,有些地方还不太明白,但耗费的时间太久了,先学习一下后面的知识再回来看看。程序里有几个比较重要的点,利用定时器中断调用UartRxMonitor监视一帧数据是否接收完毕(空闲大于等于30ms)。还有就是类似*ptr1++ !=*ptr2++或者buf[len++] = '\r'的语句都是先进行比较或赋值,再++。还有学要注意的点我再看看,会补充。

程序:

main.c

#include<reg52.h>

sbit BUZZ = P1^3;

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

extern void ConfigTimer0(unsigned int ms);
extern void ConfigUART(unsigned int baud);
extern void UartWrite(unsigned char *buf,unsigned char len);
extern void UartRxMonitor(unsigned char ms);
extern InitLcd1602();
extern 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);

void main()
{
EA = 1;
ConfigTimer0(1);
ConfigUART(9600);
InitLcd1602();

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 code *cmdPtr[] = {
&cmd0[0],&cmd1[0],&cmd2[0]};
for(i = 0;i<sizeof(cmdLen);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("bad command.\r\n",sizeof("bad command.\r\n")-1);
return;
}
buf[len++] = '\r';
buf[len++] = '\n';
UartWrite(buf,len);
}

void ConfigTimer0(unsigned int ms)
{
                unsigned long tmp;

    tmp = 32768000/12;
                tmp = (tmp*ms)/1000;
    tmp = 65536 - tmp;
    tmp = tmp + 33;
    T0RH = (unsigned char)(tmp>>8);
    T0RL = (unsigned char)tmp;
    TMOD &= 0xF0;
    TMOD |= 0x01;
    TH0 = T0RH;
                TL0 = T0RL;
    ET0 = 1;
    TR0 = 1;
}

void InterruptTimer0() interrupt 1
{
TH0 = T0RH;
TL0 = T0RL;
if(flagBuzzOn)
{
BUZZ = ~BUZZ;
}
else
{
BUZZ = 1;
}
UartRxMonitor(1);
}


uart.c

#include<reg52.h>

bit flagFrame = 0;
bit flagTxd = 0;

unsigned char cntRxd = 0;
unsigned char pdata bufRxd[64];

extern void UartAction(unsigned char *buf,unsigned char len);

void ConfigUART(unsigned int baud)
{
SCON = 0x50;
TMOD &= 0x0F;
TMOD |= 0x20;
TH1 = 255-(32768000/12/32)/baud;
TL1 = TH1;
ET1 = 0;
ES = 1;
TR1 = 1;
}

void UartWrite(unsigned char *buf,unsigned char len)
{
while(len--)
{
flagTxd = 0;
SBUF = *buf++;
while(!flagTxd);
}
}

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 = 0;
static unsigned char idletmr = 0;

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 UartDriver()
{
unsigned char len;
unsigned char pdata buf[40];

if(flagFrame)
{
flagFrame = 0;
len = UartRead(buf,sizeof(buf));
UartAction(buf,len);
}
}

void InterruptUART() interrupt 4
{
if(RI)
{
RI = 0;
if(cntRxd<sizeof(bufRxd))
{
bufRxd[cntRxd++] = SBUF;
}
}
if(TI)
{
TI = 0;
flagTxd = 1;
}
}


Lcd1602.c

#include<reg52.h>

#define LCD1602_DB P0
sbit LCD1602_RS = P2^0;
sbit LCD1602_RW = P2^1;
sbit LCD1602_E = P1^2;

void delay()
{
unsigned int i;
i=5;
while(--i);
}

void LcdWaitReady()
{
unsigned char sta;

LCD1602_DB = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
do{
LCD1602_E = 1;
sta = LCD1602_DB;
LCD1602_E = 0;
}while(sta&0x80);
LCD1602_RS = 1;
LCD1602_RW = 1;
}

void LcdWriteCmd(unsigned char cmd)
{
LcdWaitReady();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;
delay();
LCD1602_E = 1;
delay();
LCD1602_E = 0;
}

void LcdWriteDat(unsigned char dat)
{
LcdWaitReady();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
delay();
LCD1602_E = 1;
delay();
LCD1602_E = 0;
}

void LcdSetCursor(unsigned char x,unsigned char y)
{
unsigned char addr;

if(y == 0)
addr = 0x00+x;
else
addr = 0x40+x;
LcdWriteCmd(addr | 0x80);
}

void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str)
{
LcdSetCursor(x,y);
while(*str != '\0')
{
LcdWriteDat(*str++);
}
}

void LcdAreaClear(unsigned char x,unsigned char y,unsigned char len)
{
LcdSetCursor(x,y);
while(len--)
{
LcdWriteDat(' ');
}
}
void InitLcd1602()
{
LcdWriteCmd(0x38);
LcdWriteCmd(0x0C);
LcdWriteCmd(0x06);
LcdWriteCmd(0x01);
}

好懒~~不想说~~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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