1.硬件连接图

2.PC接收端接收结果

3.单片机接收到的发送成功信号

4.串口信号波形


6.单片机源程序
cpp
/************************************************
* 文件描述 : 串口2发送接收字符串函数
* 程序文件 : main.c
* 版 本 : 4.0
* 作 者 : 火龙电子工作室
* 日 期 : 2020.12.01
* 芯 片 : IAP15W4K58S4
* 时 钟 :内部11.0592MHz
* 开发环境 :Keil uVision4 C51 V9.52
* 开 发 板 :FD51H
* 操 作 :
1、该串口2可以设置为通过DB9口J27输出。
2、使用DB9串口直连线或者USB转串口线连接开发板J27插座和电脑
3、使用外部9-12V的DC电源接入插座J22中。
4、打开STC-ISP下载软件中的串口助手,选择相应串口号,
选择波特率9600,8位数据位,1位停止位,无校验。
点打开串口 接收缓冲区选择"文本模式"
发送缓冲区选择"文本模式"
* 现 象 : 按下板子上的红色复位按键S14可以观察到菜单显示,
根据菜单提示,从串口助手发送缓冲区中输入字符H或者D,
或者任意字符,点击"发送数据"观察串口助手显示的信息。
* 备 注 :
详细操作见左侧Doc目录下的readme文件
************************************************/
//文件包含
#include "stc15.h"
#include "tm1638.h"
#include "global_var.h"
//#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
//宏定义
#define CHARTAST 1 //字符任务
#define NUMTAST 2 //数字任务
#define MENUTAST 3 //菜单任务
#define uchar unsigned char
#define TRUE 1
#define FALSE 0
//全局变量
//bit HaveTast=0; //任务标记
unsigned char Uart2Cmd; //串口命令
//函数声明
void IO_Init(void);
void Uart2_Init(void);
void Display_Menu(void);
void Uart2_Process(void);
void Uart2_SendChar(unsigned char Udat);
void Uart2_SendString(unsigned char *PBuf);
void Uart2_Init_115200(void);
sbit LEDx=P4^5;
#define BUFF_LEN 40
// struct UARTGET
// {
// uchar GetFlag;
// uchar save_p;
// //uchar buff_len;
// uchar buff[BUFF_LEN];
// };
//
//struct UARTGET uart_rev;
void uart_rev_init(struct UARTGET *p)
{
p->GetFlag=FALSE;
p->save_p=0;
}
void uart_rev_save(struct UARTGET *p,uchar dat)
{
static uchar state=0;
switch(state)
{
case 0:
p->buff[p->save_p++]=dat;
if(p->save_p>=BUFF_LEN){p->save_p=0;}
if(dat=='\r')
{state=1;}
break;
case 1:
p->buff[p->save_p++]=dat;
if(p->save_p>=BUFF_LEN){p->save_p=0;}
if(dat=='\n')
{state=0;p->save_p=0;p->GetFlag=TRUE;}
else
{
state=0;
p->GetFlag=FALSE;
p->save_p=0;
}
break;
default:state=0;break;
}
}
void led_init(void)
{
P4M1 &= ~(1 << 5); // P4M1的bit5清零
P4M0 |= (1 << 5); // P4M0的bit5置1
}
/***********************************************
函数名称:Timer0_Init
功 能:定时器0初始化函数
入口参数:无
返 回 值:无
备 注:定时初值可以使用stc下载软件中的
定时初值自动生成功能。
以下的函数和宏定义请参考STC15.H文件中的注释
************************************************/
void Timer0_Init(void)
{
ClrBits(AUXR,T0x12);//定时器0时钟12T模式
//T0工作于十六位自动重装定时方式
ClrBits(TMOD,T0_GATE|T0_CT|T0_M1|T0_M0);
TL0 = 0x00; //设置定时初值 50ms 11.0592MHz
TH0 = 0x4c; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1; //使能T0中断
EA=1; //使能总中断
}
/***********************************************
函数名称:Timer0_ISR
功 能:定时器0中断服务函数
入口参数:无
返 回 值:无
备 注:TIMER0_VECTOR宏定义,请参考STC15.H文件中的注释
************************************************/
uchar cnt_1s=0;
void Timer0_ISR(void) interrupt TIMER0_VECTOR
{
static unsigned char T0_Cnt=0;
//使用静态计数器,每次调用该中断函数时,
//静态计数器都能保持上一次的计数值。
//如果不使用静态计数器,每次调用该中断函数时
//该计数器初值都是0,计数值就无法累加。
//这里不需要重装定时初值
T0_Cnt++; //计数器加1
cnt_1s++;
if(T0_Cnt==2) //定时100ms
{
T0_Cnt=0;
LEDx=!LEDx; //将端口状态取反,输出波形周期200ms
}
}
//主方法
void uart_str_echo(struct UARTGET *p);
void main(void)
{
//TM1638_Init(); //TM1638初始化
//ToDisplay__(); //数码管显示--
//Uart2_Init_115200(); //串口2初始化
Uart2_Init();
Timer0_Init();
led_init();
Display_Menu(); //显示菜单字符
uart_rev_init(&uart_rev);
while(1)
{
//Uart2_Process(); //串口任务处理
uart_str_echo(&uart_rev);
if(cnt_1s>10)
{
cnt_1s=0;
Uart2_SendString(cmd1);
}
}
}
/***********************************************
函数名称:Uart2_Init
功 能:串口2初始化函数
入口参数:无
返 回 值:无
备 注:STC15W4K32S4单片机串口2
只能选择定时器2作为波特率发生器,
不能使用其他定时器做为波特率发生器
************************************************/
void Uart2_Init(void)
{
S2CON=0x50; //0101 0000 模式1: 1 位起始位; 8 位数据; 1 位停止位;允许接收
//ClrBits(AUXR, T2x12); //定时器2时钟为Fosc,即12T
SetBits(AUXR, T2x12); //定时器2时钟为Fosc,即1T(115200波特率必须用1T)
T2L=0xe8; //波特率9600 11.0592MHz , when //ClrBits(AUXR, T2x12); //115200 when SetBits(AUXR, T2x12);
T2H=0xff;
//T2L=0xfd; //波特率115200 11.0592MHz
//T2H=0xff;
SetBits(AUXR, T2R); //启动定时器2
SetBits(IE2, ES2); //使能串口2中断
EA=1; //打开全局中断
P1_Mode_IO_PU(PIN_0|PIN_1); //将P10 P11 设置为准双向口
}
void Uart2_Init_115200(void)
{
// S2CON=0x50;
// TH2=0xFF;
// TL2=0xFD;
// RCAP2H=0xFF;
// RCAP2L=0xFD;
///*****************/
// TCLK=1;
// RCLK=1;
// C_T2=0;
// EXEN2=0;
///*****************/
// TR2=1 ;
// TI = 1;
// // 3. 开启中断 (可选)
// ES = 1; // 开启串口中断
// EA = 1; // 开启总中断
//
// P1_Mode_IO_PU(PIN_0|PIN_1); //将P10 P11 设置为准双向口
}
/***********************************************
*函数名称:Uart2_SendChar
*功 能:串口2发送单个字符函数
*入口参数:Udat:欲发送的数据
*返 回 值:无
*备 注:无
************************************************/
void Uart2_SendChar(unsigned char Udat)
{
S2BUF=Udat; //将要发送的数据放入串口数据缓冲区
while(!(S2CON&S2TI)); //等待发送完成
ClrBits(S2CON,S2TI); //清零S2TI
}
/***********************************************
*函数名称:Uart2_SendString
*功 能:串口发送字符串函数
*入口参数:*PBuf:指向字符串的指针
*返 回 值:无
*备 注:无
************************************************/
void Uart2_SendString(unsigned char *PBuf)
{
while(*PBuf!='\0') //未到字符串末尾
{
Uart2_SendChar(*PBuf);//发送数据
PBuf++; //移动指针
}
}
void uart_str_echo(struct UARTGET *p)
{
static uchar cnt=0;
uchar i=0;
if(p->GetFlag==TRUE)
{
while((p->buff[i])!='\n') //未到字符串末尾
{
Uart2_SendChar((p->buff[i]));//发送数据
i++; //移动指针
cnt++;
if(cnt>= BUFF_LEN)
{cnt=0;break;}
//p->GetFlag=FALSE;
}
Uart2_SendChar((p->buff[i]));//发送'\n'
p->GetFlag=FALSE;
//p->
cnt=0;
}
}
/***********************************************
*函数名称:Uart2_ISR
*功 能:串口2中断处理函数
*入口参数:无
*返 回 值:无
*备 注:UART2_VECTOR宏定义请参考STC15.H文件中的注释
************************************************/
void Uart2_ISR(void) interrupt UART2_VECTOR
{
if(S2CON&S2RI) //发送和接收共用一个中断向量,需在程序中判断
{
switch(S2BUF) //判断接收缓冲区数据
{
case 'H': //接收到的字符是"H"
{
Uart2Cmd=CHARTAST;
}break;
case 'D': //接收到的字符是"D"
{
Uart2Cmd=NUMTAST;
}break;
default:
{
Uart2Cmd=MENUTAST; //接收到其他字符
}
uart_rev_save(&uart_rev,S2BUF);
}
HaveTast=1; //串口接收到数据标记有效
ClrBits(S2CON,S2RI);; //串口接收中断标记需软件清零
}
}
/***********************************************
*函数名称:Uart2_Process
*功 能:串口命令处理函数
*入口参数:无
*返 回 值:无
*备 注:无
************************************************/
void Uart2_Process(void)
{
if(HaveTast==1) //如果串口接收到数据标记有效
{
switch(Uart2Cmd) //判断接收的命令类型
{
case CHARTAST:
{
Uart2_SendChar(0x0d); //回车
Uart2_SendString("You select: 'H'\r\n");
ToDisplayHello(); //数码管显示Hello
}break;
case NUMTAST:
{
Uart2_SendChar(0x0d); //回车
Uart2_SendString("You select: 'D'\r\n");
ToDisplayBuf(1234,5678); //数码管显示12345678
}break;
case MENUTAST:
{
Uart2_SendString("\r\n"); //回车
Display_Menu();
ToDisplay__(); //数码管显示--
}break;
}
HaveTast=0;
}
}
/***********************************************
*函数名称:Display_Menu
*功 能:显示菜单函数
*入口参数:无
*返 回 值:无
*备 注:无
************************************************/
void Display_Menu(void)
{
Uart2_SendString("Welcome to FireDragon Development Board!\r\n");
Uart2_SendChar(0x0d); //回车
Uart2_SendString("Please select:\r\n");
Uart2_SendString("H-- LED display 'Hello'\r\n");
Uart2_SendString("D-- LED display '12345678'\r\n");
Uart2_SendString("*-- any other key to redispaly the menu\r\n");
}