找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 1881|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

lcd12864的STC125A32S2單片機(jī)程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:222030 發(fā)表于 2017-7-24 15:08 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
//STC12C5A單片機(jī)內(nèi)部AD連續(xù)采集126個(gè)數(shù)據(jù)
//將其處理后送12864液晶屏顯示
//橫坐標(biāo)代表時(shí)間,縱坐標(biāo)代表電壓
//延時(shí)后更新下一屏
//2014.3.7日試驗(yàn)基本成功
//2014.3.10日試驗(yàn)基本成功,剛上電時(shí)按下不同按鈕可取不同的采樣周期
//缺點(diǎn)只能測(cè)正電壓,顯示交流電半個(gè)波形
//無同步觸發(fā)功能
//按鍵掃描程序是用來調(diào)整                              每次采集的時(shí)間間隔,以便適于不同頻率 如果不用,需要給m設(shè)1初值 
//信號(hào)輸入引腳為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//液晶屏數(shù)據(jù)口
sbit    BF=P0^7;    //液晶顯示忙檢測(cè)位
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延時(shí)
void Delay_MS(uchar ms);//2延時(shí)
void Delay_S(uchar s);//3 延時(shí) 本程序沒用
void adchange();//4 AD 轉(zhuǎn)換
void Chk_busy( void );//5 液晶屏忙檢測(cè)
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個(gè)數(shù)據(jù)
void Clear(void);//10 清屏
void DisplayDot(uchar Hang,uchar lie);//11 顯示1個(gè)點(diǎn)
void drawpicture();//12 畫曲線
void lianxu_adchange();//13 連續(xù)采集多個(gè)數(shù)據(jù),用于高速采集 本程序沒用
void Delay_10S( );//14
void Delay_500
MS( );//15
void DISPLAY(uint bb);//16
數(shù)碼管顯示,可以不要
void CollectorDot100();//17本程序沒用
void keyscan();//18 按鍵掃描,可以不要
void Delay_US(uchar us)//1 延時(shí)
{
  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
開啟轉(zhuǎn)換電源
  //延時(shí),等待內(nèi)部電源穩(wěn)定,同時(shí)調(diào)節(jié)采集周期
      Delay_US(m);//500 US每次166 200US對(duì)應(yīng)61  100us每次應(yīng)改為27 50US對(duì)應(yīng)9
      Delay_US(m);
  Delay_US(m);
      Delay_US(m);
  P1M0=P1M0|0X03;     //
設(shè)置p1.0P1.1所在通道為開/漏模式
  P1M1=P1M1|0X03;
  ADC_CONTR=0xe0;     //11100000
開啟P1.0通道開始轉(zhuǎn)換
    Delay_US(m);      //延時(shí)一端時(shí)間,使輸入電壓達(dá)到穩(wěn)定
   Delay_US(m);
  ADC_
RES =0x00;     //A/D轉(zhuǎn)換結(jié)果寄存器
  ADC_RESL =0x00;
  ADC_CONTR |= 0x08;     //ADC_START=1,
開始轉(zhuǎn)換
  while(!(ADC_CONTR&0x10));   //0001,0000 等待A/D轉(zhuǎn)換結(jié)束
  temp1=ADC_RES; //讀取轉(zhuǎn)換結(jié)果,10位只要高8
      //temp2=ADC_RESL;
      ADC_CONTR=ADC_CONTR&0xe7; //
ADC_FLAG軟件清零
   Delay_US(m);
   Delay_US(m);
        P1M0=P1M0&0X00; //
設(shè)置P1口為普通I/O模式,以便用P1口顯示數(shù)據(jù)。
  P1M1=P1M1&0X40;   
}
//
每次采集除延時(shí)外,大約19 US
void Chk_busy(void)//5
判斷是否忙,實(shí)際是等待忙完
{
    DB_DATA=0xff;
   
RS=0;
    RW=1;
    E=1;
    while(
BF);  
    E=0;
}
void Write_lcd( uchar dat_cmd,uchar content)//6
寫液晶屏(命令或數(shù)據(jù))
{
    Chk_busy();
   
RS=dat_cmd;//0 命令,1數(shù)據(jù)
    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);    //
功能設(shè)定,8位接口控制,選擇普通指令(禁止了擴(kuò)展指令)
    Write_lcd(0,0x30);    //
同一指令的動(dòng)作不能同時(shí)改變RE DLG,需先改變DL G 再改變RE                               
    Write_lcd(0,0x0c);    //
整體顯示開,游標(biāo)位置顯示關(guān),游標(biāo)位置反白關(guān)
    Write_lcd(0,0x01);    //清除顯示
    Write_lcd(0,0x06);    //畫面設(shè)定,游標(biāo)右移,畫面不移動(dòng)
}
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); //
擴(kuò)充功能設(shè)定,同時(shí)關(guān)繪圖顯示
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); //
擴(kuò)充功能設(shè)定,同時(shí)開繪圖顯示
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; //
列號(hào) 0-7  
    lie2=lie%16; //
列內(nèi)號(hào) 0-15
    if(Hang<32)hang=Hang; //Y
坐標(biāo)32以內(nèi),行號(hào)=Y坐標(biāo)
    else
       {
        lie1+=8;
        hang=Hang-32;// Y
坐標(biāo)32~64之間,行號(hào)=Y坐標(biāo)-32
       }
    Write_lcd(0,0x80+hang);//
寫行號(hào)
    Write_lcd( 0,0x80+lie1 );//寫列號(hào)
    Read_lcd();//這一句還真有點(diǎn)用,但不知干什么的
    data1=Read_lcd( );//讀出原來數(shù)據(jù),,除要寫點(diǎn)位置外,原數(shù)據(jù)不變
    data2=Read_lcd( );   
    Write_lcd(0,0x80+hang);
    Write_lcd( 0,0x80+lie1 );
   if((lie2>=0)&&(lie2<=7))//1
個(gè)列地址對(duì)應(yīng)兩個(gè)字節(jié) 0-71個(gè)字節(jié),8-15是第2個(gè)字節(jié)
      {
       Write_lcd(1,data1|(0x01<<(7-lie2)));//
改變第1個(gè)字節(jié)內(nèi)容(插人所要畫的點(diǎn))
     Write_lcd(1,data2);//
第二個(gè)字節(jié)內(nèi)容不變      
      }
    elseif((lie2>=8)&&(lie2<=15))
      {
        Write_lcd(1,data1);//
1個(gè)字節(jié)內(nèi)容不變
    Write_lcd(1,data2|(0x01<<(15-lie2)));//改變第2個(gè)字節(jié)內(nèi)容(插人所要畫的點(diǎn))            
      }
     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個(gè)數(shù)據(jù)
       //CollectorDot100();//
采集100個(gè)數(shù)據(jù)并顯示所花時(shí)間  
    Clear();  //
清屏
    drawpicture(); //畫圖
    Delay_500MS( );
      //
s1=0;
       Delay_MS(250); //
延時(shí)約47ms
    Delay_500MS( );
    }      
}
void lianxu_adchange()//13
連續(xù)采集多個(gè)數(shù)據(jù)一次開啟,多次采集適合于高速
{   
      uchar i;
  ADC_CONTR=ADC_CONTR|0X80;  //10000000
開啟轉(zhuǎn)換電源
     Delay_MS(1);      //延時(shí),等待內(nèi)部電源穩(wěn)定
      //Delay_US(100);
  P1M0=P1M0|0X03;     //
設(shè)置p1.0P1.1所在通道為開/漏模式
  P1M1=P1M1|0X03;
   for(i=0;i<120;i++)
   {
  ADC_CONTR=0xe0;     //11100000
開啟P1.0通道開始轉(zhuǎn)換
     Delay_US(50);      //延時(shí)一端時(shí)間,使輸入電壓達(dá)到穩(wěn)定
  ADC_RES =0x00;     //A/D轉(zhuǎn)換結(jié)果寄存器
  ADC_RESL =0x00;
  ADC_CONTR |= 0x08;     //ADC_START=1,
開始轉(zhuǎn)換
  while(!(ADC_CONTR&0x10));   //0001,0000 等待A/D轉(zhuǎn)換結(jié)束
  tempdate[ i]=ADC_RES; //讀取轉(zhuǎn)換結(jié)果,10位只要高8      
      ADC_CONTR=ADC_CONTR&0xe7; //
ADC_FLAG軟件清零
    Delay_US(20);
   }
  P1M0=P1M0&0X00; //
設(shè)置P1口為普通I/O模式,以便用P1口顯示數(shù)據(jù)。
  P1M1=P1M1&0X40;         
}
void CollectorDot100()//9
用于計(jì)算并顯示采集100次所花時(shí)間
   {
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空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表