【51单片机】单片机开发者的福音: 让AI看电路图帮你编写程序(使用ChatGPT 中训练好的单片机工程师模型)

简介: 使用AI大语言模型编写 单片机程序. 使用的是 OpenAI公司发布的 ChatGPT .在ChatGPT上有别人训练好的 单片机工程师 with Keil uVision 5 - C Code Explainer模型, 可以上传电路图改模型可以通过这个用户所给的电路图进行编程.


这里使用的人工智能是 OpenAI公司开发的 ChatGPT.为了让AI用起来更加的顺手我们可以选择单片机工程师这个训练好的模型,当然用原本的ChatGPT-4o也是挺好用的.

第0步 需要准备东西

1. 科学上网

2. 电路图 (可以是pdf文件\也可是高清的png或者jpg图片)

第1步 寻找一个适合自己的模型

可以点开链接直达这个模型单片机工程师 with keil uvision 5,或者登录后按照下图的方式找到这个模型.

第2步 沟通方式

公式 : 介绍+目的+要求

例子:

因为chatGPT 联系上下文的能力很强, 除了第一次沟通的时候发送文件介绍之外,在此对话的时候就可以不用发送了.就是当做一个仆人一样来对话就好, 它给我们程序,我们拿去编译 下载就好,不满足我们的要求就接着和它沟通,只要你把问题和你想要的效果描述清楚,它基本上都能完成的很好,大大提高你的工作效率.

看看这次AI的回答:

我们可以看到 , 它给出了

#include "lcd1602.h"
#include "ds1302.h"

这两个库我们是没有的,所以呢 我们具体的情况还要给ai说明白,我们没有ds1302这个芯片, 也没有lcd1602.h这个库,需要自己写

进一步说明情况

请看ai的这次回答: 我个人认为应该是没什么问题,它把lcd1602模块给单独拿来出来方便我们复用,下面是ai的回答:

好的,我们可以不使用DS1302芯片,直接在程序中预设时间信息为“23:55”,并使用定时器来模拟时间的递增。以下是修改后的完整代码,包括LCD1602的驱动程序和时间的显示功能。

LCD1602驱动程序 (lcd1602.hlcd1602.c)

lcd1602.h

#ifndef _LCD1602_H_
#define _LCD1602_H_
#include <reg51.h>
sbit RS = P2^0;  // RS引脚
sbit RW = P2^1;  // RW引脚
sbit E  = P2^2;  // E引脚
sbit D4 = P2^4;  // 数据引脚 D4
sbit D5 = P2^5;  // 数据引脚 D5
sbit D6 = P2^6;  // 数据引脚 D6
sbit D7 = P2^7;  // 数据引脚 D7
void LCD_Init(void);
void LCD_Cmd(unsigned char cmd);
void LCD_Data(unsigned char dat);
void LCD_ShowString(unsigned char x, unsigned char y, char *str);
void LCD_ShowNum(unsigned char x, unsigned char y, unsigned int num, unsigned char len);
void LCD_ShowChar(unsigned char x, unsigned char y, char ch);
#endif

lcd1602.c

#include "lcd1602.h"
// 延时函数
void Delay(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 114; j++);
}
// 发送命令到LCD
void LCD_Cmd(unsigned char cmd) {
    RS = 0;
    RW = 0;
    E  = 1;
    D4 = cmd & 0x10;
    D5 = cmd & 0x20;
    D6 = cmd & 0x40;
    D7 = cmd & 0x80;
    E  = 0;
    E  = 1;
    D4 = cmd & 0x01;
    D5 = cmd & 0x02;
    D6 = cmd & 0x04;
    D7 = cmd & 0x08;
    E  = 0;
    Delay(2);
}
// 发送数据到LCD
void LCD_Data(unsigned char dat) {
    RS = 1;
    RW = 0;
    E  = 1;
    D4 = dat & 0x10;
    D5 = dat & 0x20;
    D6 = dat & 0x40;
    D7 = dat & 0x80;
    E  = 0;
    E  = 1;
    D4 = dat & 0x01;
    D5 = dat & 0x02;
    D6 = dat & 0x04;
    D7 = dat & 0x08;
    E  = 0;
    Delay(2);
}
// 初始化LCD1602
void LCD_Init(void) {
    LCD_Cmd(0x02);  // 初始化指令
    LCD_Cmd(0x28);  // 4位数据接口, 2行显示, 5x7点阵
    LCD_Cmd(0x0C);  // 显示开,光标关
    LCD_Cmd(0x06);  // 数据输入后,光标右移
    LCD_Cmd(0x01);  // 清屏
}
// 显示字符串
void LCD_ShowString(unsigned char x, unsigned char y, char *str) {
    unsigned char addr;
    if (y == 0)
        addr = 0x80 + x;
    else
        addr = 0xC0 + x;
    LCD_Cmd(addr);
    while (*str)
        LCD_Data(*str++);
}
// 显示数字
void LCD_ShowNum(unsigned char x, unsigned char y, unsigned int num, unsigned char len) {
    unsigned char t, temp;
    unsigned char show_flag = 0;
    for (t = 0; t < len; t++) {
        temp = (num / 10000) % 10;
        if (show_flag == 0 && t < len - 1) {
            if (temp == 0)
                LCD_Data(' ');
            else {
                show_flag = 1;
                LCD_Data(temp + '0');
            }
        } else
            LCD_Data(temp + '0');
        num *= 10;
    }
}
// 显示单个字符
void LCD_ShowChar(unsigned char x, unsigned char y, char ch) {
    unsigned char addr;
    if (y == 0)
        addr = 0x80 + x;
    else
        addr = 0xC0 + x;
    LCD_Cmd(addr);
    LCD_Data(ch);
}

主程序 (main.c)

#include <reg51.h>
#include "lcd1602.h"
// 定义全局变量来存储时间
unsigned char hour = 23, minute = 55, second = 0;
// 定时器中断函数,每1秒调用一次
void Timer0_ISR(void) interrupt 1 {
    TH0 = 0xFC;  // 重装载定时器初值
    TL0 = 0x18;
    
    second++;
    if (second == 60) {
        second = 0;
        minute++;
        if (minute == 60) {
            minute = 0;
            hour++;
            if (hour == 24)
                hour = 0;
        }
    }
}
// 定时器0初始化
void Timer0_Init() {
    TMOD = 0x01;  // 设置定时器0为模式1(16位定时器)
    TH0 = 0xFC;   // 设置定时器初值,使得1秒触发一次中断
    TL0 = 0x18;
    ET0 = 1;      // 使能定时器0中断
    EA  = 1;      // 使能总中断
    TR0 = 1;      // 启动定时器0
}
void main() {
    LCD_Init();      // 初始化LCD1602
    Timer0_Init();   // 初始化定时器
    while(1) {
        // 在LCD1602上显示时间
        LCD_ShowString(0, 0, "Time:");
        LCD_ShowNum(5, 0, hour, 2);   // 显示小时
        LCD_ShowChar(7, 0, ':');
        LCD_ShowNum(8, 0, minute, 2); // 显示分钟
        LCD_ShowChar(10, 0, ':');
        LCD_ShowNum(11, 0, second, 2); // 显示秒
        
        Delay(1000);  // 刷新间隔
    }
}

说明:

  1. LCD1602驱动lcd1602.hlcd1602.c文件实现了LCD1602的初始化和显示功能,包括显示字符串、数字和单个字符。
  2. 定时器模拟时钟:定时器0的中断每秒触发一次,用于更新秒、分钟和小时变量,并将其显示在LCD1602上。
  3. 程序结构:主程序通过循环不断更新LCD1602上的时间显示。

编译和运行:

  1. 将上述代码分别保存到lcd1602.hlcd1602.cmain.c中。
  2. 使用Keil uVision 5进行编译并将程序下载到开发板上。
  3. 观察LCD1602上显示的时间变化。

这个程序将在开始时显示"23:55",然后每秒自动递增,模拟时钟功能。

总之它给程序,你就拿到你的板子上进行调试即可,还不满意你就让它改.

但是由于你不是plus用户, 用多了可能就回出现(提醒你该充钱或者切换账号)

没钱有没钱的办法,可以使用 copilot 请看这篇文章【51单片机】让AI识别电路图,帮你进行编码(以51单片机为例)


这是我让AI实现的万年历功能,阅读代码其实我们不难看出ai的创造性思维是不如人类的, 就比如它不知道如何把独立按键发挥到极致,让时间日期数值可以增加可以减小,程序中它只有增加没有减小的逻辑,对用户来说体验感就大打折扣.我们能做的就是继续和它沟通完善程序,或者自己修改程序.

要实现一个万年历功能,显示时间和日期,并且可以通过独立按键修改时间和日期,需要按照以下步骤进行设计和实现。这个程序将使用8051单片机、LCD1602显示屏、以及独立按键来实现时间和日期的显示和调整。

功能实现概要:

  1. 显示内容:在LCD1602上显示当前的日期和时间。
  2. 时间日期初始化:初始时间为2024年8月15日16:19:15。
  3. 时间更新:使用定时器中断每秒更新一次时间。
  4. 独立按键调整时间日期:使用三个独立按键分别调整小时、分钟和日期。

硬件连接假设:

  • LCD1602:数据线接P2口,控制线RS、RW、E分别接P2.0、P2.1、P2.2。
  • 按键:三个独立按键分别接P3.0(调整小时)、P3.1(调整分钟)、P3.2(调整日期)。

万年历功能代码

lcd1602.h

#ifndef _LCD1602_H_
#define _LCD1602_H_
#include <reg51.h>
sbit RS = P2^0;  // RS引脚
sbit RW = P2^1;  // RW引脚
sbit E  = P2^2;  // E引脚
sbit D4 = P2^4;  // 数据引脚 D4
sbit D5 = P2^5;  // 数据引脚 D5
sbit D6 = P2^6;  // 数据引脚 D6
sbit D7 = P2^7;  // 数据引脚 D7
void LCD_Init(void);
void LCD_Cmd(unsigned char cmd);
void LCD_Data(unsigned char dat);
void LCD_ShowString(unsigned char x, unsigned char y, char *str);
void LCD_ShowNum(unsigned char x, unsigned char y, unsigned int num, unsigned char len);
void LCD_ShowChar(unsigned char x, unsigned char y, char ch);
#endif

lcd1602.c

#include "lcd1602.h"
// 延时函数
void Delay(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 114; j++);
}
// 发送命令到LCD
void LCD_Cmd(unsigned char cmd) {
    RS = 0;
    RW = 0;
    E  = 1;
    D4 = cmd & 0x10;
    D5 = cmd & 0x20;
    D6 = cmd & 0x40;
    D7 = cmd & 0x80;
    E  = 0;
    E  = 1;
    D4 = cmd & 0x01;
    D5 = cmd & 0x02;
    D6 = cmd & 0x04;
    D7 = cmd & 0x08;
    E  = 0;
    Delay(2);
}
// 发送数据到LCD
void LCD_Data(unsigned char dat) {
    RS = 1;
    RW = 0;
    E  = 1;
    D4 = dat & 0x10;
    D5 = dat & 0x20;
    D6 = dat & 0x40;
    D7 = dat & 0x80;
    E  = 0;
    E  = 1;
    D4 = dat & 0x01;
    D5 = dat & 0x02;
    D6 = dat & 0x04;
    D7 = dat & 0x08;
    E  = 0;
    Delay(2);
}
// 初始化LCD1602
void LCD_Init(void) {
    LCD_Cmd(0x02);  // 初始化指令
    LCD_Cmd(0x28);  // 4位数据接口, 2行显示, 5x7点阵
    LCD_Cmd(0x0C);  // 显示开,光标关
    LCD_Cmd(0x06);  // 数据输入后,光标右移
    LCD_Cmd(0x01);  // 清屏
}
// 显示字符串
void LCD_ShowString(unsigned char x, unsigned char y, char *str) {
    unsigned char addr;
    if (y == 0)
        addr = 0x80 + x;
    else
        addr = 0xC0 + x;
    LCD_Cmd(addr);
    while (*str)
        LCD_Data(*str++);
}
// 显示数字
void LCD_ShowNum(unsigned char x, unsigned char y, unsigned int num, unsigned char len) {
    unsigned char t, temp;
    unsigned char show_flag = 0;
    for (t = 0; t < len; t++) {
        temp = (num / 10000) % 10;
        if (show_flag == 0 && t < len - 1) {
            if (temp == 0)
                LCD_Data(' ');
            else {
                show_flag = 1;
                LCD_Data(temp + '0');
            }
        } else
            LCD_Data(temp + '0');
        num *= 10;
    }
}
// 显示单个字符
void LCD_ShowChar(unsigned char x, unsigned char y, char ch) {
    unsigned char addr;
    if (y == 0)
        addr = 0x80 + x;
    else
        addr = 0xC0 + x;
    LCD_Cmd(addr);
    LCD_Data(ch);
}

主程序 (main.c)

#include <reg51.h>
#include "lcd1602.h"
// 定义引脚
sbit Key1 = P3^0;  // 调整小时
sbit Key2 = P3^1;  // 调整分钟
sbit Key3 = P3^2;  // 调整日期
// 时间和日期变量
unsigned int year = 2024;
unsigned char month = 8, day = 15, hour = 16, minute = 19, second = 15;
// 检测按键按下状态的函数
bit Key_Pressed(sbit key) {
    if (!key) {      // 如果按键被按下
        Delay(20);   // 消抖延时
        if (!key) {  // 确认按下
            while (!key);  // 等待按键释放
            return 1;
        }
    }
    return 0;
}
// 更新时间函数
void Update_Time() {
    second++;
    if (second == 60) {
        second = 0;
        minute++;
        if (minute == 60) {
            minute = 0;
            hour++;
            if (hour == 24) {
                hour = 0;
                day++;
                // 判断每月天数
                if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day == 32) {
                    day = 1;
                    month++;
                } else if ((month == 4 || month == 6 || month == 9 || month == 11) && day == 31) {
                    day = 1;
                    month++;
                } else if (month == 2 && (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)) { // 闰年
                    if (day == 30) {
                        day = 1;
                        month++;
                    }
                } else if (month == 2 && day == 29) {
                    day = 1;
                    month++;
                }
                if (month == 13) {
                    month = 1;
                    year++;
                }
            }
        }
    }
}
// 定时器中断函数,每1秒调用一次
void Timer0_ISR(void) interrupt 1 {
    TH0 = 0xFC;  // 重装载定时器初值
    TL0 = 0x18;
    
    Update_Time();
}
// 定时器0初始化
void Timer0_Init() {
    TMOD = 0x01;  // 设置定时器0为模式1(16位定时器)
    TH0 = 0xFC;   // 设置定时器初值,使得1秒触发一次中断
    TL0 = 0x18;
    ET0 = 1;      // 使能定时器0中断
    EA  = 1;      // 使能总中断
    TR0 = 1;      // 启动定时器0
}
void main() {
    LCD_Init();      // 初始化LCD1602
    Timer0_Init();   // 初始化定时器
    while(1) {
        // 检测按键,调整时间和日期
        if (Key_Pressed(Key1)) {
            hour++;
            if (hour == 24) hour = 0;
        }
        if (Key_Pressed(Key2)) {
            minute++;
            if (minute == 60) minute = 0;
        }
        if (Key_Pressed(Key3)) {
            day++;
            // 需要根据月份判断天数
            if ((month == 1 || month == 
3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day == 32) {
                day = 1;
                month++;
            } else if ((month == 4 || month == 6 || month == 9 || month == 11) && day == 31) {
                day = 1;
                month++;
            } else if (month == 2 && (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)) { // 闰年
                if (day == 30) {
                    day = 1;
                    month++;
                }
            } else if (month == 2 && day == 29) {
                day = 1;
                month++;
            }
            if (month == 13) {
                month = 1;
                year++;
            }
        }
        // 在LCD1602上显示日期
        LCD_ShowString(0, 0, "Date:");
        LCD_ShowNum(5, 0, year, 4);  // 显示年份
        LCD_ShowChar(9, 0, '-');
        LCD_ShowNum(10, 0, month, 2); // 显示月份
        LCD_ShowChar(12, 0, '-');
        LCD_ShowNum(13, 0, day, 2);  // 显示日期
        
        // 在LCD1602上显示时间
        LCD_ShowString(0, 1, "Time:");
        LCD_ShowNum(5, 1, hour, 2);  // 显示小时
        LCD_ShowChar(7, 1, ':');
        LCD_ShowNum(8, 1, minute, 2); // 显示分钟
        LCD_ShowChar(10, 1, ':');
        LCD_ShowNum(11, 1, second, 2); // 显示秒
        
        Delay(100);  // 刷新间隔
    }
}

说明:

  1. LCD1602驱动lcd1602.hlcd1602.c文件实现了LCD1602的初始化和显示功能,包括显示字符串、数字和单个字符。
  2. 时间和日期更新:定时器0中断每秒触发一次,更新秒、分钟、小时、天、月和年。
  3. 按键调整:三个独立按键分别用于调整小时、分钟和日期。
  4. 闰年判断:程序中对2月份日期进行了闰年的判断和处理。
  5. 程序结构:主程序通过循环不断检测按键输入,并在LCD1602上实时更新日期和时间显示。

编译和运行:

  1. 将上述代码分别保存到lcd1602.hlcd1602.cmain.c中。
  2. 使用Keil uVision 5进行编译,并将程序下载到开发板上。
  3. 通过按键调整时间和日期,并观察LCD1602上显示的结果。

这个程序实现了一个简单的万年历功能,可以显示时间和日期,并且通过按键进行调整。你可以根据需求进一步修改或扩展功能。

当然,AI对程序某个部分的驱动其实是值得我们学习的, 比如按键消抖和lcd1602的驱动等等。如果你是初学的你可能很难理解按键消抖,也很难理解LCD1602的时序图,然后对着时序图 读状态 写指令 读数据 写数据。 这东西对曾经只想完成老师作业的我来说简直就是一种折磨。

相关文章
|
4天前
|
机器学习/深度学习 人工智能 自然语言处理
CogAgent-9B:智谱 AI 开源 GLM-PC 的基座模型,专注于预测和执行 GUI 操作,可应用于自动化交互任务
CogAgent-9B 是智谱AI基于 GLM-4V-9B 训练的专用Agent任务模型,支持高分辨率图像处理和双语交互,能够预测并执行GUI操作,广泛应用于自动化任务。
36 12
CogAgent-9B:智谱 AI 开源 GLM-PC 的基座模型,专注于预测和执行 GUI 操作,可应用于自动化交互任务
|
13天前
|
人工智能
AniDoc:蚂蚁集团开源 2D 动画上色 AI 模型,基于视频扩散模型自动将草图序列转换成彩色动画,保持动画的连贯性
AniDoc 是一款基于视频扩散模型的 2D 动画上色 AI 模型,能够自动将草图序列转换为彩色动画。该模型通过对应匹配技术和背景增强策略,实现了色彩和风格的准确传递,适用于动画制作、游戏开发和数字艺术创作等多个领域。
83 16
AniDoc:蚂蚁集团开源 2D 动画上色 AI 模型,基于视频扩散模型自动将草图序列转换成彩色动画,保持动画的连贯性
|
23天前
|
人工智能 安全 测试技术
EXAONE 3.5:LG 推出的开源 AI 模型,采用 RAG 和多步推理能力降低模型的幻觉问题
EXAONE 3.5 是 LG AI 研究院推出的开源 AI 模型,擅长长文本处理,能够有效降低模型幻觉问题。该模型提供 24 亿、78 亿和 320 亿参数的三个版本,支持多步推理和检索增强生成技术,适用于多种应用场景。
75 9
EXAONE 3.5:LG 推出的开源 AI 模型,采用 RAG 和多步推理能力降低模型的幻觉问题
|
25天前
|
机器学习/深度学习 人工智能
SNOOPI:创新 AI 文本到图像生成框架,提升单步扩散模型的效率和性能
SNOOPI是一个创新的AI文本到图像生成框架,通过增强单步扩散模型的指导,显著提升模型性能和控制力。该框架包括PG-SB和NASA两种技术,分别用于增强训练稳定性和整合负面提示。SNOOPI在多个评估指标上超越基线模型,尤其在HPSv2得分达到31.08,成为单步扩散模型的新标杆。
66 10
SNOOPI:创新 AI 文本到图像生成框架,提升单步扩散模型的效率和性能
|
25天前
|
人工智能 搜索推荐 开发者
Aurora:xAI 为 Grok AI 推出新的图像生成模型,xAI Premium 用户可无限制访问
Aurora是xAI为Grok AI助手推出的新图像生成模型,专注于生成高逼真度的图像,特别是在人物和风景图像方面。该模型支持文本到图像的生成,并能处理包括公共人物和版权形象在内的多种图像生成请求。Aurora的可用性因用户等级而异,免费用户每天能生成三张图像,而Premium用户则可享受无限制访问。
63 11
Aurora:xAI 为 Grok AI 推出新的图像生成模型,xAI Premium 用户可无限制访问
|
8天前
|
人工智能 自然语言处理 机器人
OpenAI推出具有图像上传和分析功能的完整o1模型,并首次推出ChatGPT Pro
OpenAI推出具有图像上传和分析功能的完整o1模型,并首次推出ChatGPT Pro
|
18天前
|
人工智能 自然语言处理 物联网
AI Safeguard联合 CMU,斯坦福提出端侧多模态小模型
随着人工智能的快速发展,多模态大模型(MLLMs)在计算机视觉、自然语言处理和多模态任务中扮演着重要角色。
|
6天前
|
机器学习/深度学习 人工智能 自动驾驶
企业内训|AI大模型在汽车行业的前沿应用研修-某汽车集团
本课程是TsingtaoAI为某汽车集团高级项目经理设计研发,课程全面系统地解析AI的发展历程、技术基础及其在汽车行业的深度应用。通过深入浅出的理论讲解、丰富的行业案例分析以及实战项目训练,学员将全面掌握机器学习、深度学习、NLP与CV等核心技术,了解自动驾驶、智能制造、车联网与智能营销等关键应用场景,洞悉AI技术对企业战略布局的深远影响。
135 97
|
11天前
|
机器学习/深度学习 人工智能 物联网
AI赋能大学计划·大模型技术与应用实战学生训练营——湖南大学站圆满结营
12月14日,由中国软件行业校园招聘与实习公共服务平台携手魔搭社区共同举办的AI赋能大学计划·大模型技术与产业趋势高校行AIGC项目实战营·湖南大学站圆满结营。
AI赋能大学计划·大模型技术与应用实战学生训练营——湖南大学站圆满结营
|
18天前
|
机器学习/深度学习 人工智能 算法
探索AI在医疗诊断中的应用与挑战
【10月更文挑战第21天】 本文深入探讨了人工智能(AI)技术在医疗诊断领域的应用现状与面临的挑战,旨在为读者提供一个全面的视角,了解AI如何改变传统医疗模式,以及这一变革过程中所伴随的技术、伦理和法律问题。通过分析AI技术的优势和局限性,本文旨在促进对AI在医疗领域应用的更深层次理解和讨论。
105 31

热门文章

最新文章