鬧鐘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時序時,會不定時再更新。
線路圖

照片#1

照片#2

照片#3

照片#4

<<程式說明:>> (本文所列之程式,將會不定時的更新或修改,各位同好可視檔案抬頭所註明之更新日期分辨之,不便之處,尚請原諒。)
/*-----------------------------------------------
檔案名稱: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;} //判斷是否閏年之2月28日
else { if(AC_mth==2 && AC_day>=30 && (AC_yer%4)==0) {AC_day=1;AC_mth++;goto C0;} //判斷是否閏年之2月29日
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); //先進行功能設置,四位元資料介面,兩行顯示,5′7點陣字元。
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的一干BYTE轉BIT的子程式,同好可以比對"I2C LCD介面應用於STC89C516RD+之溫度與濕度計"一文中的舊程式,因為副程式之行數甚多,就不在此逐條解說,相信同好應有足夠的程度了解,就不在此一一說明,請見諒。
PS:@2019/02/22補充說明
請同好要留意在線路圖中的LCM接線的不同, 本文所描述的程式, 在硬體線路上, 要特別留意在LCM模組的D0~D3(接腳#7~#10)必須要接地才可以, 一般市售的51學習機, 基本上是沒有如此的設計, 所以如果要使用本文所用的程式, 在硬體上一定要留意此點.
限會員,要發表迴響,請先登入


