找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 542|回复: 0
收起左侧

Caht GPT 写51单片机代码

[复制链接]
ID:360457 发表于 2023-6-3 11:58 | 显示全部楼层 |阅读模式
今天玩了一下最近很火的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数据线
sbit SCL = P1^0; // I2C时钟线
sbit KEY_UP = P3^2; // 上键
sbit KEY_DOWN = P3^3; // 下键
sbit KEY_SET = P3^4; // 设置键

typedef unsigned char uint8_t; // 无符号8位整型数据类型
typedef unsigned int uint16_t; // 无符号16位整型数据类型

void Delay(uint16_t i); // 延时函数
void WriteCmd(uint8_t cmd); // 写指令到LCD函数
void WriteData(uint8_t dat); // 写数据到LCD函数
void LCD_Init(); // LCD初始化函数
void LCD_ShowString(uint8_t x, uint8_t y, uint8_t* str); // LCD显示字符串函数
void LCD_ShowTime(); // LCD显示时间函数
void LCD_ShowDate(); // LCD显示日期函数
void PCF8563_Write(uint8_t addr, uint8_t dat); // 写PCF8563芯片寄存器函数
uint8_t PCF8563_Read(uint8_t addr); // 读PCF8563芯片寄存器函数
void ReadTime(); // 读取当前时间函数
void SetTime(); // 设置时间函数
uint8_t Key_Scan(); // 按键扫描函数
void AdjustTime(); // 调整时间函数

uint8_t sec, min, hour, day, week, month, year; // 时间变量定义

void main()
{
    LCD_Init(); // LCD初始化
    while(1){
        ReadTime(); // 读取当前时间
        LCD_ShowTime(); // 显示时间
        LCD_ShowDate(); // 显示日期
        Delay(1000); // 延时1s
    }
}

void Delay(uint16_t i) // 延时函数
{
    while(i--);
}

void WriteCmd(uint8_t cmd) // 写指令到LCD函数
{
    LCD_RS = 0; // 设置LCD_RS引脚为0,表示传输的是指令
    LCD_RW = 0; // 设置LCD_RW引脚为0,表示写操作
    P0 = cmd; // 设置P0口输出值为指令
    LCD_E = 1; // 设置LCD_E引脚为1,表示开始传输数据
    _nop_(); // 等待一段时间
    _nop_();
    LCD_E = 0; // 设置LCD_E引脚为0,表示数据传输结束
}

void WriteData(uint8_t dat) // 写数据到LCD函数
{
    LCD_RS = 1; // 设置LCD_RS引脚为1,表示传输的是数据
    LCD_RW = 0; // 设置LCD_RW引脚为0,表示写操作
    P0 = dat; // 设置P0口输出值为数据
    LCD_E = 1; // 设置LCD_E引脚为1,表示开始传输数据
    _nop_(); // 等待一段时间
    _nop_();
    LCD_E = 0; // 设置LCD_E引脚为0,表示数据传输结束
}

void LCD_Init() // LCD初始化函数
{
    Delay(1000); // 延时等待LCD初始化完成
    WriteCmd(0x38); // 初始化LCD显示模式
    WriteCmd(0x0c); // 开启LCD显示,并设置光标不可见
    WriteCmd(0x06); // 光标右移,字符不动
    WriteCmd(0x01); // 清屏
}

void LCD_ShowString(uint8_t x, uint8_t y, uint8_t* str) // LCD显示字符串函数
{
    uint8_t i;
    if(y == 0) WriteCmd(0x80 + x); // 如果y为0,则设置光标在第一行的第x个位置
    else WriteCmd(0xc0 + x); // 如果y为1,则设置光标在第二行的第x个位置
    for(i=0; str[i]!='\0'; i++){ // 逐个字符显示到LCD上
        WriteData(str[i]);
    }
}

void LCD_ShowTime() // LCD显示时间函数
{
    LCD_ShowString(0, 0, "Time: "); // 在第一行第一个字符显示"Time: "
    WriteData(hour/10+'0'); // 显示小时十位数
    WriteData(hour%10+'0'); // 显示小时个位数
    WriteData(':'); // 显示冒号
    WriteData(min/10+'0'); // 显示分钟十位数
    WriteData(min%10+'0'); // 显示分钟个位数
    WriteData(':'); // 显示冒号
    WriteData(sec/10+'0'); // 显示秒钟十位数
    WriteData(sec%10+'0'); // 显示秒钟个位数
}

void LCD_ShowDate() // LCD显示日期函数
{
    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芯片寄存器函数
{
    Start_I2C(); // 启动I2C总线
    Write_I2C(0xa2); // 发送写地址
    Write_I2C(addr); // 发送寄存器地址
    Write_I2C(dat); // 发送数据
    Stop_I2C(); // 停止I2C总线
}

uint8_t PCF8563_Read(uint8_t addr) // 读PCF8563芯片寄存器函数
{
    uint8_t dat;
    Start_I2C(); // 启动I2C总线
    Write_I2C(0xa2); // 发送写地址
    Write_I2C(addr); // 发送寄存器地址
    Start_I2C(); // 启动I2C总线
    Write_I2C(0xa3); // 发送读地址
    dat = Read_I2C(); // 读取数据
    NoAck_I2C(); // 发送非应答信号
    Stop_I2C(); // 停止I2C总线
    return dat; // 返回读到的数据
}

void ReadTime() // 读取当前时间函数
{
    sec = bcd2hex(PCF8563_Read(0x02) & 0x7f); // 读取秒,并将转换后的十进制数赋值给sec变量
    min = bcd2hex(PCF8563_Read(0x03) & 0x7f); // 读取分,并将转换后的十进制数赋值给min变量
    hour = bcd2hex(PCF8563_Read(0x04) & 0x3f); // 读取小时,并将转换后的十进制数赋值给hour变量
    day = bcd2hex(PCF8563_Read(0x05) & 0x3f); // 读取日,并将转换后的十进制数赋值给day变量
    week = bcd2hex(PCF8563_Read(0x06) & 0x07); // 读取周,并将转换后的十进制数赋值给week变量
    month = bcd2hex(PCF8563_Read(0x07) & 0x1f); // 读取月,并将转换后的十进制数赋值给month变量
    year = bcd2hex(PCF8563_Read(0x08)); // 读取年,并将转换后的十进制数赋值给year变量
}

void SetTime() // 设置时间函数
{
    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() // 按键扫描函数
{
    uint8_t key = 0xff; // 初始化按键值为无效值
    if(KEY_UP == 0){ // 如果检测到上键按下
        Delay(10); // 延时一段时间
        if(KEY_UP == 0) key = KEY_UP; // 如果还是检测到上键按下,则将按键值设置为KEY_UP
    }
    if(KEY_DOWN == 0){ // 如果检测到下键按下
        Delay(10); // 延时一段时间
        if(KEY_DOWN == 0) key = KEY_DOWN; // 如果还是检测到下键按下,则将按键值设置为KEY_DOWN
    }
    if(KEY_SET == 0){ // 如果检测到设置键
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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