網路城邦
上一篇 回創作列表 下一篇   字體:
鬧鐘3精簡版實作程式說明(WO PCF8574T/AT)
2019/02/04 17:00:14瀏覽664|回應0|推薦0

鬧鐘3精簡版實作程式說明(W/O PCF8574T/AT)

 

鬧鐘3精簡版實作程式說明(W/O PCF8574T/AT)

        過年假期,突然想到可以將原先"單晶片MCU STC12C5608AD的時鐘程式"一文中的I2C_LCM使用之PCF8574AT/T加以省去,直接用MCU剩餘的I/O腳來控制,最早期在LCD的介面完全用I/O腳時,總共需8個DATA+3個控制信號=11支I/O腳,算起來在小型MCU來說是很佔用數量不多的I/O腳,,之後利用PCF8974AT/T的I2C介面將LCM介面精簡至2個I/O腳就可以控制的程度,當然就是使用I2C_LCM介面板,如此成本也就增加百餘元之多,幾乎佔了LCM模組成本的1/3之多,有機會用到STC15C5608AD後有23個I/O腳,比原先的ATMEL 89C4052的I/O腳只有15腳,足足多出8個I/O腳,因此才想到如果用I2C_LCM的4BIT傳送模式的話,I/O只需要7支腳即可,而"單晶片MCU STC12C5608AD的時鐘程式"一文中有足足一個P1未使用,正可以用來給LCM的4BIT介面,如此就可以省下一個I2C_LCM介面板的成本,所以就動手修改線路與程式,來分享給各位同好。

        基本上此次的修改是使用"鬧鐘2.0加強版功能說明"一文中的基礎加以修改的,還好一切尚稱順利,將LCM的4個DATA+3個控制腳與一只20K偏壓的可變電阻焊上後,就直接修改之前的 I2CPCF8574.c 與主程式,沒想到還很順利在短短3個小時就搞定,雖然尚未利用示波器與LA量測整個LCM介面的信號波形與量測時序,來確認時序是否符合規格,就先行將修改之部份撰文分享之。

        本文將敘述的部份有2個部份,第一部份是主程式部份,這部份在解釋修改後之LCD顯示指令與I/O腳定義而已,而第2部份則重點在介紹 LCD4.c 的副程式,這是在此次實驗中最主要的部份,將來如果有進一步修改LCM時序時,會不定時再更新。

線路圖

 LT-TEST_06線路圖

照片#1

 LT-TEST_06正視圖

照片#2

 LT-TEST_06 LCM背視圖

照片#3

 LT-TEST_06組合圖

照片#4

 LT-TEST_06 LCM介面與偏壓可變電阻

 

 

 

 

<<程式說明:>>  (本文所列之程式,將會不定時的更新或修改,各位同好可視檔案抬頭所註明之更新日期分辨之,不便之處,尚請原諒。)

/*-----------------------------------------------

檔案名稱:LT-TEST_06.c @2019/02/04 PM 12:00

程式說明: 此程式在撰寫一個由MCU內部的 Timmer 0 計時器來實現時鐘,

                而重點在構思不使用 RTC DS1302 晶片下, 只利用計時器定時中斷的功能,

                並且在程式責寫時加入三個 CTx,CTy,CTz變數,來修正石英振盪晶體的頻率

                之差異,而且可以利用UART指令來設定修正的數值.

附註 :        STC12C5608AD 單晶片MCU

@2019/01/24 STC12C5608AD, XTALL=22.1184MHZ,I2C-LCM

@2019/01/25 added BUZZ & ALARM command

@2019/01/26 added SW1~SW4 functions

@2019/01/26 ALARM array had 11 sets,

@2019/01/28 added 1 more ALARM array

@2019/01/31 added ALARM for the UART checksum error & UART command error

@2019/02/04 拿去 PCF8574T/AT

------------------------------------------------*/

#include "reg52.h"

#include "stdio.h"

#include "stdlib.h"

#include "intrins.h"

#include "string.h"

#include "delay.c"

#include "LCD4.c"

 

unsigned char* RC ="TEST_06 2019-02-04\r\n";

unsigned char* SPC="                    ";

#define XTAL          22118400        //XTAL 外部石英晶體 22.1184 Mhz

#define BAUDRATE        115200            //UART BAUDRATE 115200,8,N,1

#define UARTSIZE        12                 //Uart buffer size

#define BS                      0x08                //\b backspace code

#define WAIT           10

#define WAIT5         5

#define IEPROM                0x1ff9

typedef unsigned char BYTE;

typedef unsigned int WORD;

typedef unsigned long DWORD;

 

sbit CDS          = P3^2;        //CDS sensor input

//sbit                        = P3^3;        //

//sbit LCM_SDA         = P3^4;        //PCF8574AT SDA

//sbit LCM_SCL         = P3^5;        //PCF8574AT SCL

sbit ALARM            = P3^7;        //ALARM out

 

sbit RS                     = P1^0;        //LCD4 RS

sbit RW                    = P1^1;        //LCD4 RW

sbit EN                     = P1^2;        //LCD4 EN

sbit OUT3                = P1^3;        //

sbit OUT4                = P1^4;        //LCD D4

sbit OUT5                = P1^5;        //LCD D5

sbit OUT6                = P1^4;        //LCD D6

sbit OUT7                = P1^5;        //LCD D7

 

sbit LED_GRN        =P2^7;

sbit LED_YEW        =P2^6;

sbit LED_BLU        =P2^5;

sbit LED_RED        =P2^4;

sbit SW4          =P2^3;

sbit SW3          =P2^2;

sbit SW2          =P2^1;

sbit SW1          =P2^0;

/*------------------------------------------------

                整體變數宣告

------------------------------------------------*/

bit Turn_flag=0,SetFlag=0,busy=0,LCD_flag,DISP_flag=0,BUZZ=0,CDS_flag,CT_flag=0;      

 

unsigned char  temp[40];

unsigned char  UART_buf[UARTSIZE];        //UART RCV Buffer

unsigned char  ALM[12][2]= {{0,7},{5,7},{10,7},{15,7},{20,7},{25,7},{30,7},{35,7},{40,7},{45,7},{50,7},{55,7}};        //ALARM array

unsigned xdata AC_ms=0,Rcv_idx,AC_sec,AC_min,AC_hrs,AC_day,AC_mth,AC_yer,CTx,CTy,CTz;

unsigned xdata ALM_no;                 //ALARM set no.

unsigned short CT,CDS_cnt;

/*------------------------------------------------

                  函數聲明

------------------------------------------------*/

void Init_Timer0(void);

void Init_Timer1(void);

void Uart_SendStr(unsigned char *value,unsigned int leng);

void Uart_PutChar(unsigned char dat);

void Uart_ISR_Handle(void);

void Uart_cmd(void);              // UART接收指令處理副程式

void Sent_Uart(void);              // UART送出訊息

void CHECK_year(void);               // 萬年曆檢查副程式

void LED_flash(void);              // LED閃爍

/*------------------------------------------------

                    主程式

------------------------------------------------*/

void main(void)

{      unsigned char i=0,k;        //

       

        P1 = P2 = P3 =0xff;        AUXR &= 0xbf;

        CT=58921;                     // Timer 0 count down參數基值

        Init_Timer0();           // 計時器初始化

        Init_Timer1();           // UART baus rate

        LCD4_Device_Init();        //啟動LCM介面板與 1602液晶螢幕

        DelayMs(WAIT5);          //需延遲待待LCD螢幕內部運作

        CDS_cnt=0;DISP_flag=0;

        for(i=0;i

       SetFlag=0;                                                // 完成 LCM 的初啟程式.清除旗號

        LCD4_Write_Command(0x01);              //清除螢幕內容,

        DelayMs(WAIT5);

        AC_sec=AC_min=0,AC_hrs=12;AC_day=4;AC_mth=2;AC_yer=19;

        ET0=1;

        TR0=1;

        ES=1;

        EA=1;              //打開總中斷

//**********************************

        Uart_SendStr(RC,22);                    //system start, sent the system information to UART

        DelayMs(WAIT5);

        sprintf(temp,"%2d/%d/%d ",(int)AC_yer,(int)AC_mth,(int)AC_day); // 顯示 // 時間;

        if(RI==0)        {        LCD4_Write_String(0,0,temp);       }

        Rcv_idx=0;

        CDS_flag=0;

        while(1)        //主程式

        {        BUZZ=1;ALM_no=0;CTx=0;CTy=50;CTz=0;

                START:

                //**************************

                ES=1;LED_YEW=~BUZZ;

               

                if(SetFlag==1)                //UART HAD COMMAND RECIVED

                {        DISP_flag=0;LED_BLU=0;

                        k=0;

                        //****** UART CHECKSUM

                        for(i=0;i<10;i++) k="k%256+(int)UART_buf[i];}" p="">

                        if((int)UART_buf[11] == k)            //比對CHECKSUM

                        {        Uart_cmd();     }

                        else {        BUZZ=1;DelayMs(100);BUZZ=0;BUZZ=1;DelayMs(100);BUZZ=0; }        //CHECKSUM ERROR

                        //顯示接收到的 UART DATA

                        if(DISP_flag==0)

                        {        sprintf(temp,"%02x%02x%02x%02x",(int)UART_buf[2],(int)UART_buf[3],(int)UART_buf[4],(int)UART_buf[5]);

                                LCD4_Write_String(0,1,temp);

                                sprintf(temp,"%02x %02x<%02x",(int)uart_buf[6],(int)uart_buf[11],(int)k); p="">

                                LCD4_Write_String(8,1,temp);

                        }

                           SetFlag=0;Rcv_idx=0;LED_BLU=1;

                }            

                //****************************

                if(Turn_flag==1 )                     

                {        LED_GRN=~LED_GRN;

                        if(AC_min>=60 )                             // 是否時間""已滿60

                        {        AC_min=0;AC_hrs++;   

                                if(CTz >= AC_hrs)           // 判斷是否需要補加""

                                {        AC_sec++;     }

                        }

                        if(AC_hrs>=24 )                             // 判斷是否已滿24小時

                        {        AC_hrs=0;AC_day++;

                                CHECK_year();                      // 萬年曆檢核                               

                        }

                        if((AC_sec/3)>11 )                  // 顯示 ALARM時間 lister

                        {        sprintf(temp,"%d/%d/%2d ",(int)AC_yer,(int)AC_mth,(int)AC_day); }        // 顯示 // 時間;

                        else

                        {        LCD4_Write_String(0,0,"        ");

                                sprintf(temp,"%d %d:%d ",(int)AC_sec/3,(int)ALM[AC_sec/3][1],(int)ALM[AC_sec/3][0]);      }                             

                        if(RI==0)        {        LCD4_Write_String(0,0,temp);       }                     

                        sprintf(temp,"%2d:%2d:%2d",(int)AC_hrs,(int)AC_min,(int)AC_sec);        //顯示 CLOCK 時間               

                        if(RI==0)        {        LCD4_Write_String(8,0,temp);       }

                        for(i=0;i<12;i++) vertify="" the="" alarm="" set="" current="" time="" p="">

                        {        if(ALM[i][1]==AC_hrs && ALM[i][0]==AC_min && (AC_sec%2)==0) {        BUZZ=1;goto AAA;     }        // 比對 ALARM時間是否吻合

                                if(ALM[i][1]!=AC_hrs || ALM[i][0]!=AC_min ) {        BUZZ=0; }                               

                        }

                        AAA:

                        if(CDS==0 && CDS_flag==0)        { CDS_cnt++;LED_RED=0;CDS_flag=~CDS_flag;CT_flag=1;BUZZ=1;DelayMs(100); BUZZ=0;}                //check CDS detector ON

                        else  {        if(CDS==1 && CDS_flag==1) {        LED_RED=1;CDS_flag=~CDS_flag;  }        }                      //check CDS detector OFF

                        if(SW1==0 )                    //check SW1 for display CDS_cnt, CTx, CTy, CTz data

                        {        while(SW1==0)

                                {        LED_flash();             }

                                LCD4_Write_String(0,1,SPC);

                                CT_flag=1;

                                sprintf(temp,"CDS_cnt=%5d, CTx=%2x, CTy=%2x, CTz=%2x\r\n",(short)CDS_cnt,(int)CTx,(int)CTy,(int)CTz);        //列印 CDS_cnt, CTx, CTy CTz 的數值                   

                                Uart_SendStr(temp,strlen(temp)); 

                        }

                        if(SW2==0)                     // auto set the alarm by 5 minters

                        {        while(SW2==0)

                                {        LED_flash();             }

                                for(i=0;i<12;i++) p="">

                                {        ALM[i][1]=AC_hrs;      }                               

                        }

                        if(SW3==0)                     // 設定5分鐘後蜂鳴器提醒

                        {        while(SW3==0)

                                {        LED_flash();             }

                                ALM[0][1]=AC_hrs;

                                ALM[0][0]=AC_min+5;

                                if(        ALM[0][0]>=60) {ALM[0][0]=ALM[0][0]-60;ALM[0][1]++;        }

                                if(        ALM[0][1]>=24) {ALM[0][1]=ALM[0][1]-24;        }

                        }

                        if(SW4==0)                     // 設定10分鐘後蜂鳴器提醒

                        {        while(SW4==0)

                                {        LED_flash();             }

                                ALM[0][1]=AC_hrs;

                                ALM[0][0]=AC_min+10;

                                if(        ALM[0][0]>=60) {ALM[0][0]=ALM[0][0]-60;ALM[0][1]++;        }

                                if(        ALM[0][1]>=24) {ALM[0][1]=ALM[0][1]-24;        }

                        }

                        if(CT_flag==1)

                        {        LCD4_Write_String(0,1,SPC);

                                sprintf(temp,"%5d ",(short)CDS_cnt);

                                if(RI==0)        {LCD4_Write_String(0,1,temp);}

                                sprintf(temp,"%2d %2d %2d ",(int)CTx,(int)CTy,(int)CTz);        //顯示 CDS_cnt, CTx, CTy CTz 的數值           

                                if(RI==0)        {LCD4_Write_String(7,1,temp);}

                                CT_flag=0;

                        }

                        Turn_flag=0;                  

                }                                                     

                goto START;   

        }

}

//********************************

void LED_flash(void)

{        LED_RED=LED_GRN=LED_BLU=LED_YEW=0;DelayMs(100);

        LED_RED=LED_GRN=LED_BLU=LED_YEW=1;DelayMs(100);

}

void CHECK_year(void)

{        if((AC_mth==4 || AC_mth==6 || AC_mth==9 || AC_mth==11) && AC_day>=31) {AC_day=1;AC_mth++;goto C0;}        //判斷有31日的月份

        else  {        if(AC_mth==2 && AC_day>=29 && (AC_yer%4)!=0) {AC_day=1;AC_mth++;goto C0;}                                //判斷是否閏年之228                                

        else  {        if(AC_mth==2 && AC_day>=30 && (AC_yer%4)==0) {AC_day=1;AC_mth++;goto C0;}                                //判斷是否閏年之229

        else  {        if((AC_mth==1 || AC_mth==3 || AC_mth==5 || AC_mth==7 || AC_mth==8 || AC_mth==10 || AC_mth==12) && AC_day>=32) {AC_day=1;AC_mth++;goto C0;}        }        //判斷有30日的月份

        }      }

        C0:

        if(AC_mth>=13)        {AC_yer++;AC_mth=1;}        // 判斷月份是否已滿12

        return;

}

//******************

void Uart_cmd(void)

{     

        switch((int)UART_buf[2])

        {      case 0x80:        //WIFI下傳時間.

                                        AC_hrs=(UART_buf[5]/16)*10+(UART_buf[5]%16);        //16進制轉為10進制

                                        AC_min=(UART_buf[4]/16)*10+(UART_buf[4]%16);

                                        AC_sec=(UART_buf[3]/16)*10+(UART_buf[3]%16);

                                        break;

                case 0x81:        //WIFI下傳日期

                                        AC_yer=(UART_buf[5]/16)*10+(UART_buf[5]%16);        //16進制轉為10進制

                                        AC_mth=(UART_buf[4]/16)*10+(UART_buf[4]%16);

                                        AC_day=(UART_buf[3]/16)*10+(UART_buf[3]%16);

                                        sprintf(temp,"%2d/%d/%d ",(int)AC_yer,(int)AC_mth,(int)AC_day); // 顯示 // 時間;

                                        if(RI==0)        {        LCD4_Write_String(0,0,temp);       }

                                        break;

                //*******************

                case 0x82:        CTx=(UART_buf[3]/16)*10+(UART_buf[3]%16);         // CTx參數, 補正差

                                        CTy=(UART_buf[4]/16)*10+(UART_buf[4]%16);         // CTy參數, 扣負差

                                        CTz=(UART_buf[5]/16)*10+(UART_buf[5]%16);         // CTz參數, 補秒數

                                        CT_flag=1;

                                        break;

                case 0x83:        CT_flag=1;

                                        DISP_flag=1;                   //設定顯示時間修正參數值

                                        break;

                case 0x84:  ALM_no=UART_buf[3];               //ALARM 編組 NO

                                        if(ALM_no>=12) break;

                                        ALM[ALM_no][1]=(UART_buf[5]/16)*10+(UART_buf[5]%16);         // ALARM 小時

                                        ALM[ALM_no][0]=(UART_buf[4]/16)*10+(UART_buf[4]%16); // ALARM 分鐘

                                        break;

                default:        {        BUZZ=1;DelayMs(100);BUZZ=0;BUZZ=1;DelayMs(100);BUZZ=0;        }break;

        }     

}

/*------------------------------------------------

                計數器0的初始化 for w/o RTC

------------------------------------------------*/

void Init_Timer0(void)                             // 計數器0的初始化

{      TMOD |=        0x01;                                       // 選擇為計時器0模式,工作方式 1,僅用TR0打開啟動。

        AUXR &= ~0x80;

        TH0 = (65536-(CT+CTx-CTy))>>8;        // 設置計時器初始值, 4ms

        TL0  = (65536-(CT+CTx-CTy));         //

       

        TR0 = 1;          //打開計時器                           

}

/*------------------------------------------------

                計時器 TIMER0 中斷處理 for w/o RTC

------------------------------------------------*/

void TIMER0(void) interrupt 1 using 1

{      unsigned int i;

        TH0 = (65536-(CT+CTx-CTy))>>8;        // 重設計時器初始值

        TL0  = (65536-(CT+CTx-CTy));         //

        i++;

        if(BUZZ==1) ALARM= ~ALARM;               // 如何ALARM旗號被啟動,就輸出 BUZZL信號

        else ALARM=0;

        if(i>=250)                                         // 確認是否滿足1秒鐘

        {        AC_sec++;if(AC_sec>=60)        {AC_sec=0;AC_min++;}       

                i=0;Turn_flag=1;                       // 設定足秒旗號

        }

}

/*------------------------------------------------

                計數器 1 的初始化        115200,8,N,1 @ 1T / 22.1184Mhz

------------------------------------------------*/

void Init_Timer1(void)

{     

        SCON = 0x5a;

        AUXR |= 0x40;

        TMOD = 0x20;       // setting Timer1 to 8bits autoload

        TL1 = (256-(XTAL/32/BAUDRATE)); // @22.1184Mhz, for 115200bps

        TH1 = (256-(XTAL/32/BAUDRATE));

        TR1 = 1;                 // Timer1 running enable

        ES = 1;           // serial port interrupt enable

        EA = 1;           // interrupt enable

}

/*------------------------------------------------

                發送一個位元組

------------------------------------------------*/

void Uart_PutChar(unsigned char dat)

{        while(busy);

        busy=1;

        SBUF = dat;

}

/*------------------------------------------------

                發送一個字串

------------------------------------------------*/

void Uart_SendStr(unsigned char *value,unsigned int leng)

{        while(leng>0)   //

        {        Uart_PutChar(*value);

                value++;

                leng--;

        }     

}

/*------------------------------------------------

                串口中斷程式

---------------------------------------------*/

void Uart_ISR_Handle (void) interrupt 4

{      if(RI==1)

        {        UART_buf[Rcv_idx]=SBUF;

                if(UART_buf[Rcv_idx-1]==0x20 && UART_buf[Rcv_idx]==0xa5) {Rcv_idx=1;UART_buf[0]=0x20;UART_buf[1]=0xa5;}

                Rcv_idx++;            

                if(Rcv_idx>=UARTSIZE)        //連續接收16個字元資訊

                {        Rcv_idx=0;

                       SetFlag=1;                        //接收完成,標誌旗號設定 1

                }             

                RI = 0;

        }

        if(TI==1)                                  //如果是發送標誌位元,清零

        {        TI=0;

                busy=0;                                    //清除傳送旗號

        }

}

//*********************************

 

//*** FILE:LCD4.c

 

unsigned xdata LCD4temp=0;

bit LCD4_flag2=0;                      //應答標誌位元

 

/*------------LCD1602寫入指令----------------------------

函數名稱:void LCD4_Write_Command(unsigned char command)       

          LCD4寫入指令

函數參數:unsigned char command //準備寫入的指令

函數說明:向LCD4的指令寄存器寫入一個指令

---------------------------------------------------------------*/

void LCD4_Write_Command(unsigned char command)        //LCD4寫入指令

{     

        DelayMs(5);    //此處插入一個等待很重要,小於這個時間會導致連續寫時出現錯誤

    //先寫入高4

        LCD4temp = command & 0xf0 | 0x08;        //先處理高4位,EN=0,RW=0,RS=0

        P1=LCD4temp;

        LCD4temp |= 0x0c;         //拉高EN

        P1=LCD4temp;

        LCD4temp &= 0xfb;               //EN置低,下降沿寫入液晶

        P1=LCD4temp;

        //接下來寫入低4

        if(LCD4_flag2==0) return;        //判斷是否是冷開機

        LCD4temp = command<<4; p="">

        P1=LCD4temp;

        LCD4temp |= 0x0c;         //拉高EN

        P1=LCD4temp;

        LCD4temp &= 0xfb;               //EN置低,下降沿寫入液晶

        P1=LCD4temp;

}

/*------------LCD1602寫入資料----------------------------

函數名稱:void LCD1602_Write_Data(unsigned char data)       

          LCD4寫入資料

函數參數:unsigned char data //準備寫入的資料

函數說明:向LCD4的指令寄存器寫入一個資料

---------------------------------------------------------------*/

void LCD4_Write_Data(unsigned char Data)        //LCD4寫入資料 

{

        DelayMs(5);    //此處插入一個等待很重要,小於這個時間會導致連續寫時出現錯誤

        //先寫入高4

        LCD4temp = (Data & 0xf0) | 0x09;        //先處理高4位,EN=0,RW=0,RS=1

        P1=LCD4temp;

        LCD4temp |= 0x0c;                         //拉高EN

        P1=LCD4temp;

        LCD4temp &= 0xfb;                        //EN置低,下降沿寫入液晶

        P1=LCD4temp;

        //接下來寫入低4

        LCD4temp = (Data<<4) 0x09="" p="">

        P1=LCD4temp;

        LCD4temp |= 0x0c;                         //拉高EN

        P1=LCD4temp;

        LCD4temp &= 0xfb;                        //EN置低,下降沿寫入液晶

        P1=LCD4temp;

}

/*------------------------------------------------------------------

函數名稱:void LCD4_Init(void)     //LCD4初始化函數

函數參數:無

函數說明:參考LCD4液晶說明手冊,請特別留意LCD4_flag2

------------------------------------------------------------------*/

void LCD4_Device_Init(void)      //LCD1602初始化函數

{     

        DelayMs(50);                                  //冷開機

        LCD4_Write_Command(0x38);

        DelayMs(50);

        LCD4_Write_Command(0x28);

        DelayMs(5);

        LCD4_Write_Command(0x28);

        DelayMs(5);

        LCD4_Write_Command(0x28);

        DelayMs(50);                          //先等待50毫秒VDD上電穩定

        LCD4_flag2=1;

        LCD4_Write_Command(0x28);      //先進行功能設置,四位元資料介面,兩行顯示,57點陣字元。

        DelayMs(25);                  //等待上條指令完成

        LCD4_Write_Command(0x08);        //Display On/Off Control,顯示開關:D=1打開,游標開關:C=1打開,閃爍開關:B=1打開

        DelayMs(5);

        LCD4_Write_Command(0x01);      //清屏

        DelayUs2x(5);

        LCD4_Write_Command(0x06);      //AC位址遞增模式

        DelayUs2x(5);

        LCD4_Write_Command(0x01);      //清屏

        DelayUs2x(5);

        LCD4_Write_Command(0x02);        //HOME

        DelayMs(5);

        LCD4_Write_Command(0x0f);        //Display On/Off Control,顯示開關:D=1打開,游標開關:C=1打開,閃爍開關:B=1打開

        DelayMs(5);

}

/*--------設置AC地址--------------------------------------------------

函數名稱:void LCD4_Set_Position(unsigned char x, unsigned char y)

          LCD4設置下一個準備寫入的字元位置

函數參數:unsigned char x 行地址 0~F

          unsigned char y 列地址 0~1

函數說明:設置AC地址,

---------------------------------------------------------------------*/

void LCD4_Set_Position(unsigned char x, unsigned char y)         

{      //LCD4設置下一個準備寫入的字元位置

        unsigned char address = (y * 0x40) + (0x80 + x) ;

        LCD4_Write_Command(address);

        DelayUs2x(150);

}

/*--------向指定的位置開始寫字串 ---------------------------------------

函數名稱:LCD4_Write_String(unsigned char X, unsigned char Y, char *s)

          向指定的位置開始寫字串

函數參數:unsigned char X             //列位置

          unsigned char Y                //行位置

          char *String          //要顯示的字串

函數說明:向指定的位置開始寫字串

------------------------------------------------------------------------*/

void LCD4_Write_String(unsigned char X, unsigned char Y, char *String)     

{      //向指定的位置開始寫字串

        LCD4_Set_Position(X,Y);

        while(*String)

        {

                LCD4_Write_Data(*String++);

                DelayUs2x(50);

        }

}

@2019/02/05 修改之程式說明

) LT-TEST_06.c主程式部份:

        在主程式有修改之處, 在原先的LCM顯示的指令修改為本次的新指令,其仔的部份大致上未做任何異動。

新指令部份

      #include "LCD4.c"

      LCD4_Device_Init();                   //啟動LCM介面板與 1602液晶螢幕

      LCD4_Write_Command(0x01);         //清除螢幕內容,

      LCD4_Write_String(0,1,temp);

舊指令部份

      #include "I2CPCF8574.c"                                //I2C LCM 副程式

      LCD1602_Device_Init(XIO_ID);                    //啟動I2C LCD介面板與 1602液晶螢幕

      LCD1602_Write_Command(XIO_ID,0x01);   //清除螢幕內容, XIO_ID 需依  I2C                                                                              //PCF8574T(0x40) PCF8574AT(0x70)

      LCD1602_Write_String(XIO_ID,0,1,temp);

        舊指令因為需要有分辨 使用何者的I2C 介面IC PCF8574T PCF8574T所以需帶入XIO_ID的變數 而新指令部份因為已不再使用I2C元件 所以就不需帶入I2C PORT位址變數。

FILE:LCD4.c是副程式

        在此程式的修改,最大的是LCD4.C的副程式,總共有5個子程式被修改,當然是移除了XIO_ID的變數,同時也不再需要I2C的一干BYTEBIT的子程式,同好可以比對"I2C LCD介面應用於STC89C516RD+之溫度與濕度計"一文中的舊程式,因為副程式之行數甚多,就不在此逐條解說,相信同好應有足夠的程度了解,就不在此一一說明,請見諒。


 
PS:@2019/02/22補充說明
 請同好要留意在線路圖中的LCM接線的不同, 本文所描述的程式, 在硬體線路上, 要特別留意在LCM模組的D0~D3(接腳#7~#10)必須要接地才可以, 一般市售的51學習機, 基本上是沒有如此的設計, 所以如果要使用本文所用的程式, 在硬體上一定要留意此點.

( 興趣嗜好電腦3C )
回應 推薦文章 列印 加入我的文摘
上一篇 回創作列表 下一篇

引用
引用網址:https://classic-blog.udn.com/article/trackback.jsp?uid=PYANG&aid=124538615