|
今天玩了一下最近很火的Caht GPT
要求寫一個 “1602屏 PCF8563ic 三個按鍵 的51單片機萬年歷的C語言代碼”
然后就給了我一段下面的代碼,各位看官看看,純屬娛樂!蠻有意思的。
#include <reg51.h>
#include <intrins.h>
sbit LCD_RS = P2^0; // LCD_RS引腳
sbit LCD_RW = P2^1; // LCD_RW引腳
sbit LCD_E = P2^2; // LCD_E引腳
sbit SDA = P1^1; // I2C數(shù)據(jù)線
sbit SCL = P1^0; // I2C時鐘線
sbit KEY_UP = P3^2; // 上鍵
sbit KEY_DOWN = P3^3; // 下鍵
sbit KEY_SET = P3^4; // 設(shè)置鍵
typedef unsigned char uint8_t; // 無符號8位整型數(shù)據(jù)類型
typedef unsigned int uint16_t; // 無符號16位整型數(shù)據(jù)類型
void Delay(uint16_t i); // 延時函數(shù)
void WriteCmd(uint8_t cmd); // 寫指令到LCD函數(shù)
void WriteData(uint8_t dat); // 寫數(shù)據(jù)到LCD函數(shù)
void LCD_Init(); // LCD初始化函數(shù)
void LCD_ShowString(uint8_t x, uint8_t y, uint8_t* str); // LCD顯示字符串函數(shù)
void LCD_ShowTime(); // LCD顯示時間函數(shù)
void LCD_ShowDate(); // LCD顯示日期函數(shù)
void PCF8563_Write(uint8_t addr, uint8_t dat); // 寫PCF8563芯片寄存器函數(shù)
uint8_t PCF8563_Read(uint8_t addr); // 讀PCF8563芯片寄存器函數(shù)
void ReadTime(); // 讀取當(dāng)前時間函數(shù)
void SetTime(); // 設(shè)置時間函數(shù)
uint8_t Key_Scan(); // 按鍵掃描函數(shù)
void AdjustTime(); // 調(diào)整時間函數(shù)
uint8_t sec, min, hour, day, week, month, year; // 時間變量定義
void main()
{
LCD_Init(); // LCD初始化
while(1){
ReadTime(); // 讀取當(dāng)前時間
LCD_ShowTime(); // 顯示時間
LCD_ShowDate(); // 顯示日期
Delay(1000); // 延時1s
}
}
void Delay(uint16_t i) // 延時函數(shù)
{
while(i--);
}
void WriteCmd(uint8_t cmd) // 寫指令到LCD函數(shù)
{
LCD_RS = 0; // 設(shè)置LCD_RS引腳為0,表示傳輸?shù)氖侵噶?br />
LCD_RW = 0; // 設(shè)置LCD_RW引腳為0,表示寫操作
P0 = cmd; // 設(shè)置P0口輸出值為指令
LCD_E = 1; // 設(shè)置LCD_E引腳為1,表示開始傳輸數(shù)據(jù)
_nop_(); // 等待一段時間
_nop_();
LCD_E = 0; // 設(shè)置LCD_E引腳為0,表示數(shù)據(jù)傳輸結(jié)束
}
void WriteData(uint8_t dat) // 寫數(shù)據(jù)到LCD函數(shù)
{
LCD_RS = 1; // 設(shè)置LCD_RS引腳為1,表示傳輸?shù)氖菙?shù)據(jù)
LCD_RW = 0; // 設(shè)置LCD_RW引腳為0,表示寫操作
P0 = dat; // 設(shè)置P0口輸出值為數(shù)據(jù)
LCD_E = 1; // 設(shè)置LCD_E引腳為1,表示開始傳輸數(shù)據(jù)
_nop_(); // 等待一段時間
_nop_();
LCD_E = 0; // 設(shè)置LCD_E引腳為0,表示數(shù)據(jù)傳輸結(jié)束
}
void LCD_Init() // LCD初始化函數(shù)
{
Delay(1000); // 延時等待LCD初始化完成
WriteCmd(0x38); // 初始化LCD顯示模式
WriteCmd(0x0c); // 開啟LCD顯示,并設(shè)置光標(biāo)不可見
WriteCmd(0x06); // 光標(biāo)右移,字符不動
WriteCmd(0x01); // 清屏
}
void LCD_ShowString(uint8_t x, uint8_t y, uint8_t* str) // LCD顯示字符串函數(shù)
{
uint8_t i;
if(y == 0) WriteCmd(0x80 + x); // 如果y為0,則設(shè)置光標(biāo)在第一行的第x個位置
else WriteCmd(0xc0 + x); // 如果y為1,則設(shè)置光標(biāo)在第二行的第x個位置
for(i=0; str[i]!='\0'; i++){ // 逐個字符顯示到LCD上
WriteData(str[i]);
}
}
void LCD_ShowTime() // LCD顯示時間函數(shù)
{
LCD_ShowString(0, 0, "Time: "); // 在第一行第一個字符顯示"Time: "
WriteData(hour/10+'0'); // 顯示小時十位數(shù)
WriteData(hour%10+'0'); // 顯示小時個位數(shù)
WriteData(':'); // 顯示冒號
WriteData(min/10+'0'); // 顯示分鐘十位數(shù)
WriteData(min%10+'0'); // 顯示分鐘個位數(shù)
WriteData(':'); // 顯示冒號
WriteData(sec/10+'0'); // 顯示秒鐘十位數(shù)
WriteData(sec%10+'0'); // 顯示秒鐘個位數(shù)
}
void LCD_ShowDate() // LCD顯示日期函數(shù)
{
uint8_t buf[16];
sprintf(buf, "%04d-%02d-%02d", year+2000, month, day); // 將年、月、日格式化為字符串
LCD_ShowString(0, 1, buf); // 在第二行顯示日期
}
void PCF8563_Write(uint8_t addr, uint8_t dat) // 寫PCF8563芯片寄存器函數(shù)
{
Start_I2C(); // 啟動I2C總線
Write_I2C(0xa2); // 發(fā)送寫地址
Write_I2C(addr); // 發(fā)送寄存器地址
Write_I2C(dat); // 發(fā)送數(shù)據(jù)
Stop_I2C(); // 停止I2C總線
}
uint8_t PCF8563_Read(uint8_t addr) // 讀PCF8563芯片寄存器函數(shù)
{
uint8_t dat;
Start_I2C(); // 啟動I2C總線
Write_I2C(0xa2); // 發(fā)送寫地址
Write_I2C(addr); // 發(fā)送寄存器地址
Start_I2C(); // 啟動I2C總線
Write_I2C(0xa3); // 發(fā)送讀地址
dat = Read_I2C(); // 讀取數(shù)據(jù)
NoAck_I2C(); // 發(fā)送非應(yīng)答信號
Stop_I2C(); // 停止I2C總線
return dat; // 返回讀到的數(shù)據(jù)
}
void ReadTime() // 讀取當(dāng)前時間函數(shù)
{
sec = bcd2hex(PCF8563_Read(0x02) & 0x7f); // 讀取秒,并將轉(zhuǎn)換后的十進制數(shù)賦值給sec變量
min = bcd2hex(PCF8563_Read(0x03) & 0x7f); // 讀取分,并將轉(zhuǎn)換后的十進制數(shù)賦值給min變量
hour = bcd2hex(PCF8563_Read(0x04) & 0x3f); // 讀取小時,并將轉(zhuǎn)換后的十進制數(shù)賦值給hour變量
day = bcd2hex(PCF8563_Read(0x05) & 0x3f); // 讀取日,并將轉(zhuǎn)換后的十進制數(shù)賦值給day變量
week = bcd2hex(PCF8563_Read(0x06) & 0x07); // 讀取周,并將轉(zhuǎn)換后的十進制數(shù)賦值給week變量
month = bcd2hex(PCF8563_Read(0x07) & 0x1f); // 讀取月,并將轉(zhuǎn)換后的十進制數(shù)賦值給month變量
year = bcd2hex(PCF8563_Read(0x08)); // 讀取年,并將轉(zhuǎn)換后的十進制數(shù)賦值給year變量
}
void SetTime() // 設(shè)置時間函數(shù)
{
PCF8563_Write(0x02, hex2bcd(sec)); // 寫入秒
PCF8563_Write(0x03, hex2bcd(min)); // 寫入分
PCF8563_Write(0x04, hex2bcd(hour)); // 寫入小時
PCF8563_Write(0x05, hex2bcd(day)); // 寫入日
PCF8563_Write(0x06, hex2bcd(week)); // 寫入周
PCF8563_Write(0x07, hex2bcd(month)); // 寫入月
PCF8563_Write(0x08, hex2bcd(year)); // 寫入年
}
uint8_t Key_Scan() // 按鍵掃描函數(shù)
{
uint8_t key = 0xff; // 初始化按鍵值為無效值
if(KEY_UP == 0){ // 如果檢測到上鍵按下
Delay(10); // 延時一段時間
if(KEY_UP == 0) key = KEY_UP; // 如果還是檢測到上鍵按下,則將按鍵值設(shè)置為KEY_UP
}
if(KEY_DOWN == 0){ // 如果檢測到下鍵按下
Delay(10); // 延時一段時間
if(KEY_DOWN == 0) key = KEY_DOWN; // 如果還是檢測到下鍵按下,則將按鍵值設(shè)置為KEY_DOWN
}
if(KEY_SET == 0){ // 如果檢測到設(shè)置鍵
|
|