51单片机之串口

文章目录

  • 串口
    • 串口基本认知
      • 关于电器标准和协议
      • 关于串口的电平
    • 串口通信
    • 串行口通信
    • 串口寄存器
      • 串行口相关寄存器
      • 串口接线方式
      • 串口编程要素
      • 如何配置串口寄存器
      • 新手上路
      • 小试牛刀
      • 编程练习
    • 蓝牙模块
    • WIFI模块
      • AT指令
      • 初始配置和指令
      • 入网设置
      • 连接到TCP server
      • 透传
      • 单片机实现
      • esp8266作为服务器
    • 4G模块
      • 产品简介
      • 功能特点
      • 模块使用
      • 快速入门
      • 修改4G模块波特率
      • 单片机实现

串口

串口基本认知

串行接口简称串口,也称[串行通信](串行通信_百度百科 (baidu.com))接口或[串行通讯接口](串行端口_百度百科 (baidu.com))(通常指[COM](串行端口_百度百科 (baidu.com))接口),是采用串行通信方
式的[扩展接口](扩展接口_百度百科 (baidu.com))。串行接口(Serial Interface)是指数据一位一位地顺序传送。其特点是[通信线路](通信线路(信息通讯术语)_百度百科 (baidu.com))简
单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成
本,特别适用于远距离通信,但传送速度较慢 。

  • 是设备间接线通信的一种方式
  • 数据一位一位地顺序传送
  • 双向通信,全双工
  • 传送速度相对较慢

关于电器标准和协议

串行接口按电气标准及协议来分包括[RS-232](RS-232_百度百科 (baidu.com))、[RS-422](RS-422_百度百科 (baidu.com))、[RS-485](EIA-485_百度百科 (baidu.com))等。RS-232-C、RS-422与RS-485
标准只对接口的电气特性做出规定,不涉及接插件、电缆或协议。

RS-232
也称标准[串口](串行端口_百度百科 (baidu.com)),最常用的一种[串行通讯接口,比如我们的电脑主机的9针串口 ,最高速率为20kb/s
RS-232是为[点对点](点对点(科技)_百度百科 (baidu.com))(即只用一对收、发设备)通讯而设计的,其传送距离最大为约15米。所以RS-232适
合本地设备之间的通信 。

51单片机之串口_第1张图片

RS-422

由于接收器采用高输入阻抗和发送[驱动器](驱动器_百度百科 (baidu.com))比RS-232更强的[驱动能力](驱动能力_百度百科 (baidu.com)),故允许在相同传输线上连接多个接
收[节点](节点(通信技术名词)_百度百科 (baidu.com)),最多可接10个节点。即一个主设备(Master),其余为从设备(Slave),从设备之间不能通
信,所以RS-422支持点对多的双向通信。
RS-422的最大传输距离为1219米,最大传输速率为10Mb/s。平衡双绞线的长度与传输速率成反比。

RS-485
是从RS-422基础上发展而来的,无论四线还是二线连接方式总线上可多接到32个设备。

51单片机之串口_第2张图片

关于串口的电平

经常听说的UART

异步串行是指UART(Universal Asynchronous Receiver/Transmitter),通用异步接收/发送。
UART包含TTL电平的[串口](串行端口_百度百科 (baidu.com))和[RS-232](RS-232_百度百科 (baidu.com))电平的串口

RS-232电平
逻辑1为-3~-15V的电压, 逻辑0为3~15V的电压

  • 笔记本通过RS-232电平和单片机通信

51单片机之串口_第3张图片

  • TTL电平

​ TTL是Transistor-Transistor Logic,即晶体管-晶体管逻辑的简称,它是计算机处理器控制的设备内部各部分之间通信的标准术。 TTL电平信号应用广泛,是因为其数据表示采用二进制规定,+5V等价于逻辑”1”,0V等价于逻辑”0”。

​ 数字电路中,由TTL电子元器件组成电路的电平是个电压范围,规定:

输出高电平>=2.4V,输出低电平<=0.4V;
输入高电平>=2.0V,输入低电平<=0.8V;

  • ​ 笔记本电脑通过TTL电平与单片机通信

​ TX发送线(端口)P3.1

​ RX接收线 (端口)P3.0

​ USB转TTL,使用ch340通信

51单片机之串口_第4张图片

串口通信

串行口通信

51单片机之串口_第5张图片

串口寄存器

串行口相关寄存器

51单片机之串口_第6张图片

  • 串行口控制器SCON和PCON

51单片机之串口_第7张图片

51单片机之串口_第8张图片

  • 串行口数据缓冲寄存器SBUF

51单片机之串口_第9张图片

  • 从机地址控制寄存器SADEN和SADDR

control

  • 与串行口中断相关的寄存器IE和IPH、IP

51单片机之串口_第10张图片

串口接线方式

  • RXD:数据输入引脚,数据接受;STC89系列对应P3.0口,上官一号有单独引出
  • TXD:数据发送引脚,数据发送;STC89系列对应P3.1口,上官一号有单独引出
  • 接线方式

51单片机之串口_第11张图片

串口编程要素

印象塑造

  • 输入/输出数据缓冲器都叫做SBUF, 都用99H地址码,但是是两个独立的8位寄存器
  • 代码体现为: 想要接收数据char data_UART = SBUF 想要发送数据 SBUF = data_UART

51单片机之串口_第12张图片

  • 回忆UART是异步串行接口,通信双方使用时钟不同,因为双方硬件配置不同,

但是需要约定通信速度,叫做波特率

电脑配置波特率:

51单片机之串口_第13张图片

如何配置串口寄存器

  1. 使用STC-ISP配置

晶振频率11.0592MHz、串口1、8位UART,波特率可变、9600波特率、波特率发生器选择定时器1(8位自动重载)、定时器始终为12T

51单片机之串口_第14张图片

  1. 自己动手配置波特率
  • 配置SCON为8为UART,波特率可变,允许串口接收

SCON = 0101 0000 = 0x50;

51单片机之串口_第15张图片

  • 配置定时器1为8为自动重载定时器

TMOD &= 0x0F; //清空高4位,低4位保持不变

TMOD |= 0x20; //配置定时器1为8位自动重载定时器

51单片机之串口_第16张图片

  • 计算波特率

51单片机之串口_第17张图片

选用的是8位UART,波特率可变,所以波特率为:9600 = (2SMOD/32) x (定时器1的溢出率)

定时器1的溢出率 = SYSclk / 12 / (256-TH1);

前边设置波特率选择位为不加倍,所以SMOD = 0;

则 9600 = 2 0 32 \frac{2^0}{32} 3220 x 110592 12 ∗ ( 256 − T H 1 ) \frac{110592}{12*(256-TH1)} 12(256TH1)110592

最终得出TH1 = 253 = 0xFD; 因为使用的是八位自动重载定时器,所以TL1 = TH1 = 0xFD;

TH1 = 0xFD;

TL1 = 0xFD;

  • 禁止ALE信号输出,提升系统性能

sfr AUXR = 0x8E;

AUXR = 0x01;

  • 最后启动定时器1

TR1 = 1;

51单片机之串口_第18张图片

新手上路

/*
	给电脑发送一个字符
*/
#include 
#include 

sfr AUXR = 0x8E;		//52.h里不包含AUXR的地址,自己定义

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void UART_Init()
{
	SCON = 0x50;		//配置SCON为8位UART,波特率可变,REN = 1允许串行接收
	TMOD &= 0x0F;
	TMOD |= 0x20;		//配置定时器1为8为自动重载定时器
	TL1 = 0xFD;
	TH1 = 0xFD;			//9600波特率初值
	AUXR = 0x01;		//禁止ALE输出,提升系统稳定性
	TR1 = 1;			//开启定时器1
}

void main()
{
	char data_UART = 'a';		//定义一个字符
	UART_Init();
	while(1)
	{
		Delay1000ms();
		SBUF = data_UART;		//单片机通过串口助手向电脑发送一个字符a
	}
}

字符 ‘a’ 是如何从单片机上传到PC的
a的ASSII码是97,16进制就是0x61, 二进制是01010001,这个8位就是数据位
串口工作模式1,一帧数据有10位,起始位(0),数据位,停止位(1)
那么a的一帧数据就是 0 1000 1010 1 起始位,a的低位到高位,停止位

  • 除了速度要求,还要有数据格式,双方 暗号 对上了再发数据,所以有起始位,和停止位 的概念
  • 一个字节有8位,比如字母‘a’的ASSII码是十进制97,二进制是 0110 0001 ,一次从地位到高位发
    送,接收也是

51单片机之串口_第19张图片

小试牛刀

/*
	向电脑发送一个字符串
*/
#include 
#include 

sfr AUXR = 0x8E;

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void UART_Init()
{
	SCON = 0x50;		//配置SCON为8位UART,波特率可变,REN = 1允许串行接收
	TMOD &= 0x0F;
	TMOD |= 0x20;		//配置定时器1为8为自动重载定时器
	TL1 = 0xFD;
	TH1 = 0xFD;			//9600波特率初值
	AUXR = 0x01;		//禁止ALE输出,提升系统稳定性
	TR1 = 1;			//开启定时器1
}

void SendByte(char data_UART)
{
	SBUF = data_UART;
	while(!TI);			//发送数据后TI由硬件置1,软件清0
	TI = 0;
}

void SendString(char *str)		
{
	while(*str != '\0')			
	{
		SendByte(*str);
		str++;			//字符串以'\0'结尾,没有到结尾就一直偏移输出,直到*str = '\0'退出循环
	}
}

void main()
{
	UART_Init();
	while(1)
	{
		Delay1000ms();
		SendString("Hello World\r\n");		//在串口中\r\n表示换行符
	}
}

编程练习

/*
	通过电脑发送字符控制单片机LED的亮灭
*/

#include 
#include 

sfr AUXR = 0x8E;
sbit LED1 = P3^7;
char cmd;				//将cmd定义成全局变量

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void UART_Init()
{
	SCON = 0x50;		//配置SCON为8位UART,波特率可变,REN = 1允许串行接收
	TMOD &= 0x0F;
	TMOD |= 0x20;		//配置定时器1为8为自动重载定时器
	TL1 = 0xFD;
	TH1 = 0xFD;			//9600波特率初值
	AUXR = 0x01;		//禁止ALE输出,提升系统稳定性
	TR1 = 1;			//开启定时器1
    EA = 1;				//开启总中断
    ES = 1;				//开启串口中断
}

void SendByte(char data_UART)
{
	SBUF = data_UART;
	while(!TI);
	TI = 0;
}

void SendString(char *str)
{
	while(*str != '\0')
	{
		SendByte(*str);
		str++;
	}
}

void main()
{
	LED1 = 1;
	UART_Init();
	while(1)
	{
		Delay1000ms();
		SendString("Hello World\r\n");
		
	}
}

void UART_Handler() interrupt 4
{
	if(RI)			//串口中断处理函数中对接收中断的响应
	{
		RI = 0;		//清空接收中断标志位
		cmd = SBUF;
		if(cmd == 'o')
		{
			LED1 = 0;
		}
		if(cmd == 'c')
		{
			LED1 = 1;
		}
	}
    if(TI);
}
  • 注意这里的字符 ‘o’ 和字符 ‘c’ 是文本模式下的o和c

51单片机之串口_第20张图片

  • 用hex模式下,对应的指令就应该变成16进制的6F(o),63©

51单片机之串口_第21张图片

/*
	发送字符控制LED的亮灭
*/

#include 
#include 
#include 
#define SIZE 12			//宏定义

sfr AUXR = 0x8E;
sbit LED1 = P3^7;

char cmd[SIZE];

void SendByte(char data_UART)
{
    SBUF = data_UART;
    while(!TI);
    TI = 0;
}

void SendString(char *str)
{
    while(*str != '\0')
    {
        SendByte(*str);
        str++;
    }
}

void UARTInit()
{
    SCON = 0x50;
    TMOD &= 0x0F;
    TMOD|= 0x20;
    TL1 = 0xFD;
    TH1 = 0xFD;
    EA = 1;
    ES = 1;
    AUXR = 0x01;
    TR1 = 1;
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void main()
{
    LED1 = 1;
    UARTInit();
    while(1)
    {
        Delay1000ms();
        SendString("Hello World\r\n");
    }
}

void UART_Handler () interrupt 4
{
    static int i = 0;
    
    if(RI)
    {
        RI = 0;
        cmd[i] = SBUF;
        i++;
        if(i == SIZE)
        {
            i = 0;
        }
        if(strstr(cmd,"open"))		//strstr查找子串,如果发现"open",LED亮
        {
            LED1 = 0;
            i = 0;
            memset(cmd,'\0',SIZE);
        }
        if(strstr(cmd,"close"))		//查找"close",发现子串,LED灭
        {
            LED1 = 1;
            i = 0;
            memset(cmd,'\0',SIZE);
        }
    }
    if(TI);
}

蓝牙模块

蓝牙模块,又叫做蓝牙串口模块

串口透传技术

透传即透明传送,是指在数据的传输过程中,通过无线的方式这组数据不发生任何形式的改变,仿
佛传输过程是透明的一样,同时保证传输的质量,原封不动地到了最终接收者手里。

将蓝牙模块接到上官一号上,VCC-VCC,GND-GND,TXD-RXD,RXD-TXD,然后下载HC蓝牙助手,打开蓝牙,在蓝牙列表里找到HC-08连接。然后根据上节课地代码,你就能通过手机发送指令来控制LED的亮灭。

如何修改蓝牙名称:将蓝牙模块和ttl模块连接插到电脑上,打开串口调试,发送AT+NAME=xxx(新修改的名称),在修改蓝牙名称的时候断开与手机的连接。成功修改后返回OKset字样。

51单片机之串口_第22张图片

WIFI模块

蓝牙,ESP-01s,Zigbee, NB-Iot等通信模块都是基于AT指令的设计

AT指令

简介

AT指令集是从终端设备(Terminal Equipment,TE)或数据终端设备(Data Terminal
Equipment,DTE)向终端适配器(Terminal Adapter,TA)或数据电路终端设备(Data Circuit
Terminal Equipment,DCE)发送的。
其对所传输的数据包大小有定义:即对于AT指令的发送,除AT两个字符外,最多可以接收1056个
字符的长度(包括最后的空字符)。
每个AT命令行中只能包含一条AT指令;对于由终端设备主动向PC端报告的URC指示或者response
响应,也要求一行最多有一个,不允许上报的一行中有多条指示或者响应。AT指令以回车作为结
尾,响应或上报以回车换行为结尾。

初始配置和指令

esp8266-01s出厂波特率正常是115200, 注意:AT指令,控制类指令(发送新行)都要加回车,数据传输时不加回车

  • 上电后,通过串口输出一串系统开机信息,购买的部分模块可能电压不稳,导致乱码,以 ready 为准
#####################################
禘鼃VAM?lb<l$?@>??D:j?H^M~?
ready
    
#####################################
  • 上电后发送AT指令测试通信及模块功能是否正常
AT

OK

通过AT指令配置成9600波特率

AT+UART=9600,8,1,0,0

OK

入网设置

  • 设置工作模式
AT+CWMODE=3 //1. 是station(设备)模式 2.是AP(路由)模式 3.是双模

OK
  • 以设备模式接入家中路由器
AT+CWJAP="TP-LINK_C861","makabaka987"//指令
WIFI CONNECTED //结果
WIFI GOT IP //结果
  • 查询IP地址
AT+CIFSR //指令
+CIFSR:APIP,"192.168.4.1"
+CIFSR:APMAC,"4e:75:25:0d:ae:2f"
+CIFSR:STAIP,"192.168.0.148"
+CIFSR:STAMAC,"4c:75:25:0d:ae:2f"
OK

连接到TCP server

  1. 开关网络助手,设立TCP服务器

51单片机之串口_第23张图片

  1. 连接服务器
AT+CIPSTART="TCP","192.168.0.113",8888 //指令,注意双引号逗号都要半角(英文)输入
CONNECT //结果:成功
OK //结果:成功
  1. 发送数据
AT+CIPSEND=4 // 设置即将发送数据的长度 (这里是4个字节)
>CLCA // 看到大于号后,输入消息,CLCA,不要带回车
Response :SEND OK //结果:成功
//注意,这种情况下,每次发送前都要先发送AT+CIPSEND=长度 的指令,再发数据!

透传

每次发送数据都要进行字符长度设定,如果设置成透传,就有点像蓝牙模块的玩法

在连接TCP服务器之后操作

AT+CIPMODE=1 //开启透传模式
Response :OK
AT+CIPSEND //带回车
Response: > //这个时候随意发送接收数据

退出透传模式

//在透传发送数据过程中,若识别到单独的⼀包数据 “+++”,则退出透传模式

单片机实现

#include 
#include 
#include 
#define SIZE 12

sfr AUXR = 0x8E;
sbit LED1 = P2^0;
sbit LED2 = P2^1;
sbit LED3 = P2^2;
sbit LED4 = P2^3;
sbit LED5 = P2^4;

code char Link_Web[] = "AT+CWJAP=\"TP-LINK_C861\",\"persist011104\"\r\n";	//连接网络
code char Link_Ser[] = "AT+CIPSTART=\"TCP\",\"192.168.1.7\",8880\r\n";		//连接服务器
char TH_Mode[]  = "AT+CIPMODE=1\r\n";									//透传模式
char START_TH[] = "AT+CIPSEND\r\n";										//开启透传
char Link_Web_Flag = 0;												//连接网络标志位
char AT_OK_Flag = 0;												//OK返回值标志位
char buffer[SIZE];

void UART_Init()
{
	SCON = 0x50;		//配置串口为8位,可变,REN允许串行接收
	TMOD &= 0x0F;		//清空定时器1,定时器0保持不变
	TMOD |= 0x20;		//设置定时器1位8位自动重载
	TL1 = 0xFD;			//9600波特率初值
	TH1 = 0xFD;
	TR1 = 1;				//允许定时器1工作
	AUXR = 0x01;		//禁止ALE电磁辐射输出
	EA = 1;					//开启总中断
	ES = 1;					//开启串口中断
}

void SendByte(char data_UART)
{
	SBUF = data_UART;
	while(!TI);
	TI = 0;
}

void SendString(char *str)
{
	while(*str != '\0')
	{
		SendByte(*str);
		str++;
	}
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void main()
{
	LED1 = LED2 = LED3 = LED4 = LED5 = 1;
	UART_Init();
	
	Delay1000ms();		//上电启动后,给1秒缓冲时间
	
	SendString(Link_Web);
	while(!Link_Web_Flag);
	while(!AT_OK_Flag);
	AT_OK_Flag = 0;
	if(Link_Web_Flag)
	{
		LED1 = 0;			//如果网络连接成功,LED1亮
	}
	
	SendString(Link_Ser);
	while(!AT_OK_Flag);
	if(AT_OK_Flag)
	{
		LED2 = 0;		//如果服务器连接成功,LED2亮
	}
	AT_OK_Flag = 0;
	
	SendString(TH_Mode);
	while(!AT_OK_Flag);
	if(AT_OK_Flag)
	{
		LED3 = 0;		//如果处于透传模式下,LED3亮
	}
	AT_OK_Flag = 0;
	
	SendString(START_TH);
	while(!AT_OK_Flag);
	if(AT_OK_Flag)
	{
		LED4 = 0;		//如果打开透传模式,LED4亮
	}

	while(1)
	{
		SendString("Hello World\r\n");
		Delay1000ms();
	}
}

void UART_handler () interrupt 4
{
	static int i = 0;		//静态变量,初始化只执行一次
	char tmp;
	
	if(RI == 1)
	{
		RI = 0;
		tmp = SBUF;
		if(tmp == 'W' || tmp == 'O' || tmp == 'L')	//如果tmp检测到这些关键字眼地时候,i从0开始计数
		{
			i = 0;
		}
		buffer[i] = tmp;
		i++;
		
		if(buffer[0] == 'W' && buffer[5] == 'G')	//如果检测到WIFI GOT IP的指令的时候,将																Link_Web_Flag置1
		{
			Link_Web_Flag = 1;
			memset(buffer,'\0',SIZE);				//清空缓存区,防止造成别的指令的等待
		}
		
		if(buffer[0] == 'O' && buffer[1] == 'K')		//如果检测到OK指令的时候,将AT_OK_Flag置1
		{
			AT_OK_Flag = 1;
			memset(buffer,'\0',SIZE);
		}
		
		if(buffer[0] == 'L' && buffer[2] == '1')		//如果检测到L_1的指令的时候,LED5亮
		{
			LED5 = 0;
			memset(buffer,'\0',SIZE);
		}
		
		if(buffer[0] == 'L' && buffer[2] == '0')		//如果检测到L_0的指令的时候,LED5灭
		{
			LED5 = 1;
			memset(buffer,'\0',SIZE);
		}
		
		if(i == SIZE)
		{
			i = 0;
		}
	}
	
	if(TI);
}	

esp8266作为服务器

  • USB转TTL插入电脑,TX–RX RX-TX VCC-3.3V GDN-GND
  • 查询IP地址:AT+CIFSR
//1 配置成双模
AT+CWMODE=2
Response :OK
//2 使能多链接AT+CIPMUX=1
Response :OK
//3 建立TCPServer
AT+CIPSERVER=1 // default port = 333
Response :OK
//4 发送数据
AT+CIPSEND=0,4 // 发送4个字节在连接0通道上
>abcd //输入数据,不带回车
Response :SEND OK
//• 接收数据
+IPD, 0, n: xxxxxxxxxx //+IPD是固定字符串 0是通道,n是数据长度,xxx是数据
//断开连接
AT+CIPCLOSE=0
Response :0, CLOSED OK
//ESP-01s工作在路由模式,课程查询路由器IP地址192.168.4.2,使用的服务器默认端口号333
//ESP-01s收到收到数据op/cl给上官一号,实现LED4的亮/灭

#include 
#include 
#include 
#define SIZE 12

sfr AUXR = 0x8E;
sbit LED1 = P2^0;
sbit LED2 = P2^1;
sbit LED3 = P2^2;
sbit LED4 = P2^3;
sbit LED5 = P2^4;

char Set_Dou[] = "AT+CWMODE=2\r\n";					//设置双模模式
char More_Con[] = "AT+CIPMUX=1\r\n";				//设置使能多链接
char Set_Client[] = "AT+CIPSERVER=1\r\n";			//建立TCP Client客户端
char Send_Data[] = "AT+CIPSEND=0,5\r\n";			//发送数据
char Set_Client_Flag = 0;							//建立客户端标志位
char AT_OK_Flag = 0;				   			//OK返回值标志位
char buffer[SIZE];

void UART_Init()
{
	SCON = 0x50;		//配置串口为8位,可变,REN允许串行接收
	TMOD &= 0x0F;		//清空定时器1,定时器0保持不变
	TMOD |= 0x20;		//设置定时器1位8位自动重载
	TL1 = 0xFD;			//9600波特率初值
	TH1 = 0xFD;
	TR1 = 1;				//允许定时器1工作
	AUXR = 0x01;		//禁止ALE电磁辐射输出
	EA = 1;					//开启总中断
	ES = 1;					//开启串口中断
}

void SendByte(char data_UART)
{
	SBUF = data_UART;
	while(!TI);
	TI = 0;
}

void SendString(char *str)
{
	while(*str != '\0')
	{
		SendByte(*str);
		str++;
	}
}

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void main()
{
	LED1 = LED2 = LED3 = 1;
	LED4 = LED5 = 1;
	UART_Init();
	
	Delay1000ms();		//上电启动后,给1秒缓冲时间
	
	SendString(Set_Dou);
	while(!AT_OK_Flag);
	if(AT_OK_Flag)
	{
		LED1 = 0;								//设置双模模式成功,LED1亮
	}
	AT_OK_Flag = 0;

	SendString(More_Con);
	while(!AT_OK_Flag);
	if(AT_OK_Flag)
	{
		LED2 = 0;								//设置使能多链接成功,LED2亮
	}
	AT_OK_Flag = 0;
	
	SendString(Set_Client);
	while(!Set_Client_Flag);
	if(Set_Client_Flag)
	{
		LED3 = 0;								//建立TCP服务器成功,LED3亮
	}
	AT_OK_Flag = 0;
	while(1)
	{
		SendString(Send_Data);
		Delay1000ms();
		Delay1000ms();
		SendString("Hello");
		Delay1000ms();
		Delay1000ms();
	}
}

void UART_handler () interrupt 4
{
	static int i = 0;		//静态变量,初始化只执行一次
	char tmp;
	
	if(RI == 1)
	{
		RI = 0;
		tmp = SBUF;
		if(tmp == '0' || tmp == 'O' || tmp == ':')	//如果tmp检测到这些关键字眼地时候,i从0开始计数
		{
			i = 0;
		}
		buffer[i] = tmp;
		i++;
		
		if(buffer[0] == 'O' && buffer[1] == 'K')		//如果检测到OK指令的时候,将AT_OK_Flag置1
		{
			AT_OK_Flag = 1;
			memset(buffer,'\0',SIZE);
		}
		
		if(buffer[0] == '0' && buffer[2] == 'C')		//如果检测到0,CONNECT的指令的时候,将																Set_Client_Flag置1
		{
			Set_Client_Flag = 1;
			memset(buffer,'\0',SIZE);					//清空缓存区,防止造成别的指令的等待
		}
		
		if(buffer[0] == ':' && buffer[1] == 'o' && buffer[2] == 'p')		//如果检测到:op的指令的时候,LED4亮
		{
			LED4 = 0;
			memset(buffer,'\0',SIZE);
		}
		
		if(buffer[0] == ':' && buffer[1] == 'c' && buffer[2] == 'l')		//如果检测到:cl的指令的时候,LED4灭
		{
			LED4 = 1;
			memset(buffer,'\0',SIZE);
		}
		
		if(i == SIZE)
		{
			i = 0;
		}
	}
	
	if(TI);
}	

4G模块

产品简介

EC03-DNC是亿佰特推出的 LTE CAT1 数传模块产品, 该产品软件功能完善, 覆盖绝大多
数常规应用场景, EC03-DNC 是为实现串口设备与网络服务器,通过网络相互传 输 数 据
而 开 发 的 产 品 , 该 产 品 是 一 款 带 分 集 接 收 功 能 的LTE-FDD/LTE-TDD 无
线通信数传模块, 支持 LTE-FDD , LTE-TDD 网络数据连接, 用户只需通过简单的设
置, 即可实现串口到网络服务器的双向数据透明传输。

模块使用 2.0mm 排针方便客户设备集成, 使用 5V~18V 宽电压供电。 支持移动、
联通、 电信 4G 卡, 通信与 LED 指示采用兼容电平, 默认 3.3V 可适用 5V 电平, 具有抗
干扰能力, 能适应使用在一些电磁干扰强的环境当中, 比如一些电力行业当中。 本章
是针对 EC03-DNC产品的快速入门介绍, 搭建最简易的硬件环境测试 EC03-DNC的网络
传输功能, 即实现串口设备(这里指电脑) 到网络服务器的数据双向透传 。

51单片机之串口_第24张图片

功能特点

  • 采用最新4G CAT1方案;
  • 支持数据透明传输, 支持TCP、 UDP 网络协议, 支持心跳包、 注册包功能最大支持60个字节数;
  • 支持MQTT协议, 支持接入OneNet平台、 百度云平台、 阿里云平台的MQTT服务;
  • 支持两路 Socket 链路同时收发;
  • 支持 Modbus RTU 与 Modbus TCP 自动相互转换;
  • 支持网络AT指令, 可以通过网络, 远程配置设备;
  • LTE-FDD: 最大下行速率 10 Mbps, 最大上行速率 5 Mbps; LTE-TDD: 最大下行速率 7.5 Mbps, 最大上行速率 1 Mbps ;
  • 软件看门狗设计, 系统稳定。
  • 支持APN/VPN。
  • 软件和用户手册下载地址

模块使用

可以将模块和usb转ttl模块相连接,VCC-VCC GND-GND TXD-RXD RXD-TXD

将模块的天线、sim卡、电源接好,注意sim卡的方向,如果插的正确,标有4G字样的灯会亮。

51单片机之串口_第25张图片

快速入门

模块默认波特率115200,在第一次使用的时候不要选错波特率

  1. 进入 AT 指令模式, 在串口助手内发送+++(除了+++不需要勾选发送新行, 其他 AT 指令都需要勾选发送新行才有效), 必须在发送+++指令 3s 内发送其他任意 AT 指令(除重启 AT 指令外)才能完全进入 AT 指令模式。
  2. 进入 AT 指令模式后, 使用 AT+CPIN 查看SIM 卡接入情况: 例如:
 AT+CPIN
 
 +OK=1		// SIM 卡已接入

使用 AT+CSQ 查看当前信号强度: 例如:

AT+CSQ

+OK=26		//表示当前信号强度正常, 如果回复 99 表示当前信号强度异常, 请查看当前为天线是否连好
  1. 观察SIM卡灯是否亮起,AT+ICCID获得SIM卡信息:
AT+ICCID

+OK=89860083044994071059		//当前SIM 卡的 ICCID 号

由于4G模块属于公网通信,与之前的WIFI模块的局域网通信不同,所以要架设一个可供内网穿透的服务器,借用花生壳软软件

51单片机之串口_第26张图片

首先架设一个TCP Server

51单片机之串口_第27张图片

然后借用花生壳软件建立一个服务器,建立好后会出现连接成功

51单片机之串口_第28张图片

51单片机之串口_第29张图片

  1. AT+SOCK=TCPC,115.236.153.177,11933 连接socket服务器, 115.236.153.177是公网IP地址,通过花生壳获得,11933是端口号,参数之间逗号隔开
AT+SOCK=TCPC,115.236.153.177,11933

+OK		//服务器连接成功
  1. AT+LINKSTA查看连接状态,如果第四步没有问题,此时串口返回+OK=Connect
AT+LINKSTA

+OK=Connect

每次修改后都记得重启,然后模块会自动连接服务器,进入透传模式,与服务器进行通信

修改4G模块波特率

发送指令查询现行波特率

AT+UART

+OK=9600,NONE		//现行波特率

修改波特率

AT+UART=9600,NONE

+OK				//修改成功,记得重启模块,选用9600波特率

单片机实现

/*main.c*/

#include "uart.h"
#include "pin.h"

void main()
{
	LED1 = 1;			//上电熄灭LED灯,进行串口初始化
	UART_Init();
	
	while(1)
	{
		
	}
}
/*uart.c*/

#include "string.h"
#include "pin.h"
#define SIZE 12

char buffer[SIZE];

void UART_Init()
{
	AUXR = 0x01;
	SCON = 0x50;			//8位UART波特率可变,REN使能接收
	TMOD &= 0x0F;
	TMOD |= 0x20;			//配置定时器1为8位自动重载定时器
	TL1 = 0xFD;
	TH1 = 0xFD;
	TR1 = 1;
	EA = 1;
	ES = 1;
}

void UART_Hnadler () interrupt 4 
{
	static int i;
	char tmp;
	
	if(RI)
	{
		RI = 0;
		tmp = SBUF;
		if(tmp == ':')
		{
			i = 0;
		}
		buffer[i] = tmp;
		i++;
		
		if(buffer[0] == ':' && buffer[1] == 'o' && buffer[2] == 'p')		//如果发送指令:op,开灯
		{
			LED1 = 0;
			i = 0;
			memset(buffer,'\0',SIZE);
		}
		
		if(buffer[0] == ':' && buffer[1] == 'c' && buffer[2] == 'l')		//如果发送指令:cl,关灯
		{
			LED1 = 1;
			i = 0;
			memset(buffer,'\0',SIZE);
		}
		
		if(i == SIZE)
		{
			i = 0;
		}
	}
	
	if(TI);
}
/*pin.h*/

#include "reg52.h"

sfr AUXR = 0x8E;
sbit LED1 = P3^7;

你可能感兴趣的:(51单片机,51单片机,c语言)