📄 uart.c
字号:
#include <string.h>
#include <stdio.h>
#include "uart.h"
#include "menu.h"
#include "Lcd.h"
#include "system.h"
#define MAXLEN 2000 //Uart接收数据区
char xdata Mydata[MAXLEN];
char *USP; //Uart发送字符串指针
char UBUSY; //Uart发送忙标志位
char xdata *URP=Mydata; //Uart接收指针,指向数据接受区
////////////////////////////////////////////////////////////////////////////////////////////////
//串口模块参数设置菜单
char code *UartConfigMenu={"(10,2)串口传输实验参数设置,(6,60)波特率设置: ,1200,2400,4800,9600,\
19200,28800,57600,115200,(6,90)显示方式: ,字符,十六进制,(6,120)数据返回: ,打开,关闭,"};
//串口模块参数默认值
unsigned char UartParaList[]={3,0,0};
////////////////////////////////////////////////////////////////////////////////////////////////
void Hexprintf(unsigned char x,unsigned char y, char *ptr) //以十六进制显示*ptr
{
unsigned char temp;
unsigned int low,high;
char buf[10];
temp=*ptr;
high=temp/16;
low=temp%16;
sprintf(buf,"%X%X%s",high,low," \0");
tprintf(x,y,buf);
if (X>=39)
{
X=0;
Y+=16;
}
}
void UartSend(char *ptr) //通过UART发送指定字符串
{
char SFRPAGE_SAVE;
SFRPAGE_SAVE=SFRPAGE;
SFRPAGE=UART0_PAGE;
USP=ptr;
TI0=1;
SFRPAGE=SFRPAGE_SAVE;
}
void inter() interrupt 4
{
if (TI0) //发送USP指向字符
{
TI0 = 0;
if(*USP!='\0')
{
SBUF0 = *USP;
USP++;
}
else
{
UBUSY=0;
}
}
if (RI0) //将数据保存到数据接收区
{
RI0 = 0;
if( URP-Mydata < MAXLEN-1 )
{
*URP = SBUF0;
URP++;
}
}
}
void uart_port_ini(void)
{
SFRPAGE = 0x0F;
XBR0 |= 0x04; //Uart引出到管脚:Tx到P0.0;Rx到P0.1
XBR2 |= 0x40; //弱上拉全局允许,交叉开关使能
P0MDOUT |= 0x01;
IE |= 0x90;
}
void uart_ini(unsigned char Sel_Baud)
{
SFRPAGE = 0x00;
SSTA0 = 0x10; //选择T1作为时钟源,禁止波特率2分频
SCON0 = 0x50; //Uart工作在方式1:8位可变波特率.忽略停止位.接受允许.
CKCON = 0x00; //sys/12 -> T1
TMOD |= 0x20; //T1工作方式:自动再装入8位定时器
//波特率设置
switch (Sel_Baud)
{ // 波特率设置=256-22.1184M/12/16/Baud
case 0: TH1 = 160; break; // 1200
case 1: TH1 = 208; break; // 2400
case 2: TH1 = 232; break; // 4800
case 3: TH1 = 244; break; // 9600
case 4: TH1 = 250; break; // 19200
case 5: TH1 = 252; break; // 28800
case 6: TH1 = 254; break; // 57660
case 7: TH1 = 255; break; // 115200
}
TL1 = TH1;
TR1 = 1;
}
//串口模块函数
void Uart()
{
char *p[20]; //记录每页显示的起始地址,支持最多20页显示
unsigned char currentp; //记录当前页号
char xdata *DSP; //显示指针
unsigned char Disflag; //显示接收数据标志位
unsigned int RCounter; //记录接收字节数
char SFRPAGE_SAVE; //保存SFR值
if(MenuActive(UartConfigMenu, UartParaList)==0) //放弃菜单设置,直接退出
return ;
uart_port_ini();
uart_ini(UartParaList[0]);
UartSend("C8051f124 UART ready!!");
SFRPAGE=0x0F;
Udprintf(0,208," 波特率: ");
switch (UartParaList[0])
{
case 0: Udprintf(10,208,"1200"); break;
case 1: Udprintf(10,208,"2400"); break;
case 2: Udprintf(10,208,"4800"); break;
case 3: Udprintf(10,208,"9600"); break;
case 4: Udprintf(10,208,"19200"); break;
case 5: Udprintf(10,208,"28800"); break;
case 6: Udprintf(10,208,"57600"); break;
case 7: Udprintf(10,208,"115200"); break;
}
dprintf(26,224,"暂停 清空 退出");
Key[6].pressed=1; //进行初始化
while(1)
{
if(Key[6].pressed==1) //检测到清空键
{
int i;
Clear(0,208);
currentp=0;
DSP=Mydata;
URP=Mydata;
USP=Mydata;
Disflag=1;
RCounter=0;
for(i=0;i<20;i++)
p[i]=Mydata;
for(i=0;i<MAXLEN;i++)
Mydata[i]='\0';
X=0;
Y=0;
dprintf(1,224," ");
dprintf(6,224," ");
dprintf(26,224,"暂停");
Udprintf(20,208,"接收字节数: 0 ");
SFRPAGE_SAVE=SFRPAGE;
SFRPAGE=UART0_PAGE;
REN0=1; //接受允许
SFRPAGE=SFRPAGE_SAVE;
Key[6].pressed=0;
}
if(CheckKeyF==1) //键盘检测
{
CheckKey();
CheckKeyF=0;
}
if (URP > DSP) //检测新接收数据
{
if(Disflag==1) //是否需要显示
{
if(UartParaList[1]==0)
DSP=tprintf(X,Y,DSP);
else
{
Hexprintf(X,Y,DSP);
DSP++;
}
if(F) //写满了一页
{
Disflag=0; //关显示
if(UartParaList[1]==1) DSP--;
p[currentp+1]=DSP; //记录下页地址
dprintf(6,224,DownArrow);
}
}
if(RCounter!=(URP-Mydata)) //显示接收字节数
{
RCounter=(URP-Mydata);
if(RCounter==MAXLEN-1) //数据区满
{
Udprintf(20,208,"接收区已满(2k字节)");
SFRPAGE_SAVE=SFRPAGE; //关掉UART
SFRPAGE=UART0_PAGE;
REN0=0;
SFRPAGE=SFRPAGE_SAVE;
}
else //刷新数字
{
char buf[10];
sprintf(buf,"%d",RCounter);
Udprintf(32,208,buf);
}
}
}
if(Key[1].pressed==1) //检测到下键
{
if(p[currentp+1]!=Mydata) //可以向下翻页
{
currentp++;
Clear(0,208);
dprintf(1,224,UpArrow);
if(UartParaList[1]==0)
{
DSP=tprintf(0,0,p[currentp]);
if(F==0) //写完了,未写满一页,等待接收显示新数据
{
Disflag=1;
dprintf(6,224," ");
}
else //该页已写满
{
Disflag=0;
p[currentp+1]=DSP;
dprintf(6,224,DownArrow);
}
}
if(UartParaList[1]==1)
{
dprintf(6,224," ");
DSP=p[currentp];
Disflag=1;
F=0;
X=0;
Y=0;
}
}
Key[1].pressed=0;
}
if(Key[0].pressed==1) //向上翻页
{
if(currentp>0) //可以向上翻页
{
currentp--;
Clear(0,208);
if(currentp>0)
{
dprintf(1,224,UpArrow);
}
else
{
dprintf(1,224," ");
}
dprintf(6,224,DownArrow);
if(UartParaList[1]==0)
tprintf(0,0,p[currentp]);
if(UartParaList[1]==1)
{
Disflag=1;
DSP=p[currentp];
F=0;
X=0;
Y=0;
}
}
Key[0].pressed=0;
}
if(Key[5].pressed==1) //暂停
{
char temp;
SFRPAGE_SAVE=SFRPAGE; //切换Uart开关
SFRPAGE=UART0_PAGE;
REN0=~REN0;
temp=REN0;
SFRPAGE=SFRPAGE_SAVE;
if(temp==0) //当前为暂停状态
{
Udprintf(16,224,"暂停接收");
dprintf(26,224,"继续");
}
else //当前为接收状态
{
dprintf(16,224," ");
dprintf(26,224,"暂停");
}
Key[5].pressed=0;
}
if(Key[7].pressed==1) //退出串口模块
{
ClearKey(); //清按键
Clear(0,240); //清屏幕
SFRPAGE_SAVE=SFRPAGE;
SFRPAGE=UART0_PAGE;
REN0=0; //关闭Uart接受
TR1=0; //关T1
SFRPAGE=SFRPAGE_SAVE;
return;
}
if(UartParaList[2]==0) //数据返回
{
if(UBUSY==0) //Uart发送空闲
{
if( USP<URP ) //有字节需要发送
{
UBUSY=1; //Uart忙
SFRPAGE_SAVE=SFRPAGE;
SFRPAGE=UART0_PAGE;
TI0=1; //进入发送中断
SFRPAGE=SFRPAGE_SAVE;
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -