登录  | 立即注册

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

扫一扫,访问微社区

QQ登录

只需一步,快速开始

开启左侧

[寒假笔记] 基于单片机驱动用LCD1602显示实现服务器性能监控

[复制链接]
发表于 2018-2-23 12:07:48 | 显示全部楼层 |阅读模式
学习笔记
学习科目: 基于单片机驱动用LCD1602实现的的服务器/计算机性能监控
学习安排: 基于单片机驱动用LCD1602显示实现的服务器/计算机性能监控
开始时间: 2018-02-23
结束时间:
本帖最后由 Linkfox.cc@灵狐 于 2018-2-23 12:12 编辑

过年几天看到了一个文章是用树莓派驱动1602基于PHP探针和Py的服务器监控



QQ截图20180223111913.png
突发奇想 就想用单片机也做一个
我在自己房间里假设了一台服务器,初中时候不会linux就安的winserver2010用kangle3.4做网站平台
毕竟是win么,由于运行的服务太多还太杂经常的爆内存卡硬盘然后一会就宕机了,虽然我近期申请了一个监控服务器状态但是仅仅功能是ping我的服务器
这个kangle估计也没用心维护,真正代码跑溢出的时候机器能ping通,但是cpu和内存都爆满,根本无法响应外部请求
所以我就想用单片机来监控服务器的CPU,RAM,磁盘读写状态

首先就要实现从电脑到单片机的通讯问题

串口通讯是一个一个字节传送的,需要一个变量来储存之前接收的数据

在串口中断里写这段代码
[mw_shl_code=c,true]void  serial() interrupt 4
{
   ES = 0;
   RI = 0;
   buf = SBUF;
         senddata(buf);
         temp=buf;

   if(count<32)
   {         

                 if(count<16){
                 cdis1[count]=temp;
                 }else{
                 cdis2[count-16]=temp;
                 }
    count++;

                 if(count==32)
                         playflag=1;
    }

   ES = 1;

}[/mw_shl_code]

我实在想不出来如何判断数据已经传送完毕,然后生成这段str
所以只能以数据满32位即LCD1602的所有显示位为准
就是数据传送满32位LCD1602才显示然后给一个 标志位表示可以显示

有一点问题我还是不太明白,我把显示函数加在了中断里,然后编译的时候说函数重定义了,没办法只好在主函数中循环驱动
下面是将字符串显示的函数
QQ截图20180223114028.png


我之前写的一个LCD1602驱动的函数我这里就直接引用了
下面是主文件 main.c
[mw_shl_code=c,true]
#include <reg52.h>
#include <intrins.h>
#include <API__LCD1602.h>        
#define uchar  unsigned char
#define uint   unsigned int
uchar temp,buf,m,count;
bit   playflag=0;
uchar data  cdis1[ ] = {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20};
uchar data  cdis2[ ] = {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20};
//===================================
void delay1(uint ms)
{uchar k;while(ms--){for(k = 0; k < 120; k++);}}
//===================================
void senddata(uchar dat)//数据回传,调试时候使用的
{
     SBUF =dat;
     while(!TI);
     TI = 0;
}
//===================================
void  serial() interrupt 4  //串行中断
{
   ES = 0;                //关闭串行中断
   RI = 0;                //清除串行接受标志位
   buf = SBUF;            //从串口缓冲区取得数据                     
         senddata(buf);
         temp=buf;

   if(count<32)
   {
                 if(count<16){
                 cdis1[count]=temp;
                 }else{
                 cdis2[count-16]=temp;
                 }
    count++;
                 if(count==32)
                         playflag=1;
    }
ES = 1;
}
//===================================
void  play()//str显示到1602上
{
   if(playflag)
   {         
                 LCD1602_Clear();
                 LCD1602_Dis_Str(0,0,cdis1);
                 LCD1602_Dis_Str(0,1,cdis2);
//     for(m=0;m<=16;m++) //一开始用显示单个字符,怎么调试第一个字符都不对
//     {
//                 LCD1602_Dis_OneChar(m-1,0,cdis[m-1]);
//                        senddata(cdis[m-1]);
//         }
//     for(m=16;m<=32;m++)
//     {
//                 LCD1602_Dis_OneChar(m-17,1,cdis[m-1]);
//         }
     playflag=0;              
     count=0x00;
     for(m=0;m<=16;m++)      
     {
                 cdis1[m]=0x20;         //清显存单元   
                cdis2[m]=0x20;
                delay1(5);}} }
//===================================
void main(void) //主函数
{
    P0 = 0xff;
    P2 = 0xff;
    SCON=0x50;           //设定串口工作方式
    PCON=0x00;           //波特率不倍增
    TMOD=0x20;           //定时器1工作于8位自动重载模式, 用于产生波特率
    EA=1;
    ES = 1;              //允许串口中断
    TL1=0xfd;
    TH1=0xfd;             //波特率9600
    TR1=1;
                Init_LCD1602();
                LCD1602_Dis_Str(0,0,"Ready To Receive");
                LCD1602_Dis_Str(3,2,"Linkfox.cc");
    while(1)        
    {play();
}
}
[/mw_shl_code]
文章结尾是API__LCD1602.h的源码
电脑端读取数据并进行串口发送的源码我就不贴了,代码写的太菜,至于读取CPURAMDiskIO状态都是github和百度出来的,,实在不好意思贴
我把程序上传一下以便大家玩玩
这是电脑上的程序,设置通讯 端口,波特率以及1602刷新的时间
QQ截图20180223120244.png

这是现在运行的状态,完美监控!
QQ截图20180223115807.png

妈妈再也不用担心我的服务器宕机啦~~~

下面是 API__LCD1602.h的代码
直接include即可
[mw_shl_code=c,true]/*********************************************************************************
//        【LCD1602驱动API】
//
//        【Linkfox.cc@灵狐】
//  【ver 1.6】
//        【Date 2018.2.11】
//----------------------------------
//        Init_LCD1602()
//        使用前先初始化
//----------------------------------        
//        LCD1602_Dis_Str()
//        在指定位置显示字符串
//----------------------------------        
//        LCD1602_Dis_OneChar()
//        在指定位置显示一个字符
//----------------------------------        
//        LCD1602_Clear()
//        清屏
**********************************************************************************/
#include <reg52.h>

typedef unsigned char uchar;
typedef unsigned int uint;

#define LCD1602_DB P0        //LCD1602数据总线

sbit LCD1602_RS = P3^5;         //RS端
sbit LCD1602_RW = P3^6;         //RW端
sbit LCD1602_EN = P3^4;         //EN端
//sbit DU = P2^6;//
//sbit WE = P2^7;//数码管位选段选用于关闭数码管显示
//DU = 0;
//WE = 0;//关闭数码管显示
/*=================================================
*函数名称:Read_Busy
*函数功能:判断1602液晶忙,并等待
=================================================*/
void Read_Busy()
{
        uchar busy;
        LCD1602_DB = 0xff;//复位数据总线
        LCD1602_RS = 0;          //拉低RS
        LCD1602_RW = 1;          //拉高RW读
        do
        {
                LCD1602_EN = 1;//使能EN
                busy = LCD1602_DB;//读回数据
                LCD1602_EN = 0;         //拉低使能以便于下一次产生上升沿
        }while(busy & 0x80); //判断状态字BIT7位是否为1,为1则表示忙,程序等待
}
/*=================================================
*函数名称:LCD1602_Write_Cmd
*函数功能:写LCD1602命令
*调用:Read_Busy();
*输入:cmd:要写的命令
=================================================*/
void LCD1602_Write_Cmd(uchar cmd)
{
        Read_Busy();         //判断忙,忙则等待
        LCD1602_RS = 0;
        LCD1602_RW = 0;        //拉低RS、RW操作时序情况
        LCD1602_DB = cmd;//写入命令
        LCD1602_EN = 1;         //拉高使能端 数据被传输到LCD1602内
        LCD1602_EN = 0;         //拉低使能以便于下一次产生上升沿
}
/*=================================================
*函数名称:LCD1602_Write_Dat
*函数功能:写LCD1602数据
*调用:Read_Busy();
*输入:dat:需要写入的数据
=================================================*/
void LCD1602_Write_Dat(uchar dat)
{
        Read_Busy();
        LCD1602_RS = 1;
        LCD1602_RW = 0;
        LCD1602_DB = dat;
        LCD1602_EN = 1;
        LCD1602_EN = 0;
}
/*=================================================
*函数名称:LCD1602_Dis_OneChar
*函数功能:在指定位置显示一个字符
*调用:LCD1602_Write_Cmd(); LCD1602_Write_Dat();        
*输入:x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行)
                dat:需要显示的数据以ASCLL形式显示
=================================================*/
void LCD1602_Dis_OneChar(uchar x, uchar y,uchar dat)
{
        if(y)        x |= 0x40;
        x |= 0x80;
        LCD1602_Write_Cmd(x);
        LCD1602_Write_Dat(dat);               
}
/*=================================================
*函数名称:LCD1602_Dis_Str
*函数功能:在指定位置显示字符串
*调用:LCD1602_Write_Cmd(); LCD1602_Write_Dat();
*输入:x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行)
                *str:需要显示的字符串
=================================================*/
void LCD1602_Dis_Str(uchar x, uchar y, uchar *str)
{
        if(y) x |= 0x40;
        x |= 0x80;
        LCD1602_Write_Cmd(x);
        while(*str != '\0')
        {
                LCD1602_Write_Dat(*str++);
        }
}
/*=================================================
*函数名称:LCD1602_Clear()
*函数功能:清屏
*调用:LCD1602_Write_Cmd();
=================================================*/
void LCD1602_Clear()
{
                LCD1602_Write_Cmd(0x01); //清除显示
}
/*=================================================
*函数名称:Init_LCD1602
*函数功能:1602初始化
*调用:        LCD1602_Write_Cmd();
=================================================*/
void Init_LCD1602()
{
        LCD1602_Write_Cmd(0x38); //        设置16*2显示,5*7点阵,8位数据接口
        LCD1602_Write_Cmd(0x0c); //开显示
        LCD1602_Write_Cmd(0x06); //读写一字节后地址指针加1
        LCD1602_Write_Cmd(0x01); //清除显示
}[/mw_shl_code]

InfoToC51_ver1.3.zip

353.38 KB, 下载次数: 647

评分

参与人数 1铜板 +66 收起 理由
alpha + 66 有才

查看全部评分

好懒~~不想说~~~
发表于 2018-2-26 22:21:44 | 显示全部楼层
厉害了,上位机程序完全不会要我做这个的话估计还是要通过嵌入式网络访问PHP来做
该会员没有填写今日想说内容.
 楼主| 发表于 2018-3-3 21:37:52 | 显示全部楼层
alpha 发表于 2018-2-26 22:21
厉害了,上位机程序完全不会要我做这个的话估计还是要通过嵌入式网络访问PHP来做

呼~刚刚收拾完返校的装备顺手刷了一下论坛才看到,,PHP探针是个好方法,我这个还需要插一根usb线。。。多谢提醒我有空改进加个无线的功能~~
好懒~~不想说~~~
发表于 2018-3-4 13:52:25 | 显示全部楼层
Linkfox.cc@灵狐 发表于 2018-3-3 21:37
呼~刚刚收拾完返校的装备顺手刷了一下论坛才看到,,PHP探针是个好方法,我这个还需要插一根usb线。。。 ...

嗯嗯,加个LWIP 协议栈就可以了
该会员没有填写今日想说内容.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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