找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1541|回复: 0
打印 上一主题 下一主题
收起左侧

lcd12864的STC125A32S2单片机程序

[复制链接]
跳转到指定楼层
楼主
ID:222030 发表于 2017-7-24 15:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//STC12C5A单片机内部AD连续采集126个数据
//将其处理后送12864液晶屏显示
//横坐标代表时间,纵坐标代表电压
//延时后更新下一屏
//2014.3.7日试验基本成功
//2014.3.10日试验基本成功,刚上电时按下不同按钮可取不同的采样周期
//缺点只能测正电压,显示交流电半个波形
//无同步触发功能
//按键扫描程序是用来调整                              每次采集的时间间隔,以便适于不同频率 如果不用,需要给m1初值 
//信号输入引脚为p1.0
#include<STC12C5A.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar idata tempdate[126]={0};
uchar temp1,temp2,m=166;
uchar
keyval,key=16;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
#define DB_DATA   P0//液晶屏数据口
sbit    BF=P0^7;    //液晶显示忙检测位
sbit    RS=P3^5;
sbit    RW=P3^6;
sbit     E=P3^4;
//sbit   
s1=P3^7;
sbit beep=P2^3;
sbit diola=P2^5;
sbit dula=P2^6;
sbit wela=P2^7;
sbit led1=P1^0;
sbit led2=P1^1;
sbit led3=P1^2;
sbit led4=P1^3;
sbit led5=P1^4;
void Delay_
US(uchar us);//1延时
void Delay_MS(uchar ms);//2延时
void Delay_S(uchar s);//3 延时 本程序没用
void adchange();//4 AD 转换
void Chk_busy( void );//5 液晶屏忙检测
void Write_lcd( uchar dat_cmd,uchar content);//6写液晶屏
uchar Read_lcd(void);//7读液晶屏
void Lcd_inital(void); //8液晶屏初始化
void CollectorDot(uchar ch);//9 采集126个数据
void Clear(void);//10 清屏
void DisplayDot(uchar Hang,uchar lie);//11 显示1个点
void drawpicture();//12 画曲线
void lianxu_adchange();//13 连续采集多个数据,用于高速采集 本程序没用
void Delay_10S( );//14
void Delay_500
MS( );//15
void DISPLAY(uint bb);//16
数码管显示,可以不要
void CollectorDot100();//17本程序没用
void keyscan();//18 按键扫描,可以不要
void Delay_US(uchar us)//1 延时
{
  while(--us);
}
void Delay_MS(uchar ms)//2
{
  do {Delay_US(246);Delay_US(247);}
  while(--ms);
}
void Delay_S(uchar s)//3
本程序没用
{
  do{Delay_MS(200);Delay_MS(200);Delay_MS(200);Delay_MS(200);Delay_MS(200);}
  while(--s);
}
void adchange()//4
{
  ADC_CONTR=ADC_CONTR|0X80;  //10000000
开启转换电源
  //延时,等待内部电源稳定,同时调节采集周期
      Delay_US(m);//500 US每次166 200US对应61  100us每次应改为27 50US对应9
      Delay_US(m);
  Delay_US(m);
      Delay_US(m);
  P1M0=P1M0|0X03;     //
设置p1.0P1.1所在通道为开/漏模式
  P1M1=P1M1|0X03;
  ADC_CONTR=0xe0;     //11100000
开启P1.0通道开始转换
    Delay_US(m);      //延时一端时间,使输入电压达到稳定
   Delay_US(m);
  ADC_
RES =0x00;     //A/D转换结果寄存器
  ADC_RESL =0x00;
  ADC_CONTR |= 0x08;     //ADC_START=1,
开始转换
  while(!(ADC_CONTR&0x10));   //0001,0000 等待A/D转换结束
  temp1=ADC_RES; //读取转换结果,10位只要高8
      //temp2=ADC_RESL;
      ADC_CONTR=ADC_CONTR&0xe7; //
ADC_FLAG软件清零
   Delay_US(m);
   Delay_US(m);
        P1M0=P1M0&0X00; //
设置P1口为普通I/O模式,以便用P1口显示数据。
  P1M1=P1M1&0X40;   
}
//
每次采集除延时外,大约19 US
void Chk_busy(void)//5
判断是否忙,实际是等待忙完
{
    DB_DATA=0xff;
   
RS=0;
    RW=1;
    E=1;
    while(
BF);  
    E=0;
}
void Write_lcd( uchar dat_cmd,uchar content)//6
写液晶屏(命令或数据)
{
    Chk_busy();
   
RS=dat_cmd;//0 命令,1数据
    RW=0;
    E=1;
    DB_DATA=content;   
    E=0;
}
uchar Read_lcd(void)//7
读液晶屏
{
    uchar rddata;
    Chk_busy();
    RS=1;
    RW=1;
    E=1;
    rddata=DB_DATA;
    E=0;
    return rddata;
}
void Lcd_inital(void)    //8  Lcd
初始化
{  
  dula=1;
wela=1;
P0=0xff;
dula=0;
wela=0;
// diola=1;
Write_lcd(0,0x30);    //
功能设定,8位接口控制,选择普通指令(禁止了扩展指令)
    Write_lcd(0,0x30);    //
同一指令的动作不能同时改变RE DLG,需先改变DL G 再改变RE                               
    Write_lcd(0,0x0c);    //
整体显示开,游标位置显示关,游标位置反白关
    Write_lcd(0,0x01);    //清除显示
    Write_lcd(0,0x06);    //画面设定,游标右移,画面不移动
}
void CollectorDot()//9
   {
     uchar i;            
     for(i=0;i<126;i++)
      {              
       adchange();
     tempdate[ i]=temp1;
      }
    }
void Clear(void)//10
清屏
{
    uchar i,j,k;
k=0x80;
Write_lcd(0,0x34); //
扩充功能设定,同时关绘图显示
for(i=0;i<32;i++)
{
  Write_lcd(0,0x80+i);
  Write_lcd(0,k);
  for(j=0;j<16;j++)  
        Write_lcd(1,0x00);        
}
k=0x88;
for(i=0;i<32;i++)
{
  Write_lcd(0,0x80+i);
     Write_lcd(0,k);
     for(j=0;j<16;j++)  
     Write_lcd(1,0x00);        
}
Write_lcd(0,0x36); //
扩充功能设定,同时开绘图显示
Write_lcd(0,0x30);
}

void DisplayDot(uchar Hang,uchar lie)//11
y 0-63 x 0-127
       {   
       uchar hang,lie1,lie2,data1,data2;   
       Write_lcd(0,0x34);                     
    lie1=lie/16; //
列号 0-7  
    lie2=lie%16; //
列内号 0-15
    if(Hang<32)hang=Hang; //Y
坐标32以内,行号=Y坐标
    else
       {
        lie1+=8;
        hang=Hang-32;// Y
坐标32~64之间,行号=Y坐标-32
       }
    Write_lcd(0,0x80+hang);//
写行号
    Write_lcd( 0,0x80+lie1 );//写列号
    Read_lcd();//这一句还真有点用,但不知干什么的
    data1=Read_lcd( );//读出原来数据,,除要写点位置外,原数据不变
    data2=Read_lcd( );   
    Write_lcd(0,0x80+hang);
    Write_lcd( 0,0x80+lie1 );
   if((lie2>=0)&&(lie2<=7))//1
个列地址对应两个字节 0-71个字节,8-15是第2个字节
      {
       Write_lcd(1,data1|(0x01<<(7-lie2)));//
改变第1个字节内容(插人所要画的点)
     Write_lcd(1,data2);//
第二个字节内容不变      
      }
    elseif((lie2>=8)&&(lie2<=15))
      {
        Write_lcd(1,data1);//
1个字节内容不变
    Write_lcd(1,data2|(0x01<<(15-lie2)));//改变第2个字节内容(插人所要画的点)            
      }
     Write_lcd(0,0x36);
       Write_lcd(0,0x30);      
    }
void drawpicture()//12
画图
{
    uchar dot,x,y1,y2;
  for(dot=0;dot<126;dot++)
   {
      x=dot;
    y1=tempdate[dot]/4;
        y2=63-y1;
        DisplayDot(y2,x);   
   }
}

void Delay_500MS( )//1
{
uint bb=6667;
while(bb>0)
{
Delay_US(200);
bb--;
}
}

void main ()
{
Lcd_inital(); //
初始化
diola=1;
while(key==16){keyscan();}
switch(key)
{
case 0:m=9;led2=0;break;
case 1:m=27;led3=0;break;
case 2:m=61;led4=0;break;
case 4:m=166;led5=0;break;
default:break;
}
while(1)
      {                              
      CollectorDot();//
采集126个数据
       //CollectorDot100();//
采集100个数据并显示所花时间  
    Clear();  //
清屏
    drawpicture(); //画图
    Delay_500MS( );
      //
s1=0;
       Delay_MS(250); //
延时约47ms
    Delay_500MS( );
    }      
}
void lianxu_adchange()//13
连续采集多个数据一次开启,多次采集适合于高速
{   
      uchar i;
  ADC_CONTR=ADC_CONTR|0X80;  //10000000
开启转换电源
     Delay_MS(1);      //延时,等待内部电源稳定
      //Delay_US(100);
  P1M0=P1M0|0X03;     //
设置p1.0P1.1所在通道为开/漏模式
  P1M1=P1M1|0X03;
   for(i=0;i<120;i++)
   {
  ADC_CONTR=0xe0;     //11100000
开启P1.0通道开始转换
     Delay_US(50);      //延时一端时间,使输入电压达到稳定
  ADC_RES =0x00;     //A/D转换结果寄存器
  ADC_RESL =0x00;
  ADC_CONTR |= 0x08;     //ADC_START=1,
开始转换
  while(!(ADC_CONTR&0x10));   //0001,0000 等待A/D转换结束
  tempdate[ i]=ADC_RES; //读取转换结果,10位只要高8      
      ADC_CONTR=ADC_CONTR&0xe7; //
ADC_FLAG软件清零
    Delay_US(20);
   }
  P1M0=P1M0&0X00; //
设置P1口为普通I/O模式,以便用P1口显示数据。
  P1M1=P1M1&0X40;         
}
void CollectorDot100()//9
用于计算并显示采集100次所花时间
   {
uchar i;
uint AA;
TMOD=0X01;
TH0=0;
TL0=0;
TR0=1;               
     for(i=0;i<100;i++)
      {              
       adchange();
     tempdate[ i]=temp1;
      }
  TR0=0;
  AA=TH0*256+TL0;
  DISPLAY(AA);
    }
void DISPLAY(uint bb)
  {
     uint i;
      uchar b1,b2,b3,b4,b5;
   b1= bb/10000%10;
   b2= bb/1000%10;
     b3= bb/100%10;
     b4= bb/10%10;
     b5= bb%10;
   for(i=0;i<2000;i++)
   {
   wela=1;
   DB_DATA=0xfe;
   wela=0;
    dula=1;
   DB_DATA=table[b1];
       dula=0;
    Delay_MS(10);
    wela=1;
   DB_DATA=0xfd;
   wela=0;
    dula=1;
   DB_DATA=table[b2];
       dula=0;
    Delay_MS(10);
    wela=1;
   DB_DATA=0xfb;
   wela=0;
    dula=1;
   DB_DATA=table[b3];
       dula=0;
    Delay_MS(10);
    wela=1;
   DB_DATA=0xf7;
   wela=0;   
   dula=1;
   DB_DATA=table[b4];
       dula=0;
    Delay_MS(10);
     wela=1;
   DB_DATA=0xef;
   wela=0;   
   dula=1;
   DB_DATA=table[b5];
       dula=0;
    Delay_MS(10);
   }
}
void keyscan()
{
  uchar temp;   
    P3=0xef;
    temp=P3;
    temp=temp&0x0f;
    if(temp!=0x0f)
    {
      Delay_MS(20);
      if(temp!=0x0f)
      {
        temp=P3;
        switch(temp)
        {
          case 0xee:
               key=0;
               break;
          case 0xed:
               key=4;
               break;
          case 0xeb:
               key=8;
               break;
          case 0xe7:
               key=12;
               break;
         }
         while(temp!=0x0f)
         {
           temp=P3;
           temp=temp&0x0f;
           beep=0;
         }
         beep=1;
        
         }
    }
    P3=0xdf;
    temp=P3;
    temp=temp&0x0f;
    if(temp!=0x0f)
    {
      Delay_MS(20);
      if(temp!=0x0f)
      {
        temp=P3;
        switch(temp)
        {
          case 0xde:
               key=1;
               break;
          case 0xdd:
               key=5;
               break;
          case 0xdb:
               key=9;
               break;
          case 0xd7:
               key=13;
               break;
         }
         while(temp!=0x0f)
         {
           temp=P3;
           temp=temp&0x0f;
           beep=0;
         }
         beep=1;
      
      }
      }
    P3=0xbf;
    temp=P3;
    temp=temp&0x0f;
    if(temp!=0x0f)
    {
      Delay_MS(20);
      if(temp!=0x0f)
      {
        temp=P3;
        switch(temp)
        {
          case 0xbe:
               key=2;
               break;
          case 0xbd:
               key=6;
               break;
          case 0xbb:
               key=10;
               break;
          case 0xb7:
               key=14;
               break;
         }
         while(temp!=0x0f)
         {
           temp=P3;
           temp=temp&0x0f;
           beep=0;
         }
         beep=1;      
  
      }
      }
    P3=0x7f;
    temp=P3;
    temp=temp&0x0f;
    if(temp!=0x0f)
    {
      Delay_MS(20);
      if(temp!=0x0f)
      {
        temp=P3;
        switch(temp)
        {
          case 0x7e:
               key=3;
               break;
          case 0x7d:
               key=7;
               break;
          case 0x7b:
               key=11;
               break;
          case 0x77:
               key=15;
               break;
         }
         while(temp!=0x0f)
         {
           temp=P3;
           temp=temp&0x0f;
           beep=0;
         }
         beep=1;   
      }
      
}
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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