C51- 4G 与 LCD

EC03-DNC 4G模块的使用:

接线4根 -- 基于串口 -- GND VCC RX XT

支持透传 --  支持 TCP,UDP网络协议
支持MQTT协议
支持Socket链路同时收发

波特率: 默认 115200 
==============================

AT指令:

1. 进入AT模式:线接好,
然后向串口发送 +++  -- 注意不要换新行,然后再3s内重新发送其他 AT 指令(除了重启AT指令之外)

2.进入AT  模式后,使用AT+CPIN 查看 SIM卡接入情况
  AT+CSQ    --  查询信号强度

3.接入服务器 ,   AT + SOCK=TCPC,116 

AT+ICCID  --  查询SIM卡的CCID号(集成电路识别码)

AT+UART  -- 查询串口的波特率
AT+UART=9600,NONE    // 9600  -- 修改波特率,  NONE,没有校验位 

AT+REBT  -- 整个模块重启


---------------------------------
特殊  -- 先配置,重启后才运行服务器的东西

错误码: 


ERR   -1  无效命令格式
-2    无效命令
-3    无效操作符
-4    无效参数
-5    操作不允许

================================================

内网穿透

作用 -- 配置一个外网可以访问的服务器

前言:

基本的局域网结构: 


单片机 192.168.0.112
电脑: 192.168.0.113
路由器:192.168.0.1

单片机和电脑通过路由器获得相同的网段可以相互访问

================

前提:公网通信 -- 不认识 局域IP

引入:“内网IP穿透”:

概念:为局域网的设备提供一个外网可访问的地址和端口

步骤:

先通过网络调试助手 -- 架设 服务器

然后通过花生壳 生成 TCP 服务器 -- 得到一个外网IP

然后再自己创建一个TCP 客户端,发送信息过去给自己的服务器

===============================================

AT配置4G模块

配置4G模式 --让他访问服务器:

//查看当前心跳包:
AT+HEARTINFO:
// 1 ASCLL    0-- HEX
AT+HEARTINFO=1,sgNo1   


//查询心跳包的频率(时间间隔):

AT+HEARTM
//配置:
AT+HEARTM=3

-------------------------------
服务器的连接:
AT+SOCK=TCPC,公网IP,公网端口号

115.236.153.174:50986

AT+SOCK=TCPC,115.236.153.174,50986

  
连上之后可以看到服务器 一直能接收到 我们发送的心跳包
//连接 上之后就是透传 -- 能相互通信了

=====================================
4G模块通过 外网 发送命令实现灯的开关  -- 和蓝牙一样简单 -- 但是需要提前做内网穿透 -- 优势是可以实现远距离传输

远程服务器发送指令控制C51点灯


#include"reg52.h"
#include<string.h>

#define SIZE 12

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

char cmd[SIZE];

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

    
    i = 43;
    j = 6;
    k = 203;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}

void UartInit(void)        //9600bps@11.0592MHz
{
    AUXR=0x01; //减少定时器辐射 -- 抗干扰
    SCON =0x50; //配置 串口口工作方式1,REN 使能接收
    //不配 PCON  -- 不设置倍数关系
    //配置定时器1为 8位自动重装
    TMOD &=0xF0; //高位清零
  TMOD |=0x20;  //00 10  -- 配置为定时器1为: 1 0 模式 -- 8位自动重装
  
    //定义初值
  TL1=0xFD;
    TH1=0xFD; // 9600 波特率的初值
  TR1= 1; // 定时器 -- 启动
    
    EA =1; // 开启总中断
    ES=1;  // 开启串口中断
    
}


void sendByte(char a)
{
SBUF = a;
while(!TI);
TI=0;    
}


void sendString(char *str)
{

 while(*str!='\0')
 {
 sendByte(*str);
 str++;
 } 

}


void main()
{
    
    D5=1;

    //配置C51串口的 通信方式:
    UartInit();
while(1){
   Delay1000ms();
  //往发送缓冲区 写入数据-- 就完成数据的发送
  //sendString("mengxianggiegie\r\n");
    

 }
}

void uartHandler() interrupt 4
{
    static i = 0;
    char tmp;
 if(RI) // 中断处理函数中,对于接收中断的响应
 {
    RI=0; //清楚接收中断标志位
      tmp=SBUF;
      if(tmp==':'){
    i=0; 
    }
      cmd[i++] = tmp;
    

    if(cmd[0]==':' && cmd[1]=='o' && cmd[2]=='p'){//收到 o-pen 开灯
     D5=0;
         i=0;    
         memset(cmd,'\0',SIZE);
    }
      if(cmd[0]==':' && cmd[1]=='c' && cmd[2]=='l'){//收到 o-pen 开灯
     D5=1; 
         i=0;    
         memset(cmd,'\0',SIZE);
    }
        if(i==12) 
            i=0;

 }
  
    
}


LCD  -- 1602:   16字 * 2行

管脚:

需要用 16 根线:

第 1 脚: VSS 为电源地
第 2 脚: VDD 接 5V 正电源
第 3 脚: VL 为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度
过高时会产生“鬼影”,使用时可以通过一个 10K 的电位器调整对比度

第 4 脚:RS 为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器 

第 5 脚:R/W 为读写信号线,高电平时进行读操作,低电平时进行写操作。当 RS 和 R/W 共
同为低电平时可以写入指令或者显示地址,当 RS 为低电平 R/W 为高电平时可以读忙信号,
当 RS 为高电平 R/W 为低电平时可以写入数据。
第 6 脚:E 端为使能端,当 E 端由高电平跳变成低电平时,液晶模块执行命令。
第 7~14 脚:D0~D7 为 8 位双向数据线。
第 15 脚:背光源正极。
第 16 脚:背光源负极

============================
配 RS = 1 接收的就是数据  配RS=0 接收指令(地址)

so 需要封装两个 函数 -- 对应RS是高电平的时候写内容,低电平的时候写地址

-------------------------------------


LCD1602  和 C51 的连线:


电源:
VSS --  GND
VDD -- 5V

//对比度:
VO = GND


//控制线
RS -- P1.0
RW --P1.1
E -- P1.4

//背光灯
A -- 5V
K  -- GND

数据:
D0 ~ D7: P0.0 ~P0.7

只需要知道两件事:


知道在哪显示 :(地址)

 配RS=0 接收指令(地址)
知道显示什么:(内容)

配 RS = 1 接收的就是数据
就是ASCLL码 -- 直接输入字符即可 -- 'a'


 LCD1602 初始化过程(8bit)


(1)延时 15ms
(2)写指令 38H(不检测忙信号)
(3)延时 5ms
(4)以后每次写指令,读/写数据操作均需要检测忙信号
(5)写指令 38H:显示模式设置
(6)写指令 08H:显示关闭
(7)写指令 01H:显示清屏
(8)写指令 06H:显示光标移动设置
(9)写指令 0CH:显示开及光标设置

忙标志: 



RS =0       RW=1
怎么判断是否在忙呢? 
数据的高位 BF 的值:  1  -- 忙      0 --不忙


报错积累 --定义了函数但是程序中没有被调用
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
要求写入地址时,最高位是bit7 -- 恒为高电平- 第一行,第五个 1000 0101 -- 0x85

case1: 通过LCD输出一个字符 'C'

#include"reg52.h"
#include "intrins.h"

#define dataBuffer  P0 // 定义8位数据线,P0端口

sbit RS=P1^0;
sbit RW=P1^1;
sbit EN=P1^4;


void check_busy() //
{
    char tmp=0x80;
    dataBuffer=0x80;
    // 1000 0000  -- 0x80  只更新 bit7
    while(tmp &= 0x80){//只要tmp -- 数据位的高位 1 的时候就是一直忙的状态,只有不忙的时候才跳出while循环
  RS=0;
  RW=1;

    EN=0;
    _nop_();
    EN=1;
    _nop_();    
    _nop_();
    tmp=dataBuffer;//读取总线上面的数
  EN=0;
    _nop_();
    }

}

void Write_Cmd_Func(char cmd)
{
    check_busy(); //先检查是否繁忙
  RS=0; //写内容
  RW=0;

    EN=0;
    _nop_(); // 给一个微秒 
    dataBuffer=cmd;
    EN=1;
    _nop_(); // tpw tf
    EN=0;
    _nop_();
}

void Write_Data_Func(char dataShow)
{
    check_busy(); 
 RS=1;//写地址 -- 指令
    
 RW=0;

    EN=0;
    _nop_(); // 给一个微秒 
    dataBuffer=dataShow;
    EN=1;
    _nop_(); // tpw tf
    EN=0;
    _nop_();

}

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

    i = 27;
    j = 226;
    do
    {
        while (--j);
    } while (--i);
}


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

    i = 9;
    j = 244;
    do
    {
        while (--j);
    } while (--i);
}


void LCD1602_INIT()
{
  //LCD1602 初始化过程(8bit)
  //(1)延时 15ms
    Delay15ms();
//(2)写指令 38H(不检测忙信号)
  Write_Cmd_Func(0x38);    
    //(3)延时 5ms
    Delay5ms();
//(4)以后每次写指令,读/写数据操作均需要检测忙信号
//(5)写指令 38H:显示模式设置
      Write_Cmd_Func(0x38);    
//(6)写指令 08H:显示关闭
      Write_Cmd_Func(0x08);    
//(7)写指令 01H:显示清屏
      Write_Cmd_Func(0x01);    
//(8)写指令 06H:显示光标移动设置
      Write_Cmd_Func(0x06);    
//(9)写指令 0CH:显示开及光标设置
  Write_Cmd_Func(0x0C);    

}


void main()
{

char position =0x80 + 0x05;
char dataShow='C';
LCD1602_INIT();
Write_Cmd_Func(position);     //选择要显示的地址
Write_Data_Func(dataShow); // 选择要发送的字符
    
}


//注意读写 区别: 


读操作 : 先拉高 EN =1 后才去 读数据 tmp=dataBuffer;
写操作: 先 读取数据 tmp=dataBuffer; 在再拉高 EN=1 

====================================


case2:通过输出一行字符串

#include"reg52.h"
#include "intrins.h"

#define dataBuffer  P0 // 定义8位数据线,P0端口

sbit RS=P1^0;
sbit RW=P1^1;
sbit EN=P1^4;


void check_busy() // 检查是否繁忙 -- 读时序操作
{
    char tmp=0x80;
    dataBuffer=0x80;
    // 1000 0000  -- 0x80  只更新 bit7
    while(tmp &= 0x80){//只要tmp -- 数据位的高位 1 的时候就是一直忙的状态,只有不忙的时候才跳出while循环
  RS=0;
  RW=1;

    EN=0;
    _nop_();
    EN=1;
    _nop_();    
    _nop_();
    tmp=dataBuffer;//读取总线上面的数
  EN=0;
    _nop_();
    }

}

void Write_Cmd_Func(char cmd) // 写入地址 -- 写时序操作
{
    check_busy(); //先检查是否繁忙
  RS=0; //写内容
  RW=0;

    EN=0;
    _nop_(); // 给一个微秒 
    dataBuffer=cmd; 
    _nop_(); // 数据建立时间 --tsp 
    EN=1;
    _nop_(); // tpw tf
    EN=0;
    _nop_();
}

void Write_Data_Func(char dataShow) //写入内容 --  写时序操作
{
    check_busy(); 
 RS=1;//写地址 -- 指令
    
 RW=0;

    EN=0;
    _nop_(); // 给一个微秒 
    dataBuffer=dataShow;
    _nop_(); 
    EN=1;
    _nop_(); // tpw tf
    EN=0;
    _nop_();

}

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

    i = 27;
    j = 226;
    do
    {
        while (--j);
    } while (--i);
}


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

    i = 9;
    j = 244;
    do
    {
        while (--j);
    } while (--i);
}


void LCD1602_INIT()
{
  //LCD1602 初始化过程(8bit)
  //(1)延时 15ms
    Delay15ms();
//(2)写指令 38H(不检测忙信号)
  Write_Cmd_Func(0x38);    
    //(3)延时 5ms
    Delay5ms();
//(4)以后每次写指令,读/写数据操作均需要检测忙信号
//(5)写指令 38H:显示模式设置
      Write_Cmd_Func(0x38);    
//(6)写指令 08H:显示关闭
      Write_Cmd_Func(0x08);    
//(7)写指令 01H:显示清屏
      Write_Cmd_Func(0x01);    
//(8)写指令 06H:显示光标移动设置
      Write_Cmd_Func(0x06);    
//(9)写指令 0CH:显示开及光标设置
  Write_Cmd_Func(0x0C);    

}

void  LCD1602_ShowLine(char line,char row,char *string)
{
switch(line){
 case 1:
     Write_Cmd_Func(0x80 +  row); //选择开始位置
   while(*string){
   Write_Data_Func(*string);
   string++;
   }
 
    break;

 case 2:
     Write_Cmd_Func(0x80 + 0x40 +row); //选择开始位置
   while(*string){
   Write_Data_Func(*string);
   string++;
   } 
 
    break;


}


}


void main()
{

char position =0x80 + 0x05;
char dataShow='C';
LCD1602_INIT();
LCD1602_ShowLine(1,5,"NO.1");
LCD1602_ShowLine(2,0,"mxj handsome");
    

}


 

  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值