单片机
2017-03-04 23:36:11 huangchun96 阅读数 194
  • 51单片机综合小项目-第2季第4部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第2季第4个课程,也是51单片机学完之后的一个综合小项目,该项目运用了开发板上大多数外设设备,并将之结合起来实现了一个时间、温度显示以及报警功能、时间调整功能等单片机控制常见的功能,有一定代码量,需要一定调试技巧和编程能力来完成,对大家是个很好的总结和锻炼,并且能拓展项目经验。

    3411 人正在学习 去看看 朱有鹏
体重是体质测试的基本测试项目之一,随着社会的进步、科技的发展,传统的纯机械的体重测量仪逐渐被淘汰,取而代之的是以电子和机械相结合的简易体重测量仪。该系统以单片机8051为核心部件,它包括信号采集、电压转换、信号放大、A/D转换、LED显示等。通过电阻应变式称重传感器来采集外来信号,然后进行电压转换,通过放大电路把传感器采集来的信号放大,再通过A/D转换器,把模拟信号转换成数字信号传给单片机,再由汇编语言编制的软件程序对输入的信号进行采集、判断、分析、处理、运算,最终结果通过LED显示器显示出来。
2013-10-23 16:37:00 shaozhanyu 阅读数 1364
  • 51单片机综合小项目-第2季第4部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第2季第4个课程,也是51单片机学完之后的一个综合小项目,该项目运用了开发板上大多数外设设备,并将之结合起来实现了一个时间、温度显示以及报警功能、时间调整功能等单片机控制常见的功能,有一定代码量,需要一定调试技巧和编程能力来完成,对大家是个很好的总结和锻炼,并且能拓展项目经验。

    3411 人正在学习 去看看 朱有鹏
先说一下,交流电压,搞了我几个月,搞死我了,找了好几种方法转直流,进AD,就是不行。NND!!!!
在软件上仿真了好几个电路,都蛮好的波形。焊成板子就是不行,没出来电压,要么就是不滑,进了AD差天上去了,N次想砸了它GOUNIANGYANGDE!!!!!!
今天!!就在今(四声)天!!!!用的运放半波整流加RC滤波,不接入AD,调放大倍数后得到对应直流电压。接入AD后再看,MD!!!电压从珠穆朗玛都拉到贝加尔湖了!!中间串了个20K电阻(看TNND还拉低不!!)终于用表在线量OK了,程序OK了。TLC1543啊!!NNND!!!!让我一度认为运放不合适,想换其他运放,一度换电路,一度迷茫“为嘛仿真的和现实就不符昵”为嘛现实和理想差距这么大哩!!!!!一度认为仿真软件有问题!!!
所以:教训:(单片机) 教训版:
       注意电路供流能力,空载和负载的电压变化受到什么影响!
       注意器件属于电压输入型还是电流输入型,要“限流”,还是增大“供流”!!!
       不要总是考虑电阻大影响电压,人家电流小啊!!uA级别的,TLC1543就需要限流!!!
        以后再不注意这些问题!我就不姓少!!!!!!!!!!!!!
    还有一个待解决问题:运放做的正弦峰值检测电路,仿真蛮好的,焊成板子就是不行,电压直接奔最高了。为嘛!!这一切都是为嘛!!运放我用的LM358,用单电池供电不行,用俩电池供电,也不行!!!
/********多周期测频法,精度与晶振和闸门时间有关。晶振越大,闸门时间越长,都可以提高精度。************************/
#include <stc89c52.h>
#include <intrins.h>
#define uchar  unsigned char
#define uint  unsigned int
#define LCD12864_IO    P0
#define CLERADISPLAY   LCD12864_command(0x01);
int a1=0,a2=0,a3=0,a4=0,a5=0,a6=0;//存储电压值的每一位,设计a4,a5是小数位. 
const uchar num[]="0123456789. ";

//AD转换控制脚 
sbit  CLK = P1^0; //TLC1543 18P
sbit  ADDRESS = P1^1; //17P
sbit  SDATA = P1^2; //16P
sbit  CS  = P1^3; //15P 
/********************************************************************/
sbit LCD12864_RS=P2^5;  // 12864-st7920 4P RS 
sbit LCD12864_RW=P2^6;  //RW(5P) 
sbit LCD12864_EN=P2^7;   //E(6P)    
/********************************************************************/
void LCD12864_busy(void);
void LCD12864_command(unsigned char command);
void LCD12864_data(unsigned char dat);
void LCD12864_address(unsigned char row,unsigned char line);
void LCD12864_string(unsigned char row,unsigned char line,unsigned char *s);
void LCD12864_picture(unsigned char *gImage);
void LCD12864_init(void);
void LCD12864_char (unsigned char row,unsigned char line,unsigned char a);
unsigned char LCD12864_ReadData();
void LCD12864_Drawpoint(uchar X,uchar Y);
void LCD12864_LineX(unsigned char X0, unsigned char X1, unsigned char Y);
void LCD12864_LineY( unsigned char X, unsigned char Y0, unsigned char Y1);
void LCD12864_DrawPicture( unsigned char code *pic);
void clrgdram();
/********************************************************************/
//
double DAT[7]={1150.0, 1150.1, 1150.2, 285.0,15000.0, 4000.0,31000.0}; //都放大了10倍   
//       U     V      W      E     N     F   CINT     
// 控制脚 
sbit CONTRL=P1^7; //测频控制脚 
sbit SCANF =P2^0; //键盘扫描控制脚 
sbit LED2  =P2^1; //状态显示控制脚1 
sbit LED1  =P2^2; //状态显示控制脚2 
sbit SHUCHU=P2^3; //继电器输出控制脚 
//
bit FLAG; //测频标志位
bit xunhuanflag;//显示方式标志位 
bit outflag; //允许输出标志 
bit  eding;//额定状态标志   
// 按键存储   
bdata uchar key; //键值存储 
sbit key0=key^0;//停机    
sbit key1=key^1;//启动按钮 
sbit key2=key^2; //显示方式(高循环) 
sbit key3=key^3; //自检    
sbit key4=key^4;//灯检   
sbit key5=key^5;//复位    
sbit key6=key^6;//应急  (高应急)  
sbit key7=key^7;//油压(高有油压)    
uint t1h,t1l,t2h,t2l;//测频变量 
double cnt1,cnt2;
double AD; //定义为float 类型,可以防止下面做四则运算时每一步的值超出 范围 
unsigned long int  X;
/****************************************************************/         
uint rd1543(uchar address);//AD转换程序 
void voltage(); //电压检测 
void init();   //初始化 
void zhuansu();   //计算转速 
void reset();//测频计数定时复位 
uchar scanf(); //键盘扫描 
void keychuli();  //按键处理程序 
void baohu();
void display(unsigned long int sx,uchar j); //显示函数 
void displayFX(unsigned long int sx);
/*************************************************************/
void delayus(uint);
void delayms(uint);
void delays(uint m); //延时秒 

unsigned char code Bmp019[]=
{
/*------------------------------------------------------------------------------
;  若数据乱码,请检查字模格式设置,注意选择正确的取模方向和字节位顺序。
;  源文件 / 文字 : C:\Documents and Settings\Administrator\桌面\888.bmp字模
;  宽×高(像素): 128×64
;  字模格式/大小 : 单色点阵液晶字模,横向取模,字节正序/1024字节
;  数据转换日期  : 2010-7-26 20:46:48
------------------------------------------------------------------------------*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0xF8,0x00,0x00,0x00,0x3E,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x08,0x00,0x00,0x00,0x03,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
0x00,0x00,0x08,0x00,0x00,0x00,0x02,0x00,0x08,0x00,0x00,0x00,0x08,0x08,0x00,0x00,
0x00,0x20,0x18,0x00,0x00,0x00,0x08,0x00,0x1F,0x80,0x00,0x00,0x08,0x1F,0x80,0x00,
0x00,0x3D,0xF8,0x00,0x08,0x00,0x08,0xE0,0x02,0x00,0x00,0x7F,0xFF,0x00,0x80,0x00,
0x00,0x38,0x38,0x00,0x18,0x00,0x00,0x30,0x02,0x00,0x00,0x80,0x00,0x00,0x80,0x00,
0x00,0x30,0x08,0x01,0xF0,0x00,0x20,0x30,0x0F,0xF8,0x00,0x80,0x0F,0xE0,0x80,0x00,
0x00,0x30,0x38,0x00,0xFC,0x30,0x20,0xE0,0x83,0x80,0x00,0x00,0x00,0x20,0x00,0x00,
0x00,0x3F,0xF8,0x00,0x0C,0x30,0x01,0xE0,0x00,0xF0,0x00,0x02,0x00,0x20,0x00,0x00,
0x00,0x30,0x18,0x66,0xBF,0xF0,0x00,0xE0,0x0F,0xE0,0x00,0x07,0xFF,0xC0,0x00,0x00,
0x00,0x30,0x18,0x3F,0xFF,0xF0,0x00,0xC0,0x38,0x20,0x00,0x00,0x22,0x00,0x00,0x00,
0x00,0x20,0x00,0x00,0x00,0x30,0x00,0x80,0x00,0x00,0x00,0x00,0x83,0x00,0xFC,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xF0,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xFF,0xFE,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xFF,0xF0,0x00,0x7F,0xFF,0xFC,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xFF,0xC3,0xF0,0x00,0x03,0xE0,0x00,0x3F,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xFF,0x8C,0x00,0x00,0x00,0x03,0xFF,0x0F,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xFE,0x00,0x03,0xFF,0xE0,0x0F,0xFF,0x87,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFE,0x1F,0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xFE,0x03,0xFF,0xFF,0xFF,0x1F,0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0x1F,0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xF0,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0x87,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xC1,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x81,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0x83,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x7F,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x3F,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFC,0x00,0x03,0xFF,0xFF,0xFD,0x80,0x0F,0xF8,0x1F,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xF8,0x00,0x03,0xFF,0xFF,0xF8,0xFF,0x87,0xFC,0x0F,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xF8,0x03,0xFF,0xFF,0xFF,0xFF,0x00,0x1F,0xFE,0x0F,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xF8,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xF8,0x7F,0xF0,0x0F,0xFF,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xF8,0x3F,0xF0,0x1F,0xFF,0xFF,0xFF,0xFF,0xFC,0x0F,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFC,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x3F,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0x87,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xC1,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x83,0xC0,0xFF,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x07,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xFC,0x1F,0xFF,0xFF,0xFF,0xFF,0xFC,0x07,0xFF,0xC3,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xFE,0x03,0xFF,0xFF,0xFF,0xFF,0xF0,0x3F,0xFF,0xE1,0xFF,0xFF,0xC0,
0x03,0xFF,0xFF,0xFE,0x00,0x1F,0xFF,0xFF,0xFF,0xC3,0xFF,0xFF,0xE1,0xFF,0xFF,0xC0,
0x03,0x01,0xFF,0xF0,0x7F,0x03,0xFF,0xFF,0xFF,0xFF,0xF0,0x00,0x03,0xFF,0xFF,0xC0,
0x00,0x00,0x00,0x03,0xFD,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x3F,0xFF,0xFF,0xFF,0xC0,
0x00,0x3F,0x00,0x3F,0x80,0xFF,0xFF,0xFF,0xFF,0x10,0x1F,0xFF,0xFF,0xFF,0xFF,0xC0,
0x02,0x1F,0xFF,0xFE,0x03,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,
0x03,0x81,0xF8,0x00,0x03,0xFF,0xFF,0xFF,0xFE,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
//
 void delayms(uint k)
 {
uint data i,j;
for(i=0;i<k;i++)
  {
    for(j=0;j<121;j++)
     {;}
   }
 }
 //
void delayus(uint x)      
 {
    while(--x);
 }
 /***********************/
 void delays(uint m)
{
uint i,j;
for(i=0;i<m;i++)
  {
   for(i=0;i<1000;i++)
  {
    for(j=0;j<121;j++)
     {;}
   }
   }
}
 

void Mcu_init(void)
{
 
 LCD12864_init();
 
 
 CLERADISPLAY  
 CLERADISPLAY  
 LCD12864_init();
}

/*******************************************************************/
void LCD12864_busy(void)
{
    bit BF = 0;
    LCD12864_EN=0; 
    LCD12864_RS=0;
    LCD12864_RW=1;
    LCD12864_IO=0xff;  //单片机读数据之前必须先置高位
    do
    {
     LCD12864_EN=1;
        BF=LCD12864_IO&0x80;
        LCD12864_EN=0;
    } while(BF);
    
}
/*******************************************************************/
//          写入命令  
/*******************************************************************/
void LCD12864_command(unsigned char command)
{
    LCD12864_busy();
    LCD12864_EN=0;
    LCD12864_RS=0;
    LCD12864_RW=0;  
   LCD12864_IO=0xff;
    LCD12864_EN=1;
    LCD12864_IO=command;
    LCD12864_EN=0;
}

//读数据函数
unsigned char LCD12864_ReadData()
{
  unsigned char read_data;
   LCD12864_busy();
    LCD12864_IO=0xff;
 LCD12864_RS=1;
 LCD12864_RW=1;
 LCD12864_EN=0;
 LCD12864_EN=1;
 read_data=LCD12864_IO;
    LCD12864_EN=0;
    
 return(read_data);
}
/*******************************************************************/
//          写入一字节数据
/*******************************************************************/
void LCD12864_data(unsigned char dat)
{
   
    LCD12864_busy();
    LCD12864_EN=0;
    LCD12864_RS=1;
    LCD12864_RW=0;
    LCD12864_IO=0xff;
    LCD12864_EN=1;
    LCD12864_IO=dat;
    LCD12864_EN=0;
}

/*******************************************************************/
//          设置显示位置    row(1~4),line(1~8)
/*******************************************************************/
void LCD12864_address(unsigned char row,unsigned char line)
{
    switch(row) 
    {
        case 1:LCD12864_command(0x7f + line);
        break;
        case 2:LCD12864_command(0x8f + line);
        break;
        case 3:LCD12864_command(0x87 + line);
        break;
        case 4:LCD12864_command(0x97 + line);
        default:
        break;
    }
}
 /*****************显示 一个 字符  **************/
  void LCD12864_char (unsigned char row,unsigned char line,unsigned char a)

 
    LCD12864_address(row,line); 
    LCD12864_data(a);
}
/*******************************************************************/
//          在指定位置显示字符串
/*******************************************************************/
void LCD12864_string(unsigned char row,unsigned char line,unsigned char *s)

    unsigned char LCD12864_temp; 
    LCD12864_address(row,line); 
    LCD12864_temp=*s;
    while(LCD12864_temp != 0x00) 
    { 
        LCD12864_data(LCD12864_temp);
        LCD12864_temp=*(++s);
    }  
}
/****************************
0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 上半屏行坐标,表示的是多少列 
0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 下半屏行坐标,每组8列,每列16位,共128位, 
0x80
0x81
0x82
0x83
........
0x9f    //列坐标,共32个,表示的是行数 ,分两个半屏,每个32行,共64行 
         //Y坐标 只是用来确定具体坐标,在哪一行    
   功能:图形模式下,显示(X,Y)点    
        输入:X(0~127) Y(0~63) 相对屏幕坐标  
        输出:无
点亮某一点的操作步骤: 1.求出水平坐标X对应的地址和是哪一位  0x80-----0x8f  (范围0-15) X/16求地址 X%16求该地址哪一位
         2.求垂直坐标Y对应的地址和上下半屏  0x80------0x9f(范围0-63) Y本身就是8位地址,Y=63-Y ,Y--(0-31)
         3.写入行列地址(Y是行X是列),0x80+Y  ,0X80+X/16
                       4.读要显示的数据 DAT
                       5.区分上下半屏(X%16<=7&&X%16>=0是上半屏)写入数据每一位 DAT|0x80 ;DAT<<1
             注意:这个函数显示某一点时,可能会把上次显示的处于同一地址的其他位的点擦掉,所以先保存所有数据,最后显示,就连贯起来了

 *******************************/
/*******************************************************************/
  /**************************************************************/
//------------------清整个GDRAM空间----------------------------
/**************************************************************/
void clrgdram()
{
    unsigned char x,y ;
    for(y=0;y<64;y++)
    for(x=0;x<16;x++)
    {
       LCD12864_command(0x34);
       LCD12864_command(y+0x80);
       LCD12864_command(x+0x80);
       LCD12864_command(0x30);
      LCD12864_data(0x00);
      LCD12864_data(0x00);
    }
}
/******************************************/
/*******8==========================================================================
功能:图形模式下,显示(X,Y)点    
输入:X(0~127) Y(0~63)     
输出:无  
0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 上半屏行坐标,表示的是多少列,X地址 
0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 下半屏行坐标,X地址 (水平地址 )     
0x80  (垂直地址) 
0x81
0x82
0x83
........
0x9f    //列坐标,共32个,表示的是行数 ,分两个半屏,每个32行,共64行 
====================================================================**********/   
void LCD12864_Drawpoint(uchar X,uchar Y)
{
     uchar i= 0, j = 0,ok=0;
     uchar temp1 = 0x00,temp2 = 0x00;   
     LCD12864_command(0x34);  //8位,扩充指令,绘图关 
     LCD12864_command(0x36);  //8位,扩充指令,绘图开 
     i = X/16;  //计算出X字节地址(0X80-0X8F) 
     j = X%16;  //计算出该字节的具体位(0-15)       
     //Y = 63 - Y;
   if(Y>=0 && Y<=31)//判断上下半屏 
      {
        ok=1;
      }
   else if(Y>=32 && Y<=63)//下半屏
     {
       Y = Y - 32;//Y只有0-31共32个 地址 
       i = i + 8;//X地址进入下半屏 (0X88-0X8F)
    ok=1;
     }
      
   if(ok)
    { 
     //读数据操作
        LCD12864_command(0x80+Y);   //第一步:设置Y坐标,读数据先写地址,写GDRAM时先写垂直地址(0X80-0X9F)
        LCD12864_command(0x80+i);  //第二步:设置X坐标   
        LCD12864_ReadData();    //第三步:空读取一次   
        temp1 =LCD12864_ReadData();    //第四步:读取高字节,先读高字节 
        temp2 =LCD12864_ReadData();   //第五步:读取低字节    
          //图形模式下的写数据操作    
        LCD12864_command(0x80+Y);    //第一步:设置Y坐标  
        LCD12864_command(0x80+i);   //第二步:设置X坐标  
         if(j>=0 && j<=7)   //判断是高字节 
          {  
         LCD12864_data(temp1|(0x80>>j));  //第三步:写高字节数据  
         LCD12864_data(temp2);      //第四步:写低字节数据     
          }
         else if(j>7 && j<=15)   //判断是低字节 
           {   
              j = j - 8;  
            LCD12864_data(temp1);
            LCD12864_data(temp2|(0x80>>j));  //改变字节里的位   
           }   
      }

      
    
}
/******************************************/
//画线 
/********************************************/
//画水平线
void LCD12864_LineX(unsigned char X0, unsigned char X1, unsigned char Y)
{
 unsigned char Temp ;
 if( X0 > X1 )
 {
 Temp = X1 ;    //交换X0 X1值  
 X1 = X0 ;     //大数存入X1
 X0 = Temp;   //小数存入X0
 }
for( ; X0 <= X1 ; X0++ )
LCD12864_Drawpoint(X0,Y);
}
//画垂直线  
void LCD12864_LineY( unsigned char X, unsigned char Y0, unsigned char Y1)
{
unsigned char Temp ;
if( Y0 > Y1 )//交换大小值 
{
Temp = Y1 ;
Y1 = Y0 ;
Y0 = Temp ;
}
for(; Y0 <= Y1 ; Y0++)
LCD12864_Drawpoint( X, Y0) ;
}

/******************************************/
/**************画图************************/

  void LCD12864_DrawPicture( unsigned char code *pic)
{
    unsigned char i, j, k ;
        LCD12864_command(0x34);//开扩充指令 
        LCD12864_command(0x36);//开绘图功能   
for( i = 0 ; i < 2 ; i++ )//分上下两屏写    
{
for( j = 0 ; j < 32 ; j++)//垂直地址递加 ,行扫方式 
{
  LCD12864_command( 0x80 + j ) ;//写Y坐标(Y的范围: 0X80-0X9F )
if( i == 0 ) //写X坐标 
{
LCD12864_command(0x80);//上半屏 
}
else
{
LCD12864_command(0x88);//下半屏开始地址 
}
for( k = 0 ; k < 16 ; k++ ) //写一整行数据 
{
 LCD12864_data( *pic++ );//前面只写入首地址,后面依次写入数据,地址会自动递增  
}
}
}
LCD12864_command( 0x30);//恢复到一般模式 
}

//          初始化设置
/*******************************************************************/
void LCD12864_init(void)
{
    CLERADISPLAY      //  clear DDRAM
    LCD12864_command(0x30);     //  8 bits unsigned interface,basic instrument
    LCD12864_command(0x02);     //  cursor return
    LCD12864_command(0x0c);     //  display,cursor on
    LCD12864_command(0x03);   
    LCD12864_command(0x06);
    CLERADISPLAY       //  clear DDRAM
}
//
//显示函数
void display(unsigned long int sx,uchar j) 
{
      a1=sx/100000;
      a2=sx%100000/10000;
      a3=sx%10000/1000;//千位 
      a4=sx%1000/100;//百位 
      a5=sx%100/10;//十位 
   a6=sx%10;//个位 
 
   switch(j)
 {
    case 0x00: LCD12864_string(2,5,"  Ua    ");break;
    case 0x01: LCD12864_string(2,5,"  Ub    ");break;
    case 0x02: LCD12864_string(2,5,"  Uc    ");break;
    case 0x03: LCD12864_string(2,5,"  E     ");break;
    case 0x04: LCD12864_string(2,5,"  转速  ");break;
 case 0x05: LCD12864_string(2,5,"  频率  ");break;
 case 0x06: LCD12864_string(2,5,"脉冲计数");break;
 case 0x07: LCD12864_string(2,5,"        ");break;
  default :break;
 }
 LCD12864_command(0x90); //指定显示位置 
 LCD12864_data(num[a1]); //从最高位开始显示 
 LCD12864_data(num[a2]);
 LCD12864_data(num[a3]);
 LCD12864_data(num[a4]);
 LCD12864_data(num[a5]);
 LCD12864_data(num[10]);//小数点,前面测量计算时扩大了10倍,这里缩小回来 
 LCD12864_data(num[a6]);
 }

/*********************************
                       主函数入口 
/********************************************/ 
//主函数入口 
// 
main()
{
 
 uchar ii=0;
 CONTRL=0;
 FLAG=0;
 P0=0x00;
LED1=0;
LED1=1;
P0=0x00;
LED2=0;
LED2=1;
 P0=0x00;
 SHUCHU=0;//打开闸门 
 SHUCHU=1;
 baohu();//判断采样数据保护 
 Mcu_init();
CLERADISPLAY 
delays(1);
display(100000,7); 
LCD12864_char(1,2,'A');
LCD12864_string(1,2,"shaozhanyu");
delays(2);
clrgdram();
CLERADISPLAY
delays(1);
clrgdram();
delays(1);
LCD12864_LineX(8,113,25);
clrgdram();
CLERADISPLAY
delays(2);
clrgdram();
LCD12864_LineY(55,29,57);
delays(2);
clrgdram();
delays(1);
LCD12864_DrawPicture(Bmp019);
delays(3);

Mcu_init();
CLERADISPLAY 
LCD12864_string(3,1,"U V W E SP F CT");
LCD12864_char(2,1,'D');
LCD12864_string(4,1,"计数");
LCD12864_string(1,2,"少占鱼做");
delays(1);
/***************8888
    P0=0x10;//怠速,准备打开K5继电器,关闭其他输出继电器 
   SHUCHU=0;//打开输出闸门 
 SHUCHU=1;//关闭闸门 
 outflag=0;//输出标志位
 ******************/ 
  AD=0.0;
LCD12864_string(1,2,"灯光测试");
P0=0x41;
LED1=0;
LED1=1;
delayms(1000);
P0=0x42;
LED1=0;
LED1=1;
delayms(1000);
P0=0x44;
LED1=0;
LED1=1;
delayms(1000);
P0=0x48;
LED1=0;
LED1=1;
delayms(1000);
P0=0x50;
LED1=0;
LED1=1;
delayms(1000);
P0=0x60;
LED1=0;
LED1=1;
delayms(1000);
P0=0x41;
LED2=0;
LED2=1;
delayms(1000);
P0=0x42;
LED2=0;
LED2=1;
delayms(1000);
P0=0x44;
LED2=0;
LED2=1;
delayms(1000);
P0=0x48;
LED2=0;
LED2=1;
delayms(1000);
P0=0x50;
LED2=0;
LED2=1;
delayms(1000);
P0=0x60;
LED2=0;
LED2=1;
delayms(1000);
P0=0x00;
LED1=0;
LED1=1;
P0=0x00;
LED2=0;
LED2=1;
delayms(500);
LCD12864_string(1,2,"测继电器");

 P0=0x04;//启动 
 SHUCHU=0;//打开闸门 
 delays(3);
 SHUCHU=1;
  P0=0x18;//停机 
 SHUCHU=0;//打开闸门 
 delays(3);
 SHUCHU=1;
 P0=0x40;//怠速,准备打开K5继电器,关闭其他输出继电器 
 SHUCHU=0;//打开输出闸门 
 delays(3);
  SHUCHU=1;//关闭闸门 
 P0=0xa0;//准备合闸(交流,直流 内控制 )   
 SHUCHU=0;
  delays(3);
   SHUCHU=1;
  P0=0x00;
 SHUCHU=0;//打开闸门 
 SHUCHU=1;

keychuli(); //扫描并处理按键 
delayms(600);
voltage();
LCD12864_string(3,1,"U V W E SP F ");
LCD12864_char(2,1,'D');
LCD12864_string(1,2,"少氏出品");
delays(11);
///初始化 
LCD12864_string(4,1,"直流正常");
init();
 while(1)
 { 
   while(!FLAG); //等待频率测出 
  
  keychuli(); //扫描并处理按键 
LCD12864_string(1,2,"测量电压");
delayms(500);
 voltage();  //采样电压 
LCD12864_string(1,2,"转换完成");
delayms(600);
baohu();//判断采样数据保护 
 
  for(;ii<6;)
     {
 if(xunhuanflag==0)  //定点 
 {display(DAT[ii],ii);
  LCD12864_string(1,2,"定点显示");
  break;
  }  
  display(DAT[ii],ii);
  LCD12864_string(1,2,"循环显示");
     
  delayms(2200);
  keychuli();
  ii++;
 }//循环 显示结束 
  if(ii==6)
  ii=0;
 LCD12864_string(1,2,"下轮复位");
   delayms(700);
   init();
 
}
}
 /*************************************/
//初始化函数  
 void init()
{  
 /******T1定时器模式,外部INT1控制开启,T0计数器不允许中断,外部控制
INTO开启,外部中断0允许(EX0=1),   
     定时器T2中断允许 (ET2=1) ************/  
   CONTRL=0;
      FLAG=0;
   EX0=0;
      ET2=0;
      //三个定时器方式设置 
      TMOD=0x9d; //T0T1方式控制    
      T2MOD=0x00;
      T2CON=0x00;//定时器2,16位定时方式,自动重装。      
    
      TH0= 0x00; // T0高8位
      TL0= 0x00; // T0低8位
                      
      TH1= 0x00; // T1高8位
      TL1= 0x00; // T1低8位
   EXEN2=0;  
      TH2=256/256;
      TL2=256%256; 
   RCAP2H=256/256;
   RCAP2L=256%256;
      //中断设置        5
      EX0=1;//允许外部0输入中断(INT0引脚)
      ET2=1; //开定时中断2 
      IT0=1; //外部中断0边沿触发,下降沿到来触发 
      //优先级设置
   PX0=1;
      //预置T0,T1
      TR1=1;//先允许T1定时,因T1的GATE=1,还要等外部INT1高电平才计数
      TR0=1;//先允许T0计数 ,同T1一样,等待INTO高电平     
      TR2=1;//启动T2定时,不用外部控制,直接启动   
      EA=1; //开全局中断 
   CONTRL=1;
 
      //初始化完成......
}
 /**********************************
void reset()
 {
  CONTRL=0;
  FLAG=0;
  TL0=0x00;
  TH0=0x00;
  TL1=0x00;
  TH1=0x00;
  TF2=0;
  TH2=256/256;
  TL2=256%256;
  TR1=1;//先允许T1定时,因T1的GATE=1,还要等外部INT1高电平才计数
  TR0=1;//先允许T0计数 ,同T1一样,等待INTO高电平     
  TR2=1;//启动T2定时,不用外部控制,直接启动     
  EA=1; //开全局中断 
  CONTRL=1;
  
 }
*******************************/
 //键盘扫描 
 uchar scanf()
 {
  uchar value;
  P0=0xff;
  delayms(1);
  SCANF=0;//打开键扫闸门 
  value=P0;
  delayms(2);
  value=P0;
  SCANF=1;
  return  value;
 }
 /********************************/
 //键处理 
 void keychuli()
 {
   uchar k;
   //关于指示灯,交流是一组,直流是一组,其他状态用液晶显示 
    /***************************************/
   /******************/
   key=scanf();
   /******************/
   //启动键判断 
   if(key1==0&&key7==0&&DAT[4]==0)//启动位 ,油压和转速为0 
 {
for(k=0;k<3;k++)//三次启动循环 
{
     P0=0x04;//准备 输出K6继电器 
     SHUCHU=0;//打开闸门 
 delays(3);//隔三秒响应一次停机键    
//响应停机键     
  key=scanf();
     if(key0==0&&key7==1&&DAT[4]>500)//停机开关状态,油压高,转速达到500,其他继电器都停止工作 ,所以 ,P0=0x08 
   {
    P0=0x18;//准备输出K0,K9继电器 
   SHUCHU=0;//打开输出闸门 
 SHUCHU=1;//关闭闸门 
 outflag=0;//输出标志位 
 }
 if(key1==0&&key7==1&&DAT[4]>430) //每启动一次都判断是否成功,成功直接跳出 
break ; //判断启动成功,立即跳出启动for 循环 
  delays(3);//没有启动成功,继续启动3秒 
  key=scanf();
     if(key1==0&&key0==0&&key7==1&&DAT[4]>500)//停机,油压高,转速达到500,其他继电器都停止工作 ,所以 ,P0=0x08 
   {
    P0=0x18;//准备输出K0,K9继电器 
   SHUCHU=0;//打开输出闸门 
 SHUCHU=1;//关闭闸门 
 outflag=0;//输出标志位 
 }
  if(key1==0&&key7==1&&DAT[4]>430) //每启动一次都判断是否成功,成功直接跳出 
break ;
  delays(3);
  key=scanf();
     if(key0==0&&key7==1&&DAT[4]>500)//停机,油压高,转速达到500,其他继电器都停止工作 ,所以 ,P0=0x08 
   {
    P0=0x18;//准备输出K0,K9继电器 
   SHUCHU=0;//打开输出闸门 
 SHUCHU=1;//关闭闸门 
 outflag=0;//输出标志位 
 }
     if(key1==0&&key7==1&&DAT[4]>430) //每启动一次都判断是否成功,成功直接跳出 
break ;
   
  P0=0x18;//停止 
  SHUCHU=0;
  SHUCHU=1;
  delays(9);
}//for启动循环结束 
     SHUCHU=1;//关闭闸门 
 
   /**********************/
   //启动失败判断 
    if(key7==0) //油压低 
    if(DAT[4]<440)
     {
 P0=0x01;//点亮启动失败灯 
 LED1=0;//开启573输入 
 LED1=1;//关闭使能,74HC573锁定状态 
 outflag=0;//输出标志位清0,表示输出未允许 
     }
 }
   //停机键判断 
  /********************/
   if(key0==0&&key7==1&&DAT[4]>500)//停机,油压高,转速达到500,其他继电器都停止工作 ,所以 ,P0=0x08 
   {
     P0=0x00;//准备交直流断闸(交流,直流 内控制 )   
  SHUCHU=0;
  SHUCHU=1;
  delayms(3);
        P0=0x40;//怠速,准备打开K5继电器,关闭其他输出继电器 
       SHUCHU=0;//打开输出闸门 
     SHUCHU=1;//关闭闸门 
     outflag=0;
  delays(29);
    P0=0x18;//准备 输出K0和K9停油继电器 
   SHUCHU=0;//打开输出闸门 
 SHUCHU=1;//关闭闸门 
 outflag=0;//输出标志位 
 }
 /*****************/
 //应急键判断 
       if(key6==1)//应急/正常,高电位应急 
       {
    eding=1;//应急标志 
       }
     else if(key6==0) //进入怠速 
          {
        eding=0;//怠速标志 
          }
   if(eding==0)//对怠速的处理 
    {
        P0=0x40;//怠速,准备打开K5继电器,关闭其他输出继电器 
       SHUCHU=0;//
     SHUCHU=1;//关闭闸门 
     outflag=0;
       }
  if(eding==1&&outflag==0)//对额定的处理 
    {
 P0=0x00;//额定,准备关闭K5继电器,进入额定,其他继电器都停止工作 ,所以 ,P0=0x00
   SHUCHU=0;//打开输出闸门 
 SHUCHU=1;//关闭闸门 
 delayms(2);
 if(DAT[0]>110&&DAT[1]>110&&DAT[2]>110&&DAT[5]>390)//三相交流大于110 ,频率大于390 
     {
  P0=0xa0;//准备合闸(交流,直流 内控制 )   
  SHUCHU=0;
  SHUCHU=1;
  outflag=1;//合闸后,输出标志位置1
     }
     }
 /******************************/
 //循环键 
 if(key2==1) //处理循环定点显示标志位
 xunhuanflag=1;
 else if(key2==0)
 xunhuanflag=0;
   /*********************/
 //灯光检查键 
   if(key4==0)//灯光检查 
   {
    LED1=1;
 LED2=1;
    P0=0x7f;
    LED1=0;
 delayus(10);
 LED1=1;
 delayms(1000);
 P0=0x7f;
 LED2=0;
 delayus(10);
 LED2=1;
 }
 /************************/
 //复位键 
   if(key5==0)//复位 
   { 
    P0=0x00;
    LED1=0;
 delayus(10);
 LED1=1;
 P0=0x00;
 LED2=0;
 delayus(10);
 LED2=1;
 }
   /****************/
   //自检键 
   if(key3==0) //自检 
   { }
 
 }
 /**********保护函数*****************/
 void baohu()
 {
if(outflag==1)//前提是已经输出 
{
 //立即保护值 
 if((DAT[0]<800||DAT[1]<800||DAT[2]<800) || (DAT[0]>1800||DAT[1]>1800||DAT[2]>1800) || DAT[5]>4450||DAT[5]<3200)//立即断闸保护 
  {
 
  P0=0x00;//准备断闸(交流,直流 内控制 )   
  SHUCHU=0;
  SHUCHU=1;
  outflag=0;//断闸后,输出标志位清0 
  
  if(DAT[0]>1800||DAT[1]>1800||DAT[2]>1800)
  {
  P0=0x80;//过压 
  LED1=0;
  LED1=1; 
  } 
   if(DAT[5]>4450)
  {
  P0=0x80;//过频灯 
  LED2=0;
  LED2=1; 
  }
  if(DAT[0]<800||DAT[1]<800||DAT[2]<800)
  {
  P0=0x40;//欠压 
  LED1=0;
  LED1=1;
  }
  if(DAT[5]<3200)
  {
  P0=0x40;//欠频灯 
  LED2=0;
  LED2=1;
  }
   }//立即保护结束 
  // 延时保护值     
if(DAT[0]<1000||DAT[1]<1000||DAT[2]<1000|| DAT[0]>1270||DAT[1]>1270||DAT[2]>1270|| DAT[5]>4300||DAT[5]<3700)
   {  
 
  if(DAT[0]>1270||DAT[1]>1270||DAT[2]>1270)
  {
  P0=0x80;//过压 
  LED1=0;
  LED1=1; 

  } 
   if(DAT[5]>4300)
  {
  P0=0x80;//过频 
  LED2=0;
  LED2=1; 
  }
  if(DAT[0]<1000||DAT[1]<1000||DAT[2]<1000)
  {
 
  P0=0x40;//欠压 
  LED1=0;
  LED1=1;
  }
  if(DAT[5]<3700)
  {
  
  P0=0x40;//欠频 
  LED2=0;
  LED2=1;
  }
  delays(4);//等待交流恢复 
  voltage();
 if(DAT[0]>1100&&DAT[1]>1100&&DAT[2]>1100&&DAT[5]>3900)//三相交流大于110 ,频率大于390 
     {
  P0=0x00;
  LED1=0;
  LED1=1;
  P0=0x00;
  LED2=0;
  LED2=1;
  P0=0xa0;//准备合闸(交流直流内控制 )   
  SHUCHU=0;
  SHUCHU=1;
  outflag=1;//合闸后,输出标志位置1     
        }
 else 
 {
 
  P0=0x00;//准备断闸(交流,直流 内控制 )   
  SHUCHU=0;
  SHUCHU=1;
  outflag=0;
 }
   }//交流和频率保护结束 
 //直流电压延时保护 
   if(DAT[3]>320||DAT[3]<170)
   {if(DAT[3]>320)
  {
  LCD12864_string(4,1,"直流过压");
  }
  delays(4);//等待直流过压恢复 
  voltage();
 if(DAT[3]>170&&DAT[3]<320)
 {
  LCD12864_string(4,1,"直流正常"); 
 }
 else
 {P0=0x80;//关闭直流只开交流,因为前面已经检测过交流了,这里就不管了,当他正常    
  SHUCHU=0;
  SHUCHU=1;
  outflag=1;
  LCD12864_string(4,1,"直流故障");
 }
   if(DAT[3]<170)
  {
  LCD12864_string(4,1,"直流欠压");
  }
   delays(2);//等待直流 欠压恢复 
   voltage();
 if(DAT[3]>170&&DAT[3]<320)
 {
  LCD12864_string(4,1,"直流正常"); 
 }
 else
 {P0=0x80;//关闭直流只开交流,因为前面已经检测过交流了,这里就不管了,当他正常    
  SHUCHU=0;
  SHUCHU=1;
  outflag=1;
  LCD12864_string(4,1,"直流故障");
 }
   }//直流延时保护结束 
 }//总 保护结束 
 }//总函数结束 
 /*******************************/
 //转速计算  ,频率计算 
void zhuansu()
{
 t1h=TH0;
 t1l=TL0;
 t2h=TH1;
 t2l=TL1;
 cnt1=t1l+(t1h<<8);
 cnt2=t2l+(t2h<<8);
 DAT[6]=cnt1/cnt2*1000000.20*10.00;//计数值 
 DAT[4]=cnt1/cnt2*1000000.200/124.00*600.00*10.0; //计算转速,信号频率就是单片机计数频率的整数倍   ,这里这样写是怕cnt1 cnt2 超出范围 
 //注意这里: cnt1 cnt2  的类型不能是 uint 否则第一步计算除法会得0 , 如果你要先乘1000000.0,也不行。因为超出了uint 范围 
 DAT[5]=DAT[4]*16.00/60.000*10.0;//电压频率计算 
}
/******************************/
//外部中断0,调用转速计算 
void interint0()  interrupt 0 //using **
      //外部中断0处理      
{
 EA=0;
 zhuansu();//调用转速函数 
  FLAG=1;
 /***注意:因为TO T1是外部引脚控制的,所以,这时外部低电平,自动停止。不用软件停止**/  
}     
void intertimer2()  interrupt 5 //using **
      //T2定时中断处理      
{  
  TR2=0;
  CONTRL=0;//关闭闸门信号   
}     
/*******************************/
//AD转换程序 
/************************************************/
//常测数据函数 
void voltage() //电压测量 
{
 uchar i;
 AD=0.00;
 X=0;
for(i=0;i<10;i++)
{
AD+=rd1543(0x08); //读取AD值 
}
//
AD=AD/10.0;
X=AD*46.0001*50.00/1023.00;//转换成电压值 ,分辨率是10位 
DAT[0]=X;
AD=0.00;
//
for(i=0;i<10;i++)
{
AD+=rd1543(0x08); //读取AD值 
}
//
AD=AD/10.0;
X=AD*46.0001*50.00/1023.00;//转换成电压值 ,分辨率是10位 
DAT[1]=X;
//
AD=0.00;
//
for(i=0;i<10;i++)
{
AD+=rd1543(0x08); //读取AD值 
}
//
AD=AD/10.0;
X=AD*46.0001*50.00/1023.00;//转换成电压值 ,分辨率是10位 
DAT[2]=X;
//
/*********
for(i=0;i<20;i++)
{
AD+=rd1543(0x07); //读取AD值 
}
//
AD=AD/20;
X=AD*50.000/1023.000*28.500/4.000;
DAT[3]=X;
//
**********/
}
/***********************************************/

//TLC1543输入模拟电压范围: 0-4.9152 V 
//TLC1543AD 10个时钟方式  方式1 。 LC1543 有四位精度 。  输入 0.0024v 时,AD值为0000000001  
//0.0048时,还为1。  0.0072为 2    也就是0.0048 为一个 宽度  0.0048*AD 就是电压值 . 
uint rd1543(uchar addr)
{
     uint date_out=0;
  uchar k;
    
    // uchar j;
     CLK=0;
     CS=0;
 
          ADDRESS=(bit)(addr&0x08); //用这种愚蠢的方法比用FOR循环快的多 。 
    CLK=1;
    CLK=0;
          addr=addr*2; //用乘法比用左移快 
     
          ADDRESS=(bit)(addr&0x08);
    CLK=1;
    CLK=0;
          addr=addr*2; //用乘法比用左移快 
    ADDRESS=(bit)(addr&0x08);
    CLK=1;
    CLK=0;
          addr=addr*2; //用乘法比用左移快 
    ADDRESS=(bit)(addr&0x08);
    CLK=1;
    CLK=0;
          addr=addr*2; //用乘法比用左移快 
      
  
 // for (j=0;j<6;j++)     //填充6 个CLOCK     
   // {
      CLK=1;CLK=0;   //这里不用循环,省时间 
   CLK=1;CLK=0;
   CLK=1;CLK=0;
   CLK=1;CLK=0;
   CLK=1;CLK=0;
   CLK=1;CLK=0;
      CLK=0;
   // }
      CS=1;
      delayus(8);  //等待AD 转换
      CS=0;                   
  for(k=0;k<10;k++)
     {
    SDATA=1;                 //非P0口作为数据总线使用时,读入数据前要赋值1,特别
       CLK = 1;         //是既用于写有用于读的情况下.
       date_out<<=1;
       if(SDATA) date_out += 1;  //这样写法比下面的方法速度快(5us)
  // date_out=date_out|SDATA;//用时6US 
       CLK = 0;
     }
     return(date_out);
}
2019-05-07 22:10:18 weixin_43444989 阅读数 71
  • 51单片机综合小项目-第2季第4部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第2季第4个课程,也是51单片机学完之后的一个综合小项目,该项目运用了开发板上大多数外设设备,并将之结合起来实现了一个时间、温度显示以及报警功能、时间调整功能等单片机控制常见的功能,有一定代码量,需要一定调试技巧和编程能力来完成,对大家是个很好的总结和锻炼,并且能拓展项目经验。

    3411 人正在学习 去看看 朱有鹏

 实验开发板为CT107D蓝桥官方板,编译环境为MDK5

目录

概述:

1、单片机源代码:

main.c

IIC.c

Keyboaed.c

SMG.c

Snoic.c

Series_port.c

Data_processing.c

config.h

IIC.h

Keyboaed.h

SMG.h

Snoic.h

Series_port.h

Data_processing.h

2、上位机源代码(C):

main.c

Series.c

File.c

File.h

Series.h


概述:

 

1、单片机源代码:

  1. main.c

    #include "config.h"
    #include "SMG.h"
    #include "Snoic.h"
    #include "IIC.h"
    #include "Series_port.h"
    #include "Keyboard.h"
    #include "Data_processing.h"
    
    bit flag400ms = 0;	//400ms标志位
    bit flag_Warnning = 0;//警告标志位
    bit CE_Led1 = 0;		//Led1使能位
    bit CE_Led2 = 0;		//Led2使能位
    bit CE_Led7 = 0;		//Led7使能位
    bit CE_Led8 = 0;		//Led8使能位
    bit CE_SMG = 1;			//数码管使能位
    bit CE_SnoicG = 0;	//距离采集使能位
    bit CE_Back = 0;		//数据回显使能位(显示功能)
    bit CE_Parameter = 0;//参数修改使能位(显示功能)
    /*******************************************************************/
    void main()
    {
    	InitSystem();
    	Timer0Init();
    	InitSnoic();
    	UartInit();
    	while(1)
    	{
    		KeyScan();
    		KeyDrive();
    		Led();
    		if(flag400ms && (!CE_Back) && (!CE_Parameter) )//另外两种显示模式的修改在键盘中
    		{
    			Dis_Get();
    		}
    		flag400ms = 0;
    	}
    }
    /*******************************************************************/
    void InitSystem()
    {
    	P2  = (P2 & 0x1F) | 0x80;
    	P0  = 0xFF;
    	P2 &= 0x1F;
    	P2  = (P2 & 0x1F) | 0xA0;
    	P0  = 0x00;
    	P2 &= 0x1F;
    }
    
    void Timer0Init(void)		//1ms@11.0592MHz
    {
    	AUXR |= 0x80;		//定时器时钟1T模式
    	TMOD &= 0xF0;		//设置定时器模式
    	TMOD |= 0x01;
    	TL0 = 0xCD;		//设置定时初值
    	TH0 = 0xD4;		//设置定时初值
    	TF0 = 0;		//清除TF0标志
    	TR0 = 1;		//定时器0开始计时
    	EA  = 1;
    	ET0 = 1;
    }
    
    void Service_T0() interrupt 1
    {
    	static u16 count = 0;
    	TL0 = 0xCD;		//设置定时初值
    	TH0 = 0xD4;		//设置定时初值
    								//1ms
    	count ++;
    	SMG_Display();
    		
    	if(count >= 400)//400ms
    	{
    		count = 0;
    		flag400ms = 1;
    	}
    }
    	
    void Delay200ms()		//@11.0592MHz
    {
    	unsigned char i, j, k;
    
    	_nop_();
    	_nop_();
    	i = 9;
    	j = 104;
    	k = 139;
    	do
    	{
    		do
    		{
    			while (--k);
    		} while (--j);
    	} while (--i);
    }
    
    
    void Led()
    {
    	static bit flag_S5 = 0, flag_S6 = 0;
    	static u8 count = 3;//Led闪烁计次
    	
    	P2 = (P2 & 0x1F) | 0x80;
    	P0 = 0xFF;
    	if(CE_Led1)
    	{
    		EA = 0;
    		while(count != 0)
    		{
    			 P0 &= 0xFE;
    			 Delay200ms();
    			 P0 |= 0x01;
    			 Delay200ms();
    			 count --;
    		}
    		count = 3;
    		CE_Led1 = 0;
    		CE_SMG = 1;
    		EA = 1;
    	}
    	else if(CE_Led2)
    	{
    		 if(!flag_S5)
    		 {
    			 P0 &=  0xBF;
    			 flag_S5 = 1;
    		 }
    		 else if(flag_S5)
    		 {
    			 P0 |= 0x40;
    			 flag_S5 = 0;
    		 }
    	}
    	else if(CE_Led7)
    	{
    		 if(!flag_S6)
    		 {
    			 P0 &=  0x7F;
    			 flag_S6 = 1;
    		 }
    		 else if(flag_S6)
    		 {
    			 P0 |= 0x80;
    			 flag_S6 = 0;
    		 }
    	}
    	
    	P2 &= 0x1F;
    	
    }
    
    void Service_Warnning()//警告位判断
    {	
    	if(flag_Warnning)//打开警报
    	{
    		P2 = (P2 & 0x1F) | 0xA0;
    		P0 = 0xFF;
    		P2 &= 0x1F;
    	}
    	else //关闭警报
    	{
    		P2 = (P2 & 0x1F) | 0xA0;
    		P0 = 0x00;
    		P2 &= 0x1F;	
    	}	
    }
    
    void Scan_Warnning()//警告位扫描(在会引起电压改变的动作后调用)
    {
    	if( Vol  >= 255)//电压超限情况下
    	{
    		if(flag_Warnning) {
    			Send_UART(0);//告知主机继续采集数据
    		}
    	}
    	else 
    	{
    		if(flag_Warnning) {
    			Send_UART(0);//告知主机采集数据
    			flag_Warnning = 0;//警告位置0
    		}
    	}
    }
  2. IIC.c

    #include "IIC.h"
    
    #define DELAY_TIME 30
    
    #define SlaveAddrW 0xA0
    #define SlaveAddrR 0xA1
    
    u8 para = 0;
    
    void IIC_Delay(unsigned char i)
    {
        do{_nop_();}
        while(i--);        
    }
    //总线启动条件
    void IIC_Start(void)
    {
        SDA = 1;
        SCL = 1;
        IIC_Delay(DELAY_TIME);
        SDA = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 0;	
    }
    
    //总线停止条件
    void IIC_Stop(void)
    {
        SDA = 0;
        SCL = 1;
        IIC_Delay(DELAY_TIME);
        SDA = 1;
        IIC_Delay(DELAY_TIME);
    }
    
    //等待应答
    bit IIC_WaitAck(void)
    {
        bit ackbit;
    	
        SCL  = 1;
        IIC_Delay(DELAY_TIME);
        ackbit = SDA;
        SCL = 0;
        IIC_Delay(DELAY_TIME);
        return ackbit;
    }
    
    //通过I2C总线发送数据
    void IIC_SendByte(unsigned char byt)
    {
        unsigned char i;
    
        for(i=0; i<8; i++)
        {
            SCL  = 0;
            IIC_Delay(DELAY_TIME);
            if(byt & 0x80) SDA  = 1;
            else SDA  = 0;
            IIC_Delay(DELAY_TIME);
            SCL = 1;
            byt <<= 1;
            IIC_Delay(DELAY_TIME);
        }
        SCL  = 0;  
    }
    
    void ConfigDAC(u8 val)
    {
    	
    	IIC_Start();
    	IIC_SendByte(0x90);
    	if(IIC_WaitAck() == 1)
    	{
    		IIC_Stop();
    		return;
    	}
    	
    	IIC_SendByte(0x40);
    	IIC_WaitAck();
    	IIC_SendByte(val);
    	IIC_WaitAck();
    	IIC_Stop();
    }
    
    
    
  3. Keyboaed.c

    #include "Keyboard.h"
    
    u8 Key_Sta[4] = {
     1, 1, 1, 1
    };
    u8 Key_CodeMap[4] = {
     'A', 'B', 'C', 'D'
    };
    
    void KeyScan()//独立按键扫描程序
    {
    	u8 i;
    	
    	static u8 Key_Buff[4] = {
    	0xFF, 0xFF, 0xFF, 0xFF
    	};
    	
    	Key_Buff[0] = (Key_Buff[0] << 1) | S4;
    	Key_Buff[1] = (Key_Buff[1] << 1) | S5;
    	Key_Buff[2] = (Key_Buff[2] << 1) | S6;
    	Key_Buff[3] = (Key_Buff[3] << 1) | S7;
    	
    	for(i = 0; i < 4; i ++)
    	{
    		if( (Key_Buff[i] & 0x0F) == 0x00)//按下产生下降沿
    		{
    				Key_Sta[i] = 0;
    		}
    		if( (Key_Buff[i] & 0x0F) == 0x0F)//弹起
    		{
    				Key_Sta[i] = 1;
    		}
    	}
    }
    
    void KeyAction(u8 cmd)
    {
    	if(cmd == 'A')
    	{
    		if(CE_Led1)_nop_();
    		else 
    		{
    			CE_Led1 = 1;
    			CE_SMG = 0;
    			CE_SnoicG = 1;
    			Dis_Get();
    			SMG_Display();//刷新显示界面
    		}
    		DACOUT();
    		Service_Warnning();
    		while(S4 == 0);
    	}
    	
    	else if(cmd == 'B')
    	{
    		if(!CE_Led7)//未进入测距盲区调节的情况下
    		{	
    			if(CE_Led2)
    			{
    				CE_Led2 = 0;
    				CE_Back = 0;
    			}
    			else 
    			{
    				CE_Led2 = 1;
    				CE_Back = 1;
    				DataBack();
    			}
    		}
    		else
    		{
    			ParameterConfig();
    			DACOUT();
    			Service_Warnning();
    		}
    		while(S5 == 0);
    	}
    	
    	else if(cmd == 'D')
    	{
    		if(CE_Led7)
    		{
    				CE_Led7 = 0;
    				CE_Parameter = 0;
    		}
    		else 
    		{
    				CE_Led7 = 1;
    				CE_Parameter = 1;
    				ParameterShow();
    		}
    		while(S7 == 0);
    	}
    }
    
    void KeyDrive()
    {
    	u8 i;
    	static u8 Key_backup[4] = {
    		1, 1, 1, 1
    	};
    		
    	for(i = 0; i < 4; i ++)
    	{
    		if(Key_Sta[i] != Key_backup[i])
    		{
    			if(Key_backup[i] != 0)
    			{
    				KeyAction(Key_CodeMap[i]);
    			}
    			Key_backup[i] = Key_Sta[i];
    		}
    	}
    }
  4. SMG.c

    #include "SMG.h"
    
    u8 SMG_Buff[8] = {
    	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
    };
    
    u8 code SMG[] = {
    	              0xC0,  //"0"
                    0xF9,  //"1"
                    0xA4,  //"2"
                    0xB0,  //"3"
                    0x99,  //"4"
                    0x92,  //"5"
                    0x82,  //"6"
                    0xF8,  //"7"
                    0x80,  //"8"
                    0x90,  //"9"
                    0x88,  //"A"
                    0x83,  //"B"
                    0xC6,  //"C"
                    0xA1,  //"D"
                    0x86,  //"E"
                    0x8E,  //"F"
                    0x89,  //"H"
                    0xC7,  //"L"
                    0xC8,  //"n"
                    0xC1,  //"u"
                    0x8C,  //"P"
                    0xA3,  //"o"
                    0xBF,  //"-"
                    0xFF,  //熄灭
    								0xFF  //自定义
    };
    
    void SMG_Display()
    {
    	static u8 index = 0 , j = 0;
    	
    	if(CE_SMG)//此时数码管上的值不会随缓冲区段码的改变而改变
    	{	
    		P2 = (P2&0x1F) | 0xE0;
    		P0 = 0xFF;
    		P2 = P2&0x1F;
    		_nop_();
    		P2 = (P2&0x1F) | 0xC0;
    		P0 = 0x01<<index;	
    		P2 = P2&0x1F;
    		_nop_();
    		P2 = (P2&0x1F) | 0xE0;
    		P0 = SMG_Buff[index];
    		P2 = P2&0x1F;
    		_nop_();
    		index++;
    
    		index &= 0x07; 
    	}
    	else
    	{
    		Refresh();
    		for(j = 0; j < 7; j ++)
    		{
    			P2 = (P2&0x1F) | 0xE0;
    			P0 = 0xFF;
    			P2 = P2&0x1F;
    			_nop_();
    			P2 = (P2&0x1F) | 0xC0;
    			P0 = 0x01<<j;	
    			P2 = P2&0x1F;
    			_nop_();
    			P2 = (P2&0x1F) | 0xE0;
    			P0 = SMG_Buff[j];
    			P2 = P2&0x1F;
    			_nop_();
    		}
    	}
    }
    
    void Refresh()
    {
    	u8 index = 0;
    	for(index = 0; index < 8; index ++) SMG_Buff[index] = 0xFF;
    }
    
    
  5. Snoic.c

    #include "Snoic.h"
    
    u16 Dis_backup = 0;
    u16 Dis = 0;
    
    void Delay13us()		//@11.0592MHz
    {
    	unsigned char i;
    
    	_nop_();
    	_nop_();
    	i = 33;
    	while (--i);
    }
    
    void InitSnoic()
    {
    	AUXR &= 0xBF;		//定时器时钟12T模式
    	TMOD &= 0x0F;
    	TMOD |= 0x10;
    	TF1 = 0;
    	TR1 = 0;
    }
    
    void SendWave()
    {
    	u8 i = 8;
    	
    	while(i --)
    	{
    		Snoic_Txd = 1;
    		Delay13us();
    		Snoic_Txd = 0;
    		Delay13us();
    	}
    }
    	
    void Dis_Get()
    {
    	u16 time;
    	EA = 0;
    	SendWave();
    	EA  = 1;
    	TH1 = 0;
    	TL1 = 0;
    	TR1 = 1;
    	while( (Snoic_Rxd)&&(TF1 == 0) );
    	TR1 = 0;
    	
    	if(TF1 == 1)//最大超出测定距离
    	{
    		TF1 = 0;
    		SMG_Buff[0] = 0xC6;
    		SMG_Buff[1] = SMG[(Dis_backup / 100) % 10];//上一次测距值
    		SMG_Buff[2] = (SMG[(Dis_backup / 10) % 10] & 0x7F);
    		SMG_Buff[3] = SMG[Dis_backup % 10];
    		SMG_Buff[4] = 0xBF;
    		SMG_Buff[5] = 0xBF;
    		SMG_Buff[6] = 0xBF;
    		SMG_Buff[7] = 0xBF;
    	}
    	else
    	{	
    		time = (TL1 + (u16)TH1 * 256);
    		Dis = (u16)((time * 0.17 * 12) / 11.0592);//单位为毫米
    		SMG_Buff[0] = 0xC6;
    		
    		SMG_Buff[1] = SMG[(Dis_backup / 100) % 10];//上一次测距值
    		SMG_Buff[2] = (SMG[(Dis_backup / 10) % 10] & 0x7F);
    		SMG_Buff[3] = SMG[Dis_backup % 10];
    		
    		SMG_Buff[4] = 0xBF;
    		
    		SMG_Buff[5] = SMG[(Dis / 100) % 10];//本次测距值
    		SMG_Buff[6] = (SMG[(Dis / 10) % 10] & 0x7F);
    		SMG_Buff[7] = SMG[Dis % 10];
    		if(CE_SnoicG)//数据采集功能
    		{
    			Dis_backup = Dis;
    			CE_SnoicG = 0;
    		}
    	}
    }
  6. Series_port.c

    #include "Series_port.h"
    
    void UartInit(void)		//9600bps@11.0592MHz
    {
    	SCON = 0x50;		//8位数据,可变波特率
    	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
    	AUXR &= 0xFB;		//定时器2时钟为Fosc/12,即12T
    	T2L = 0xE8;			//设定定时初值
    	T2H = 0xFF;			//设定定时初值
    	AUXR |= 0x10;		//启动定时器2
    	ES = 1;
    	EA = 1;
    	PS = 1;
    }
    
    void Send_UART(u8 dat)
    {
    	SBUF = dat;
    	while(TI == 0);
    	TI = 0;
    }
    
    void Recive_UART() interrupt 4
    {
    	u8 dat;
    	
    	T2L = 0xE8;			//设定定时初值
    	T2H = 0xFF;			//设定定时初值
    	while(RI == 1)
    	{
    		RI = 0;
    		dat = SBUF;
    	}
    	CMD_Deal(dat);
    }
  7. Data_processing.c

    #include "Data_processing.h"
    
    u16 Vol = 0; //电压参数
    u8 Dis_H = 0;//距离高位
    u8 Dis_L = 0;//距离低位
    
    void DataBack()
    {
    	SMG_Buff[0] = 0x89;//H
    	
    	SMG_Buff[1] = 0xFF;
    	SMG_Buff[2] = 0xFF;
    	SMG_Buff[3] = 0xFF;
    	SMG_Buff[4] = 0xFF;
    	SMG_Buff[5] = SMG[(Dis_backup / 100) % 10];//上一次测距值
    	SMG_Buff[6] = (SMG[(Dis_backup / 10) % 10] & 0x7F);
    	SMG_Buff[7] = SMG[Dis_backup % 10];
    }
     
    void ParameterConfig()	
    {
    	para = para + 10;
    	if(para > 30) para = 0;
    	
    	SMG_Buff[0] = 0x8E;
    	SMG_Buff[1] = 0xFF;
    	SMG_Buff[2] = 0xFF;
    	SMG_Buff[3] = 0xFF;
    	SMG_Buff[4] = 0xFF;
    	SMG_Buff[5] = 0xFF;
    	
    	SMG_Buff[6] = (SMG[(para / 10) % 10]);
    	SMG_Buff[7] = SMG[para % 10];
    }
    
    void ParameterShow()
    {
    	SMG_Buff[0] = 0x8E;
    	SMG_Buff[1] = 0xFF;
    	SMG_Buff[2] = 0xFF;
    	SMG_Buff[3] = 0xFF;
    	SMG_Buff[4] = 0xFF;
    	SMG_Buff[5] = 0xFF;
    	
    	SMG_Buff[6] = (SMG[(para / 10) % 10]);
    	SMG_Buff[7] = SMG[para % 10];
    }	
    
    void DACOUT()//电压计算并输出
    {
    	u16 obj;
    	u16 exp = 0;
    	obj = para * 10;//单位为毫米
    	exp = (u16)((((float)(Dis_backup - obj) * 0.2) * 255)/ 50);
    	
    	if(Dis_backup <= obj) Vol = 0;
    	else if( exp < 255 )
    		Vol = exp;
    	else if( exp >= 255 )
    		Vol = 255;
    
    	ConfigDAC((u8)Vol);
    	Scan_Warnning();
    }
    
    void CMD_Deal(u8 dat)
    {
    	if(dat == 'A') 
    	{
    		flag_Warnning = 1;
    		Service_Warnning();
    	}
    	if(dat == '1') 
    	{
    		Dis_L = (u8)Dis_backup;//舍高保底
    		Dis_H = (u8)(Dis_backup >> 8);
    		Send_UART(Dis_H);		//距离
    		Send_UART(Dis_L);
     		Send_UART(Vol);	//电压
    		Send_UART(para);//测距盲区
    	}
    }
  8. config.h

    #ifndef CONFIG_H_
    #define  CONFIG_H_
    
    #include "STC15F2K60S2.h"
    #include "intrins.h"
    
    typedef unsigned char u8;
    typedef unsigned int  u16;
    typedef unsigned long u32;
    
    sbit Snoic_Txd = P1^0;
    sbit Snoic_Rxd = P1^1;
    
    sbit S7 = P3^0;
    sbit S6 = P3^1;
    sbit S5 = P3^2;
    sbit S4 = P3^3;
    
    extern bit flag400ms;
    extern bit CE_Led1;
    extern bit CE_Led2;
    extern bit CE_Led7;
    extern bit CE_Led8;
    extern bit CE_SMG;
    extern bit CE_SnoicG;
    extern bit CE_Back;
    extern bit CE_Parameter;
    extern bit flag_Warnning;
    
    void InitSystem();
    void Timer0Init(void);
    void Delay200ms();
    void Led();
    extern void Service_Warnning();
    extern void Scan_Warnning();
    
    #endif
  9. IIC.h

    #ifndef _IIC_H
    #define _IIC_H
    
    #include "config.h"
    #include "config.h"
    #include "SMG.h"
    
    sbit SDA = P2^1;  /* 数据线 */
    sbit SCL = P2^0;  /* 时钟线 */
    
    extern u8 para;
    
    void IIC_Start(void); 
    void IIC_Stop(void);  
    bit IIC_WaitAck(void);  
    void IIC_SendAck(bit ackbit); 
    void IIC_SendByte(unsigned char byt); 
    unsigned char IIC_RecByte(void);
    
    extern void ConfigDAC(u8 val);
    
    #endif
  10. Keyboaed.h

    #ifndef _KEYBOARD_H
    #define _KEYBOARD_H
    
    #include "config.h"
    #include "SMG.h"
    #include "IIC.h"
    #include "Snoic.h"
    #include "Series_port.h"
    #include "Data_processing.h"
    
    extern void KeyScan();
    extern void KeyAction(u8 cmd);
    extern void KeyDrive();
    
    
    #endif
  11. SMG.h

    #ifndef _SMG_H
    #define _SMG_H
    
    #include "config.h"
    
    extern u8 SMG_Buff[8];
    extern u8 code SMG[];
    
    extern void Refresh();
    extern void SMG_Display();
    
    #endif
  12. Snoic.h

    #ifndef _SNOIC_H
    #define _SNOIC_H
    
    #include "config.h"
    #include "SMG.h"
    #include "Data_processing.h"
    
    extern u16 Dis_backup;
    extern u16 Dis;
    
    extern void Delay13us();
    extern void InitSnoic();
    extern void SendWave();
    extern void Dis_Get();
    
    #endif
  13. Series_port.h

    #ifndef _SERIES_PORT_H
    #define _SERIES_PORT_H
    
    #include "config.h"
    #include "IIC.h"
    #include "Snoic.h"
    #include "Data_processing.h"
    
    extern void UartInit();
    extern void Send_UART(u8 dat);
    extern void SendString(u8 *str);
    extern void Recive_UART();
    
    
    #endif
  14. Data_processing.h

    #ifndef _DATA_PROCESSING_H
    #define _DATA_PROCESSING_H
    
    #include "config.h"
    #include "Snoic.h"
    #include "SMG.h"
    #include "IIC.h"
    #include "Series_port.h"
    
    extern u16 Vol;
    
    extern void DataBack();					//数据回显
    extern void ParameterConfig();	//参数修改
    extern void ParameterShow();		//参数显示
    extern void DACOUT();
    extern void CMD_Deal(u8 dat);
    
    #endif

2、上位机源代码(C):

  1. main.c

    #include "Series.h"
    #include "File.h"
    
    FILE *fp_Dis, *fp_Vol;
    int flag_CW = 0;//警报解除输出次数标志位
    
    void Init()
    {
        printf("*********************************\n");//串口发送
        printf("*1、接收距离、电压、测距盲区数据*\n");
        printf("*2、输出已接收的距离信息        *\n");
        printf("*3、输出已接收的电压信息        *\n");
        printf("*4、清空文件                    *\n");
        printf("*0、清屏                        *\n");
        printf("*********************************\n");
        printf("请输入指令\n");
        flag_CW = 1;
    }
    
    void InitFile()
    {
        fp_Dis = fopen("Distance.txt","w");
        fp_Vol = fopen("Voltage.txt","w");
        fclose(fp_Dis);
        fclose(fp_Vol);//文件初始化
    }
    
    int main(void)
    {
        char cmd;
        InitUART();
    
        InitFile();
    
        while(1)
        {
            Init();
            cmd = getchar();
            getchar();
            switch(cmd)
            {
                case '1':
                    UART_Write(cmd);
                    UART_Read_Data();
                    break;
                case '2':
                    printf("文件中的距离数据:\n");
                    File_Read('D');
                    break;
                case '3':
                    printf("文件中的电压数据:\n");
                    File_Read('V');
                    break;
                case '4':
                    InitFile();
                    printf("文件已清空!\n\n");
                    break;
                case '0':
                    system("cls");
                    break;
                default:
                    printf("*请输入正确指令!\n\n");
                    break;
            }
        }
        return 0;
    }
    
  2. Series.c

    #include "Series.h"
    
    float Dis = 0, Vol = 0,para = 0;
    
    HANDLE hCom;
    
    int InitUART(void)
    {
        char str[4];
        printf("输入端口\n");
        gets(str);
    	hCom = CreateFile(TEXT(str),
    		GENERIC_READ|GENERIC_WRITE, //允许读写
    		0, //指定共享属性,由于串口不能共享,所以该参数必须为0
    		NULL,
    		OPEN_EXISTING, //打开而不是创建
    
    		0, //属性描述,该值为FILE_FLAG_OVERLAPPED,表示使用异步I/O,该参数为0,表示同步I/O操作
    		NULL);
    
    	if (hCom == INVALID_HANDLE_VALUE)
    	{
    		printf("打开COM失败!\n");
    		return FALSE;
    	}
    	else
    	{
    		printf("COM打开成功!\n");
    	}
    
    	SetupComm(hCom, 1024, 1024); //输入缓冲区和输出缓冲区的大小都是1024字节
    
    	/*********************************超时设置**************************************/
    	COMMTIMEOUTS TimeOuts;
    	//设定读超时
    	TimeOuts.ReadIntervalTimeout = MAXBYTE;//读间隔超时(**注意这里的间隔为MAXBYTE)
    	TimeOuts.ReadTotalTimeoutMultiplier = 0;//读时间系数
    	TimeOuts.ReadTotalTimeoutConstant = 0;//读时间常量
    	//设定写超    int Dis, Vol, 时int Dis, Vol,
    	TimeOuts.WriteTotalTimeoutMultiplier = 1;//写时间系数
    	TimeOuts.WriteTotalTimeoutConstant = 1;//写时间常量
    	SetCommTimeouts(hCom, &TimeOuts); //设置超时数据写入
    
    	/*****************************************配置串口***************************/
    	DCB dcb;
    	GetCommState(hCom, &dcb);
    	dcb.BaudRate = 9600; //波特率为9600
    	dcb.ByteSize = 8; //每个字节有8位
    	dcb.Parity = NOPARITY; //无奇偶校验位
    	dcb.StopBits = ONESTOPBIT; //一个停止位
    	SetCommState(hCom, &dcb);//配置数据写入
    
        return 1;
    }
    
    void UART_Read_Data()//读取电压、距离、测距盲区
    {
        BOOL bReadStat;//读取成功判断标志位
        DWORD wCount;//实际读取的字节数
        unsigned char dat[4];
    
    
        PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR); //清空缓冲区
        bReadStat = ReadFile(hCom, dat, 4*sizeof(unsigned char), &wCount, NULL);//读取串口成功返回1
    
        if(!bReadStat)
        {
            printf("读取数据失败!\n");
            return;
        }
        else
        {
            Dis  = ((float)(dat[0] * 255 + dat[1]) / 10);
            Vol  = ((float)dat[2] / 50) ;
            para = (float)(dat[3]);
    
            printf("当前采集距离为%.2fcm\n当前输出电压为%.2fV\n当前测距盲区为%.2fcm\n\n", Dis, Vol, para);
        }
        File_Write();       //存入文件(因为有类似与递归的函数用法需要在这存)
        if( Vol >= 5 )
        {
            UART_Write('A');
            printf("*电压超限!\n");
            UART_Read_CMD();//如果电压值一直超限会一直循环不执行下一步
            if((flag_CW --) == 1) printf("*警报已解除\n\n");
        }
    }
    
    void UART_Read_CMD()//下发警告指令时调用(返回1解除0未解除)
    {
        BOOL bReadStat;//读取成功判断标志位
        DWORD wCount;//实际读取的字节数
        unsigned char dat = 'N';
    
    
        PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR); //清空缓冲区
        bReadStat = ReadFile(hCom, &dat, sizeof(unsigned char), &wCount, NULL);//读取串口成功返回1
    
        if(!bReadStat)
        {
            printf("读取数据失败!\n");
            return ;
        }
        else
        {
            if(dat == 0)//串口返回数据0再次采集数据
            {
                UART_Write('1');    //再次下发接收数据指令
                UART_Read_Data();   //接收数据
            }
        }
        return ;
    }
    
    void UART_Write(unsigned char cmd)
    {
        BOOL bWriteStat = 0;//写入成功判断标志位
        DWORD wCount = 0;//实际写入的字节数
    
        PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR); //清空缓冲区
    
        switch(cmd)
        {
            case '1':
                bWriteStat = WriteFile(hCom,&cmd,sizeof(cmd),&wCount,NULL);
                break;
            case 'A':
                bWriteStat = WriteFile(hCom,&cmd,sizeof(cmd),&wCount,NULL);
                break;
        }
        if(!bWriteStat)
        {
            printf("数据写入失败!\n");
            return;
        }
    }
    
  3. File.c

    #include "File.h"
    
    void File_Write()
    {
        static int index = 1;//文件内存储数据的索引标志
    
        fp_Dis = fopen("Distance.txt","a");
        fp_Vol = fopen("Voltage.txt","a");
        fprintf(fp_Dis,"%d %f\n", index, Dis);
        fprintf(fp_Vol,"%d %f\n", index, Vol);
        index ++;
    
        fclose(fp_Dis);
        fclose(fp_Vol);
    }
    
    void File_Read(unsigned char cmd)
    {
        float Dis_bp[1001] ,Vol_bp[1001];
        int i = 0, index = 0, n;
    
        fp_Dis = fopen("Distance.txt","r+");
        fp_Vol = fopen("Voltage.txt","r+");
    
        rewind(fp_Dis);//文件指针指向文件首
        rewind(fp_Vol);
    
        if(cmd == 'D')
        {
            while(!feof(fp_Dis))
                fscanf(fp_Dis,"%d %f\n", &index, &Dis_bp[i ++]);
        }
        else if(cmd == 'V')
        {
            while(!feof(fp_Vol))
                fscanf(fp_Vol,"%d %f\n", &index, &Vol_bp[i ++]);
        }
       n = index;
       for(i = 0 ; i < n; i ++)
        {
            if(cmd == 'D')
                printf("%d %.2f\n",i + 1, Dis_bp[i]);
            else if(cmd == 'V')
                printf("%d %.2f\n",i + 1, Vol_bp[i]);
        }
        printf("\n");
    }
    
  4. File.h

    #ifndef FILE_H_
    #define FILE_H_
    
    #include "Series.h"
    
    extern FILE *fp_Dis, *fp_Vol;
    
    extern void File_Write();
    extern void File_Read(unsigned char cmd);
    
    #endif
    
  5. Series.h

    #ifndef SERIES_H_
    #define SERIES_H_
    
    #include <stdio.h>
    #include <windows.h>
    #include "File.h"
    
    extern float Dis, Vol;
    extern int flag_CW;
    
    extern int InitUART();
    extern void UART_Read_Data();
    extern void UART_Read_CMD();
    extern void UART_Write(unsigned char cmd);
    
    #endif
    
2004-11-03 09:24:00 80x88 阅读数 5004
  • 51单片机综合小项目-第2季第4部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第2季第4个课程,也是51单片机学完之后的一个综合小项目,该项目运用了开发板上大多数外设设备,并将之结合起来实现了一个时间、温度显示以及报警功能、时间调整功能等单片机控制常见的功能,有一定代码量,需要一定调试技巧和编程能力来完成,对大家是个很好的总结和锻炼,并且能拓展项目经验。

    3411 人正在学习 去看看 朱有鹏
ICL7135的串行采集方式在单片机电压表中的应用
文章作者:严仍友 汪仁煌
文章类型:设计应用 文章加入时间:2003年10月22日1:3
文章出处:国外电子元器件


    摘要:介绍了对A/D芯片ICL7135进行串行数据采集的具体方法,同时利用该方式结构简单、编程简洁、占用单片机资源少的特点,给出了用ICL7135与AT89C52单片机构成电压表系统的硬件和软件设计方法。

    关键词:单片机 ADC 电压表 ICL7135

在常用的A/D转换芯片(如ADC0809、ICL7135、ICL7109等)中,ICL7135与其余几种有所不同,它是一种四位半的双积分A/D转换器,具有精度高(精度相当于14位二进制数)、价格低廉、抗干扰能力强等优点。通常情况下,设计者都是用单片机来并行采集ICL7135的数据,本文介绍用单片机串行方式采集ICL7135的数据以实现单片机电压表和小型智能仪表的设计方案。

1 ICL7135的串行工作方式

1.1 ICL7135的测量周期

ICL7135的测量周期包括下列四相(节拍):

(1)AUTO-ZERO(自动调零)相

    在该相时,内部IN+和IN-输入与引脚断开,且在内部连接到ANLG-COMMON,基准电容被充电至基准电压,系统接成闭环并为自动调零(AUTOZERO)电容充电以补偿缓冲放大器、积分器和比较器的失调电压。此时,自动调零精度令受系统噪声的限制,以输入为基准的总失调小于10μV。

(2)SINGAL-INTEGRATE(信号积分)相

在该相,自动调零环路被打开,内部的IN+和IN-输入被连接至外部引脚。在固定的时间周期内,这些输入端之间的差分电压被积分。当输入信号相对于转换器电源不反相(NO-RETURN)时,IN-可直接连接至ANJG-COMMON以便输出正确的共模电压。同时,在这一相完成的基础上,输入信号的极性将被系统所记录。

(3)DEINTEGRATE(去积分)相

该相的基准用于完成去积分(DEINTEGRATE)任务,此时内部IN-在内部连接ANLG-COMMON,IN+跨接至先前已充电的基准电容,所记录的输入信号的极性可确保以正确的极性连接至电容以使积分器输出极性回零。输出返回至零所需的时间正比于输入信号的幅度。返回时间显示为数字读数,并由1000(Vid/Vref)确定。满度或最大转换值发生在Vid等于Vref的两倍时。

    (4)ZERO-INTEGRATE(积分器返回零)相

内部的IN-连接到ANLG-COMMON,系统接成闭环以使积分器输出返回到零。通常这相需要100~200个时钟脉冲,但是在超范围(OVERRANGE)转换后,则需要6200个脉冲。

1.2 ICL7135时序图

图1所示是Vid为常数时的ICL7135时序图,由图1可知:在Signal-Integrate(即信号积分)相开始时,ICL7135的BUSY信号线跳高并一直保持高电平,直到De integrate(去积分)相结束时才跳回低电平。在满量程情况下,这个区域中的最多脉冲个数为30002个。其中De integrate(去积分)相的脉冲个数反映了转换结果。

图2是不同Vid值时的ICL7135时序。由图2可见:对于不同模拟量输入,ICL7135的BUSY信号的高电平宽度也不同。

2 与单片机系统的串行连接

在ICL7135与单片机系统进行连接时,如果使用ICL7135的并行采集方式,则不但要连接BCD码数据输出线,又要连接BCD码数据的位驱动信号输出端,这样至少需要9根I/O口线。因此,系统的连接比较麻烦,且编程也非常复杂。

而ICL7135的串行接法是通过计脉冲数的方法来获得测量转换结果的。由其时序分析可知,在Deintegrate(去积分)相,其脉冲数与转换结果具有一一对应关系。

实际上,可以通过单片机(例如ATMEL公司的51系列单片机AT89C52)的定时器T0(也可以使用定时器T1)来计脉冲器。由于,定时器T0所用的CLK频率是系统晶振频率的1/12。因此可利用单片机(AT89C52)的ALE信号作为ICL7135的脉冲(CLK)输入。但要注意,在软件设计编程中,若指令中不出现MOVX指令,ALE端产生的脉冲频率将是晶振的1/6。至此,便可找到定时器所使用的频率与单片机系统晶振频率的关系,以及ICL7135所需的频率输入与单片机系统晶振频率的关系。

为了使定时器T0的计数脉冲的ICL7135工作所需的脉冲同步,可以将ICL7135的BUSY信号接至AT89C52的P3.2(INT0)引脚上,并且将定时器T0的选通控制信号GATE倍1。此时定时器T0是否工作将受BUSY信号的控制。由上述时序图可知,当ICL7135开始工作时,即在积分波形的Signal-Integrate相开始时,也就是ICL7135的BUSY信号跳高时,定时器T0才开始工作,且定时器T0的TH0、TL0所记录的数据与ICL7135的测试脉冲(从积分波形的Signal-Integrate相开始时Deintegrate相结束这一区域内的脉冲称为测量脉冲)存在一定的比例关系。其系统连接图如图3所示。

在这种情况下,由于定时器T0和ICL7135所用的时钟不是同一路。因此,应当找到定时器T0所记录的数据和测量脉冲之间的某种比例关系。其比例关系如下:

Ftime=Fosc/12

Fale=Fosc/6

Freal=Fosc/24

Ficl=Fale/N

其中,Fosc为系统晶振频率;Ftime为定时器所用频率;Fale为单片机ALE输出的频率;Freal为ICL7135的测量脉冲频率;Ficl为ICL7135所用的输入频率,该频率可通过Dale分频得到。N为分频比,该系统中N应选为4。

图4 ICL7135A/D转换器与系统的连接图

    由上述频率之间的比率关系可知,AT98C52的定时器T0所用的频率是ICL7135的测量脉冲频率的两倍。因此,定时器T0所记录的脉冲数也是ICL7135的测量脉冲的两倍。图中,分频数可根据ICL7135的要求和单片机的时钟频率来选择。在这里,提倡使用四分频,这样可使定时器T0在对测量脉冲计数时不会溢出。若使用4以上的分频数,则需在软件上作一下改进。

要得到测量脉冲的个数,只需将定时器所记录的脉冲个数除以2即可。而要得到A/D转换结果所对应的脉冲数则应用测量脉冲的个数减去10001。这些转换通常可通过软件完成,因此非常简单。通过A/D转换结果所对应的脉冲数可得到被测的模拟量。通过对串行方式的讨论可以看出:使用这种方法可以不再使用8255芯片来扩展口线。其优点是占用口线少,能节省系统的硬件资源,提高系统的抗干扰能力,不用添加任何扩展口线器件,从而使系统的成本得到降低。

3 基于单片机系统的电压表设计

3.1 系统的硬件

图4所示是单片机电压表系统中ICL7135与单片机系统的典型连接示意图。图中,单片机系统的晶振为6MHz,单片机的ALE信号频率为1MHz;考虑到系统连接方面和单片机ALE信号频率范围等因素,笔者取ICL7135的输入频率为ALE信号的四分频,即选用125kHz。这样选用的好处是T0定时器在对测量脉冲计数时不会产生溢出。

3.2 系统的软件设计

ICL7135A/D与单片机连接电路的软件设计系统的程序流程图如图5所示。

    该软件流程图由三部分组成。其中转换子程序是在主程序中调用的,目的是为了不占用很长的中断时间。T0计数器设定为方式1、定时状态、选通控制设为“1”。故TMOD控制字设置为“05H”。由于T0计数器用的是系统的晶振频率,因此与设定为计数状态效果一样。

4 结束语

ICL7135的串行方式在实践中的应用效果很好。与并行方式相比,其突出的优点是结构简单、程序简洁、占用单片机的资源少、可提高抗干扰能力,同时可提高仪器的检测可靠性,并且可在不添加任何扩展口线器件的情况下使系统的成本得到降低。

2019-04-10 21:39:44 weixin_44010022 阅读数 586
  • 51单片机综合小项目-第2季第4部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第2季第4个课程,也是51单片机学完之后的一个综合小项目,该项目运用了开发板上大多数外设设备,并将之结合起来实现了一个时间、温度显示以及报警功能、时间调整功能等单片机控制常见的功能,有一定代码量,需要一定调试技巧和编程能力来完成,对大家是个很好的总结和锻炼,并且能拓展项目经验。

    3411 人正在学习 去看看 朱有鹏

单片机ADC功能电压测量

使用STC12C5A60S2测量引脚电压

官网给出的代码运行后可以在串口工具中看到电压的输出,由于需要把单片机与电脑连接,电脑则会直接给单片机供电,所以电压值不会改变。所以需要单独一块电池或使用可编程电源给单片机供电,然后连接一块屏幕用来显示。这样就能看到测量出的电压,再通过官网给出的公式来计算电压。

STC官网中贴出的电压测试代码:

 /*------------------------------------------------------------------*/
    /* --- STC MCU International Limited -------------------------------*/
    /* --- STC 1T Series MCU A/D Conversion Demo -----------------------*/
    /* --- Mobile: (86)13922805190 -------------------------------------*/
    /* --- Fax: 86-755-82944243 ----------------------------------------*/
    /* --- Tel: 86-755-82948412 ----------------------------------------*/
    /* --- Web: www.STCMCU.com -----------------------------------------*/
    /* If you want to use the program or the program referenced in the  */
    /* article, please specify in which data and procedures from STC    */
    /*------------------------------------------------------------------*/
    
    #include "reg51.h"
    #include "intrins.h"
    
    #define FOSC    11059200L
    #define BAUD    9600
    
    typedef unsigned char BYTE;
    typedef unsigned int WORD;
    
    /*Declare SFR associated with the ADC */
    sfr ADC_CONTR   =   0xBC;           //ADC control register
    sfr ADC_RES     =   0xBD;           //ADC high 8-bit result register
    sfr ADC_LOW2    =   0xBE;           //ADC low 2-bit result register
    sfr P1ASF       =   0x9D;           //P1 secondary function control register
    
    /*Define ADC operation const for ADC_CONTR*/
    #define ADC_POWER   0x80            //ADC power control bit
    #define ADC_FLAG    0x10            //ADC complete flag
    #define ADC_START   0x08            //ADC start control bit
    #define ADC_SPEEDLL 0x00            //420 clocks
    #define ADC_SPEEDL  0x20            //280 clocks
    #define ADC_SPEEDH  0x40            //140 clocks
    #define ADC_SPEEDHH 0x60            //70 clocks
    
    void InitUart();
    void InitADC();
    void SendData(BYTE dat);
    BYTE GetADCResult(BYTE ch);
    void Delay(WORD n);
    void ShowResult(BYTE ch);
    void main()
    {
        InitUart();                     //Init UART, use to show ADC result
        InitADC();                      //Init ADC sfr
        while (1)
        {
            ShowResult(0);              //Show Channel0
    			  Delay(5);
    //        ShowResult(1);              //Show Channel1
    //        ShowResult(2);              //Show Channel2
    //        ShowResult(3);              //Show Channel3
    //        ShowResult(4);              //Show Channel4
    //        ShowResult(5);              //Show Channel5
    //        ShowResult(6);              //Show Channel6
    //        ShowResult(7);              //Show Channel7
        }
    }
    
    /*----------------------------
    Send ADC result to UART
    ----------------------------*/
    void ShowResult(BYTE ch)
    {
        SendData(ch);   	//Show Channel NO.
        SendData(GetADCResult(ch));     //Show ADC high 8-bit result
    //if you want show 10-bit result, uncomment next line
        //SendData(ADC_LOW2);             //Show ADC low 2-bit result
    }
    
    /*----------------------------
    Get ADC result
    ----------------------------*/
    BYTE GetADCResult(BYTE ch)
    {
        ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
        _nop_();                        //Must wait before inquiry
        _nop_();
        _nop_();
        _nop_();
        while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag
        ADC_CONTR &= ~ADC_FLAG;         //Close ADC
    
        return ADC_RES;                 //Return ADC result
    }
    
    /*----------------------------
    Initial UART
    ----------------------------*/
    void InitUart()
    {
        SCON = 0x5a;                    //8 bit data ,no parity bit
        TMOD = 0x20;                    //T1 as 8-bit auto reload
        TH1 = TL1 = -(FOSC/12/32/BAUD); //Set Uart baudrate
        TR1 = 1;                        //T1 start running
    }
    
    /*----------------------------
    Initial ADC sfr
    ----------------------------*/
    void InitADC()
    {
        P1ASF = 0x01;                   //Open 8 channels ADC function
        ADC_RES = 0;                    //Clear previous result
        ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
        Delay(2);                       //ADC power-on and delay
    }
    
    /*----------------------------
    Send one byte data to PC
    Input: dat (UART data)
    Output:-
    ----------------------------*/
    void SendData(BYTE dat)
    {
        while (!TI);                    //Wait for the previous data is sent
        TI = 0;                         //Clear TI flag 
        SBUF = dat;                     //Send current data
    }
    
    /*----------------------------
    Software delay function
    ----------------------------*/
    void Delay(WORD n)
    {
        WORD x;
    
        while (n--)
        {
            x = 5000;
            while (x--);
        }
    }

1.先将单片机与屏幕电池正确连接,测试屏幕,使用屏幕测试代码

2.屏幕为JLX12864G-542-BN(删减掉测试图片,保留一种ASCII字库显示数据)

3.把屏幕显示与电压测量代码糅合在一起,把电压显示到屏幕上

4.记录电压值,使用官方文档中的电压计算公式计算
官网文档公式
5.用万用表测量ADC引脚电压,计算值做对比,验证测试准确性

#include <STC12C5A60S2.H>
#include "intrins.h"

#define uchar unsigned char

#define uint unsigned int

#define ulong unsigned long 
	

#define FOSC    11059200L
#define BAUD    9600


typedef unsigned char BYTE;
typedef unsigned int WORD;

uchar o,p,q,*m,*e,*f;

//sfr ADC_CONTR   =   0xBC;           //ADC control register
//sfr ADC_RES     =   0xBD;           //ADC high 8-bit result register
sfr ADC_LOW2    =   0xBE;           //ADC low 2-bit result register
//sfr P1ASF       =   0x9D;           //P1 secondary function control register

/*Define ADC operation const for ADC_CONTR*/
#define ADC_POWER   0x80            //ADC power control bit
#define ADC_FLAG    0x10            //ADC complete flag
#define ADC_START   0x08            //ADC start control bit
#define ADC_SPEEDLL 0x00            //420 clocks
#define ADC_SPEEDL  0x20            //280 clocks
#define ADC_SPEEDH  0x40            //140 clocks
#define ADC_SPEEDHH 0x60            //70 clocks

void InitUart();
void InitADC();
void SendData(BYTE dat);
BYTE GetADCResult(BYTE ch);
void Delay(WORD n);
void ShowResult(BYTE ch);

sbit lcd_cs1	=P3^6;	//????,CS:??	
sbit lcd_reset	=P3^7;	//????,RESET:??	
sbit lcd_rs	=P3^4;	//????,RS:??/??????????"A0",?揅D?
sbit lcd_e	=P3^3;	//????,E:??????	
sbit lcd_rw	=P3^2;	//????,R/W:?/?	
sbit key	=P2^0;	//????,P2.0 ?? GND ???????	
//?? P1.0~1.7 ?? DB0~DB7		
			

uchar code ascii_table_8x16[95][16];

void delay(int i)

{

		int j,k;

		for(j=0;j<i;j++)

		for(k=0;k<110;k++);


}


void delay_us(int i)

{

	int j,k;

	for(j=0;j<i;j++)

	for(k=0;k<1;k++);

}

void waitkey()


{

	repeat:	if(key==1) goto repeat;

	else	delay(2000);

}


void transfer_command(int data1)

{


		lcd_cs1=0;

		lcd_rs=0;

		lcd_e=0;

		lcd_rw=0;

		P0=data1;

		lcd_e=1;

		delay_us(2);

		lcd_cs1=1;

		lcd_e=0;

}

void transfer_data(int data1)
{

	lcd_cs1=0;

	lcd_rs=1;

	lcd_e=0;

	lcd_rw=0;


	P0=data1;

	lcd_e=1;

	delay_us(2);


	lcd_cs1=1;


	lcd_e=0;

}
		
void initial_lcd()				
{				
		lcd_reset=0;	//?????		
		delay(200);				
		lcd_reset=1;		//????		
		delay(20);				
		transfer_command(0xe2);	//???		
		delay(50);				
		transfer_command(0x2c);	//???? 1:????		
		delay(50);				
		transfer_command(0x2e);	//???? 2:??????????	
		delay(50);				
		transfer_command(0x2f);	//???? 3:????????????????	
		delay(50);				
		transfer_command(0x24);	//?????,????? 0x20~0x27	
		transfer_command(0x81);	//?????		
		transfer_command(0x2A);	//0x1A,???????,????? 0x00~0x3f	
		transfer_command(0xa2);	//1/9 ???(bias)		
		transfer_command(0xc8);	//?????:????		
		transfer_command(0xa0);	//?????:????		
		transfer_command(0x40);	//?????:0X40 ???? 1 ???,0x41:? 2 ?.
		transfer_command(0xaf);	//????		
}				

void lcd_address(uchar page,uchar column)		
{				
		column=column;				
		page=page-1;			//??????? 1 ?,??? IC ???? 0 ?,??????? 1
		transfer_command(0xb0+page);	//????????? 8 ??????? 64 ???? 8 ???
		transfer_command(((column>>4)&0x0f)+0x10);   //??????? 4 ?	
		transfer_command(column&0x0f);	//??????? 4 ?	
}				
//????				
void clear_screen()				
{				
	unsigned char i,j;				
	for(i=0;i<9;i++)		//???? IC ? 65 ?(?? 9 ??),???? 64 ?(8 ?),? 1 ?????,????????
	{				
		lcd_address(1+i,1);

			for(j=0;j<132;j++)	//???? IC ? 132 ?,???? 128 ?,? 4 ?????,??????????
			{

				transfer_data(0x00);//??????? 0,?????

			}
	}
}

void test_display(uchar data1,uchar data2)
{
	int i,j;
	for(j=0;j<8;j++)
	{
		lcd_address(j+1,0);

			for(i=0;i<128;i++)
			{

				transfer_data(data1);

				transfer_data(data2);

			}
	}
}

void display_string_8x16(uint page,uint column,uchar *text)
{
	uint i=0,j,k,n;
	while(text[i]>0x00) 
	{
		if((text[i]>=0x20)&&(text[i]<=0x7e))
		{
			j=text[i]-0x20;
			for(n=0;n<2;n++)
			{
				lcd_address(page+n,column);
				for(k=0;k<8;k++)
				{
					transfer_data(ascii_table_8x16[j][k+8*n]);//?????????,??????+1
				}
			}
			i++;
			column+=8;
		}
		else
		i++;
	}
}
void main(void)		
{		
  InitUart();                     //Init UART, use to show ADC result
  InitADC();                      //Init ADC sfr
	initial_lcd();	//LCD ???	
//	display_string_8x16(1,1," !\"#$%&'()*+,-./");	//?? 8x16 ? ASCII ????
//	display_string_8x16(3,1,"0123456789:;<=>?"); //?????????(???,???,??????)
//	display_string_8x16(5,1,"@ABCDEFGHIJKLMNO");
//	display_string_8x16(7,1,"PQRSTUVWXYZ[\\]^_");	//??:???????(\),???(\)????????(\),????(\)????
		waitkey();
//	clear_screen();
	while(1)
	{
	 ShowResult(0);              //Show Channel0
		waitkey();
		clear_screen();
	}
}

/*----------------------------
Send ADC result to UART
----------------------------*/
void ShowResult(BYTE ch)
{
    //SendData(ch);   	//Show Channel NO.
    SendData(GetADCResult(ch));     //Show ADC high 8-bit result
		
//if you want show 10-bit result, uncomment next line
  //  SendData(ADC_LOW2);             //Show ADC low 2-bit result
}
void SendData(BYTE dat)
{
    while (!TI);                    //Wait for the previous data is sent
    TI = 0;                         //Clear TI flag 
    SBUF = dat;                     //Send current data
		
		p = (dat/100)+0x30;
		o = (dat/10)%10+0x30;
		q = dat%10+0x30;
	
		f = &p;
		m = &o;
		e = &q;

	  display_string_8x16(5,1,f);
		display_string_8x16(5,10,m);
		display_string_8x16(5,19,e);
		display_string_8x16(5,26," ");
}
BYTE GetADCResult(BYTE ch)
{
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
    _nop_();                        //Must wait before inquiry
    _nop_();
    _nop_();
    _nop_();
    while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag
    ADC_CONTR &= ~ADC_FLAG;         //Close ADC

    return ADC_RES;                 //Return ADC result
}

/*----------------------------
Initial UART
----------------------------*/
void InitUart()
{
    SCON = 0x5a;                    //8 bit data ,no parity bit
    TMOD = 0x20;                    //T1 as 8-bit auto reload
    TH1 = TL1 = -(FOSC/12/32/BAUD); //Set Uart baudrate
    TR1 = 1;                        //T1 start running
}

/*----------------------------
Initial ADC sfr
----------------------------*/
void InitADC()
{
    P1ASF = 0x01;                   //Open 8 channels ADC function
    ADC_RES = 0;                    //Clear previous result
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
    Delay(2);                       //ADC power-on and delay
}



uchar code ascii_table_8x16[95][16]={

/*--  ??:     --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

/*--  ??:  !  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,

/*--  ??:  "  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

/*--  ??:  #  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,

/*--  ??:  $  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,

/*--  ??:  %  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,

/*--  ??:  &  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,

/*--  ??:  '  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

/*--  ??:  (  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,

/*--  ??:  )  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,

/*--  ??:  *  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,

/*--  ??:  +  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,

/*--  ??:  ,  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,

/*--  ??:  -  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,

/*--  ??:  .  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,

/*--  ??:  /  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,

/*--  ??:  0  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,

/*--  ??:  1  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,

/*--  ??:  2  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,

/*--  ??:  3  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,

/*--  ??:  4  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,

/*--  ??:  5  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,

/*--  ??:  6  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,

/*--  ??:  7  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,

/*--  ??:  8  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,

/*--  ??:  9  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,

/*--  ??:  :  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,

/*--  ??:  ;  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,

/*--  ??:  <  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,

/*--  ??:  =  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,

/*--  ??:  >  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,

/*--  ??:  ?  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,

/*--  ??:  @  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,

/*--  ??:  A  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,

/*--  ??:  B  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,

/*--  ??:  C  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,

/*--  ??:  D  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,

/*--  ??:  E  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,

/*--  ??:  F  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,

/*--  ??:  G  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,

/*--  ??:  H  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,

/*--  ??:  I  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,

/*--  ??:  J  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,

/*--  ??:  K  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,

/*--  ??:  L  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,

/*--  ??:  M  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,

/*--  ??:  N  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,

/*--  ??:  O  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,

/*--  ??:  P  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,

/*--  ??:  Q  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,

/*--  ??:  R  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,

/*--  ??:  S  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,

/*--  ??:  T  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,

/*--  ??:  U  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,

/*--  ??:  V  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,

/*--  ??:  W  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,

/*--  ??:  X  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,

/*--  ??:  Y  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,

/*--  ??:  Z  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,

/*--  ??:  [  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,

/*--  ??:  \  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,

/*--  ??:  ]  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,

/*--  ??:  ^  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

/*--  ??:  _  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,

/*--  ??:  `  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

/*--  ??:  a  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,

/*--  ??:  b  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,

/*--  ??:  c  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,

/*--  ??:  d  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,

/*--  ??:  e  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,

/*--  ??:  f  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,

/*--  ??:  g  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,

/*--  ??:  h  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,

/*--  ??:  i  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,

/*--  ??:  j  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,

/*--  ??:  k  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,

/*--  ??:  l  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,

/*--  ??:  m  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,

/*--  ??:  n  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,

/*--  ??:  o  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,

/*--  ??:  p  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,

/*--  ??:  q  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,

/*--  ??:  r  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,

/*--  ??:  s  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,

/*--  ??:  t  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,

/*--  ??:  u  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,

/*--  ??:  v  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,

/*--  ??:  w  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,

/*--  ??:  x  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,

/*--  ??:  y  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,

/*--  ??:  z  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,

/*--  ??:  {  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,

/*--  ??:  |  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,

/*--  ??:  }  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,

/*--  ??:  ~  --*/
/*--  Comic Sans MS12;  ??????????:?x?=8x16   --*/
0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00

};

注:字符编码方式忘了,所以注释有部分不能用 ~ - ~

本人小白一枚,请做为参考

PIC单片机功耗问题

阅读数 589

没有更多推荐了,返回首页