数码之家

 找回密码
 立即注册
搜索
查看: 2016|回复: 25

[C51] 不会写代码的老菜鸟,用deepseek折腾了几天程序,终于完成了一个小制作。

[复制链接]
发表于 2025-2-23 16:29:50 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 hbliwww 于 2025-2-23 16:36 编辑

最近deepseek火得不行,就试下用它写代码。手上现成有STC8G1K08的单片机,有TM1637驱动的数码管,就折腾一个定时器吧,deepseek写出来的代码,不是显示问题就是按键不好用,反复让它修改,最后还简化要求,总算搞了一个基本能用的程序出来。下面是完整程序和使用方法:


1:上电显示"--:--",继电器关闭

2:短按模式键 → 显示"00:00"(冒号常亮),进入暂停模式

3:短按加键 → 分钟+1(如01:00),秒保持00

4:短按模式键 → 开始倒计时(冒号闪烁),继电器开启

5:再次短按模式键 → 暂停倒计时(冒号常亮),继电器关闭

6:倒计时结束 → 自动返回"--:--"初始状态


程序如下:


#include <STC8G.H>
#include <intrins.h>

#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long

sbit DIO = P3^2;
sbit CLK = P3^3;
sbit KEY_MODE = P3^1;
sbit KEY_ADD = P3^0;
sbit RELAY = P5^4;

// TM1637命令定义
#define CMD_SET_DATA 0x40
#define CMD_SET_ADDR 0xC0
#define CMD_SET_DISPLAY 0x88

// 状态机定义
enum {MODE_IDLE, MODE_RUNNING, MODE_PAUSE};
u8 sysMode = MODE_IDLE;
bit colonBlink = 0;
u8 timeMinutes = 0, timeSeconds = 0;
u16 timerCount = 0;
u8 blinkCount = 0;

// 按键状态机
typedef struct {
    u8 cnt;
    u8 state;
} KeyState;
KeyState keyMode = {0, 0};
KeyState keyAdd = {0, 0};

// 数码管段码表(0-9,-,空格)
code u8 segTable[] = {
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,
    0x40,0x00 // 最后两位分别是'-'和空格
};

void delay_us(u8 us) {
    while (us--) _nop_(),_nop_(),_nop_(),_nop_();
}

void TM1637_Start() {
    DIO = 1; CLK = 1; delay_us(5);
    DIO = 0; CLK = 0; delay_us(5);
}

void TM1637_Stop() {
    CLK = 0; delay_us(5); DIO = 0; delay_us(5);
    CLK = 1; delay_us(5); DIO = 1; delay_us(5);
}

void TM1637_WriteByte(u8 dat) {
    unsigned char        i;
    for(i=0; i<8; i++) {
        CLK = 0; delay_us(5);
        DIO = (dat & 0x01);
        dat >>= 1;
                          delay_us(2);
        CLK = 1; delay_us(2);
    }
    CLK = 0;
                delay_us(2);
                CLK = 1;
                delay_us(2);
}

void displayTime() {
                unsigned char        i;
    u8 segData[4];
    u8 showColon = (blinkCount < 100) && colonBlink;

    // 根据模式显示内容
    if(sysMode == MODE_IDLE) {
        segData[0] = 0x40;  // '-'
        segData[1] = 0x40;
        segData[2] = 0x40 | (0<<7); // 固定冒号
        segData[3] = 0x40;
    } else {
        segData[0] = segTable[timeMinutes/10];
        segData[1] = segTable[timeMinutes%10]|((sysMode==MODE_RUNNING)?(showColon<<7):(1<<7));
        segData[2] = segTable[timeSeconds/10];
        segData[3] = segTable[timeSeconds%10];
    }

    TM1637_Start();
    TM1637_WriteByte(CMD_SET_DATA);
    TM1637_Stop();

    TM1637_Start();
    TM1637_WriteByte(CMD_SET_ADDR);
    for(i=0; i<4; i++) TM1637_WriteByte(segData);
    TM1637_Stop();

    TM1637_Start();
    TM1637_WriteByte(CMD_SET_DISPLAY | 0x02);
    TM1637_Stop();
}

void timer0Init() {
    AUXR |= 0x80; // 1T模式
    TMOD &= 0xF0;
    TL0 = 0xCD;    // 1ms@11.0592MHz
    TH0 = 0xD4;
    TR0 = 1;
    ET0 = 1;
    EA = 1;
}

void keyProcess() {
    // 模式键处理
    if(!KEY_MODE) {
        if(++keyMode.cnt > 10) {
            keyMode.cnt = 10;
            if(keyMode.state == 0) {
                keyMode.state = 1;
                switch(sysMode) {
                    case MODE_IDLE: // 进入暂停模式(初始00:00)
                        sysMode = MODE_PAUSE;
                        timeMinutes = 0;
                        timeSeconds = 0;
                        colonBlink = 0;
                        RELAY = 0;
                        break;
                    case MODE_RUNNING: // 进入暂停
                        sysMode = MODE_PAUSE;
                        colonBlink = 0;
                        RELAY = 0;
                        break;
                    case MODE_PAUSE: // 开始运行
                        if(timeMinutes > 0 || timeSeconds > 0) {
                            sysMode = MODE_RUNNING;
                            colonBlink = 1;
                            RELAY = 1;
                        }
                        break;
                }
            }
        }
    } else {
        keyMode.cnt = 0;
        keyMode.state = 0;
    }

    // 加键处理(仅在暂停有效)
    if(!KEY_ADD && sysMode == MODE_PAUSE) {
        if(++keyAdd.cnt > 10) {
            keyAdd.cnt = 10;
            if(keyAdd.state == 0) {
                keyAdd.state = 1;
                if(timeMinutes < 59) {
                    timeMinutes++;
                    timeSeconds = 0; // 秒数始终重置为0
                }
            }
        }
    } else {
        keyAdd.cnt = 0;
        keyAdd.state = 0;
    }
}

void main() {
    P3M0 = 0x00; P3M1 = 0x00;
    P5M0 = 0x20; P5M1 = 0x00;
    RELAY = 0;

    timer0Init();
    while(1) {
        displayTime();
        keyProcess();
    }
}

void timer0_isr() interrupt 1 {
    timerCount++;
    blinkCount++;

    // 1ms时基处理
    if(timerCount >= 1000) { // 1秒
        timerCount = 0;
        if(sysMode == MODE_RUNNING) {
            if(timeSeconds == 0) {
                if(timeMinutes == 0) { // 倒计时结束
                    sysMode = MODE_IDLE;
                    colonBlink = 0;
                    RELAY = 0;
                } else {
                    timeMinutes--;
                    timeSeconds = 59;
                }
            } else {
                timeSeconds--;
            }
        }
    }

    // 冒号闪烁控制(0.5Hz)
    if(blinkCount >= 1000) blinkCount = 0;
}


对于会编程的人来说,这是小菜一碟。但只会玩玩硬件的人,就非常吃力了。目前程序还有一个小问题,就是冒号闪烁得太快,程序也还有改进的地方,比如,长按加键快速增加,长按模式键切换到正计时状态,想玩的,让deepseek去折腾。@_@

打赏

参与人数 2家元 +27 收起 理由
jf201006 + 12 謝謝分享
vip2128 + 15

查看全部打赏

发表于 2025-2-23 16:54:34 | 显示全部楼层
个人看法,DS顶多解决70%的问题。
回复 支持 反对

使用道具 举报

发表于 2025-2-23 16:59:42 | 显示全部楼层
不得不服deepseek之类人工智能帮我等普通人做了很多以前想都想不到的事情
回复 支持 1 反对 0

使用道具 举报

发表于 2025-2-23 17:49:13 | 显示全部楼层
不知道DS抄的是谁的程序。
回复 支持 反对

使用道具 举报

发表于 2025-2-23 19:40:08 | 显示全部楼层
我也不会编程,想搞也得靠AI了
回复 支持 反对

使用道具 举报

发表于 2025-2-23 21:55:09 | 显示全部楼层
有时候AI也会出错吧
回复 支持 反对

使用道具 举报

发表于 2025-2-23 23:20:30 来自手机浏览器 | 显示全部楼层
不错,我最近在做进销存,也是用deepseeke写的代码,出错的地方自己改,改完运行,出错再找deepseek改,最后让deepseek再检查,目前要没运行
回复 支持 反对

使用道具 举报

发表于 2025-2-23 23:35:36 来自手机浏览器 | 显示全部楼层
新的编程方式
回复 支持 反对

使用道具 举报

发表于 2025-2-24 11:11:09 | 显示全部楼层
抖音里看到说另外一个AI工具做程序更好,不过是收费的。不知道是不是真的
回复 支持 反对

使用道具 举报

发表于 2025-2-24 20:27:13 | 显示全部楼层
目前这些AI能辅助编程,但是需要人去修改、调试,即使这样我也很满意了,至少不需要自己记忆那么多类和方法了。
回复 支持 反对

使用道具 举报

发表于 2025-2-25 15:46:17 | 显示全部楼层
知道怎么问才是最重要的,AI只能提供参考,重要的还是人,要知道整合AI的回答
回复 支持 反对

使用道具 举报

发表于 2025-2-27 17:06:35 | 显示全部楼层
我用Cursor写代码真的很好用,基本解决我80%工作量.
回复 支持 反对

使用道具 举报

发表于 2025-2-27 20:12:57 | 显示全部楼层
请问楼主是否需要先给DeepSeek提供具体的硬件电路图?至少电路图能用来确定单片机各引脚的接法和功能吧,不然给定的条件有点不足,DeepSeek该如何下手呢?还有按键不好用的问题,是不是没叫DeepSeek对按键进行消抖处理?(俺也不懂,瞎说的哈)
回复 支持 反对

使用道具 举报

发表于 2025-2-28 08:07:18 | 显示全部楼层
lht 发表于 2025-2-27 20:12
请问楼主是否需要先给DeepSeek提供具体的硬件电路图?至少电路图能用来确定单片机各引脚的接法和功能吧,不 ...

MCU可以直接用文字描述IO,类似于P32是IIO数据接口,P33是IIO时钟接口,这样让它写IIC通讯就能适配.按键消抖就更简洁了一句话,类似P31是KEY_MODE按键需要消除抖动.
回复 支持 反对

使用道具 举报

发表于 2025-2-28 13:03:31 | 显示全部楼层
还有Trae
boltnew更好,直接在网站上生成所有文件。
https://bolt.new/?rid=4u1c8l
能免费用到最新的Claude 3.7 Sonnet编程。
回复 支持 反对

使用道具 举报

发表于 2025-2-28 13:07:40 | 显示全部楼层
  1. #include <STC8G.h>
  2. #include <intrins.h>

  3. // Define pins for TM1637
  4. #define TM1637_CLK P1_0
  5. #define TM1637_DIO P1_1

  6. // Define pins for buttons
  7. #define MODE_BTN P1_2
  8. #define ADD_BTN P1_3

  9. // Define relay pin
  10. #define RELAY P1_4

  11. // TM1637 commands
  12. #define ADDR_AUTO 0x40
  13. #define ADDR_FIXED 0x44
  14. #define DISPLAY_ON 0x88
  15. #define STARTADDR 0xC0

  16. // Display state
  17. #define STATE_INIT 0
  18. #define STATE_PAUSE 1
  19. #define STATE_COUNTDOWN 2

  20. // Global variables
  21. unsigned char currentState = STATE_INIT;
  22. unsigned char minutes = 0;
  23. unsigned char seconds = 0;
  24. bit colonState = 1;
  25. unsigned int timerCounter = 0;
  26. bit buttonDebounce = 0;

  27. // Function prototypes
  28. void delay_ms(unsigned int ms);
  29. void TM1637_start(void);
  30. void TM1637_stop(void);
  31. void TM1637_write_byte(unsigned char b);
  32. void TM1637_display(unsigned char* digits, bit colon);
  33. void display_init(void);
  34. void display_time(unsigned char min, unsigned char sec, bit colon);
  35. void init_timer0(void);
  36. void check_buttons(void);

  37. // Main function
  38. void main(void)
  39. {
  40.     // Initialize system
  41.     P1M0 = 0x00;  // Set P1 as quasi-bidirectional mode
  42.     P1M1 = 0x00;
  43.    
  44.     // Initialize relay (off)
  45.     RELAY = 0;
  46.    
  47.     // Initialize display
  48.     display_init();
  49.    
  50.     // Initialize timer
  51.     init_timer0();
  52.    
  53.     // Enable global interrupts
  54.     EA = 1;
  55.    
  56.     while(1)
  57.     {
  58.         check_buttons();
  59.         
  60.         // State machine
  61.         switch(currentState)
  62.         {
  63.             case STATE_INIT:
  64.                 // Display "--:--"
  65.                 {
  66.                     unsigned char digits[4] = {0x40, 0x40, 0x40, 0x40}; // Segments for "-"
  67.                     TM1637_display(digits, 1);
  68.                 }
  69.                 break;
  70.                
  71.             case STATE_PAUSE:
  72.                 // Display time with colon on
  73.                 display_time(minutes, seconds, 1);
  74.                 break;
  75.                
  76.             case STATE_COUNTDOWN:
  77.                 // Display time with blinking colon
  78.                 display_time(minutes, seconds, colonState);
  79.                 break;
  80.         }
  81.     }
  82. }

  83. // Delay function
  84. void delay_ms(unsigned int ms)
  85. {
  86.     unsigned int i, j;
  87.     for(i = 0; i < ms; i++)
  88.         for(j = 0; j < 110; j++); // Adjust for STC8G at typical clock
  89. }

  90. // TM1637 communication functions
  91. void TM1637_start(void)
  92. {
  93.     TM1637_CLK = 1;
  94.     TM1637_DIO = 1;
  95.     delay_ms(1);
  96.     TM1637_DIO = 0;
  97.     delay_ms(1);
  98.     TM1637_CLK = 0;
  99.     delay_ms(1);
  100. }

  101. void TM1637_stop(void)
  102. {
  103.     TM1637_CLK = 0;
  104.     delay_ms(1);
  105.     TM1637_DIO = 0;
  106.     delay_ms(1);
  107.     TM1637_CLK = 1;
  108.     delay_ms(1);
  109.     TM1637_DIO = 1;
  110.     delay_ms(1);
  111. }

  112. void TM1637_write_byte(unsigned char b)
  113. {
  114.     unsigned char i;
  115.     for(i = 0; i < 8; i++)
  116.     {
  117.         TM1637_CLK = 0;
  118.         delay_ms(1);
  119.         
  120.         if(b & 0x01)
  121.             TM1637_DIO = 1;
  122.         else
  123.             TM1637_DIO = 0;
  124.             
  125.         delay_ms(1);
  126.         TM1637_CLK = 1;
  127.         delay_ms(1);
  128.         b >>= 1;
  129.     }
  130.    
  131.     // Wait for ACK
  132.     TM1637_CLK = 0;
  133.     TM1637_DIO = 1;
  134.     delay_ms(1);
  135.     TM1637_CLK = 1;
  136.     delay_ms(1);
  137.    
  138.     // Read ACK (not used)
  139.     TM1637_CLK = 0;
  140.     delay_ms(1);
  141. }

  142. // Display functions
  143. void TM1637_display(unsigned char* digits, bit colon)
  144. {
  145.     unsigned char i;
  146.     unsigned char segData[4];
  147.    
  148.     // Segment data for 0-9
  149.     unsigned char digitToSegment[] = {
  150.         0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F
  151.     };
  152.    
  153.     // Convert digits to segment data
  154.     for(i = 0; i < 4; i++)
  155.     {
  156.         if(digits[i] <= 9)
  157.             segData[i] = digitToSegment[digits[i]];
  158.         else
  159.             segData[i] = digits[i]; // Direct segment data
  160.     }
  161.    
  162.     // Add colon if needed (on digit 1)
  163.     if(colon)
  164.         segData[1] |= 0x80;
  165.    
  166.     // Send data to display
  167.     TM1637_start();
  168.     TM1637_write_byte(ADDR_AUTO);
  169.     TM1637_stop();
  170.    
  171.     TM1637_start();
  172.     TM1637_write_byte(STARTADDR);
  173.    
  174.     for(i = 0; i < 4; i++)
  175.         TM1637_write_byte(segData[i]);
  176.         
  177.     TM1637_stop();
  178.    
  179.     TM1637_start();
  180.     TM1637_write_byte(DISPLAY_ON);
  181.     TM1637_stop();
  182. }

  183. void display_init(void)
  184. {
  185.     // Initialize display
  186.     TM1637_start();
  187.     TM1637_write_byte(DISPLAY_ON);
  188.     TM1637_stop();
  189.    
  190.     // Display "--:--"
  191.     unsigned char digits[4] = {0x40, 0x40, 0x40, 0x40}; // Segments for "-"
  192.     TM1637_display(digits, 1);
  193. }

  194. void display_time(unsigned char min, unsigned char sec, bit colon)
  195. {
  196.     unsigned char digits[4];
  197.    
  198.     // Convert minutes and seconds to digits
  199.     digits[0] = min / 10;
  200.     digits[1] = min % 10;
  201.     digits[2] = sec / 10;
  202.     digits[3] = sec % 10;
  203.    
  204.     TM1637_display(digits, colon);
  205. }

  206. // Timer initialization
  207. void init_timer0(void)
  208. {
  209.     // Configure Timer0 for 10ms interrupts
  210.     TMOD &= 0xF0;    // Clear Timer0 mode bits
  211.     TMOD |= 0x01;    // Set Timer0 to mode 1 (16-bit timer)
  212.     TH0 = 0xDC;      // Initial value for 10ms at 11.0592MHz
  213.     TL0 = 0x00;
  214.     TR0 = 1;         // Start Timer0
  215.     ET0 = 1;         // Enable Timer0 interrupt
  216. }

  217. // Button handling
  218. void check_buttons(void)
  219. {
  220.     // Debounce protection
  221.     if(buttonDebounce)
  222.         return;
  223.         
  224.     // Check mode button
  225.     if(MODE_BTN == 0)
  226.     {
  227.         delay_ms(20);  // Debounce
  228.         if(MODE_BTN == 0)
  229.         {
  230.             buttonDebounce = 1;
  231.             
  232.             switch(currentState)
  233.             {
  234.                 case STATE_INIT:
  235.                     // Change to pause state
  236.                     currentState = STATE_PAUSE;
  237.                     minutes = 0;
  238.                     seconds = 0;
  239.                     break;
  240.                     
  241.                 case STATE_PAUSE:
  242.                     // Start countdown
  243.                     currentState = STATE_COUNTDOWN;
  244.                     RELAY = 1;  // Turn on relay
  245.                     break;
  246.                     
  247.                 case STATE_COUNTDOWN:
  248.                     // Pause countdown
  249.                     currentState = STATE_PAUSE;
  250.                     RELAY = 0;  // Turn off relay
  251.                     break;
  252.             }
  253.             
  254.             // Wait for button release
  255.             while(MODE_BTN == 0);
  256.             delay_ms(20);  // Debounce
  257.         }
  258.     }
  259.    
  260.     // Check add button (only in pause state)
  261.     if(ADD_BTN == 0 && currentState == STATE_PAUSE)
  262.     {
  263.         delay_ms(20);  // Debounce
  264.         if(ADD_BTN == 0)
  265.         {
  266.             buttonDebounce = 1;
  267.             
  268.             // Increment minutes
  269.             minutes++;
  270.             if(minutes > 99)
  271.                 minutes = 0;
  272.                
  273.             // Wait for button release
  274.             while(ADD_BTN == 0);
  275.             delay_ms(20);  // Debounce
  276.         }
  277.     }
  278. }

  279. // Timer0 interrupt service routine
  280. void timer0_isr() interrupt 1
  281. {
  282.     // Reload timer
  283.     TH0 = 0xDC;
  284.     TL0 = 0x00;
  285.    
  286.     // Increment counter (100 * 10ms = 1 second)
  287.     timerCounter++;
  288.    
  289.     // Toggle colon every 500ms in countdown mode
  290.     if(timerCounter % 50 == 0 && currentState == STATE_COUNTDOWN)
  291.         colonState = !colonState;
  292.    
  293.     // Update time every second in countdown mode
  294.     if(timerCounter >= 100 && currentState == STATE_COUNTDOWN)
  295.     {
  296.         timerCounter = 0;
  297.         
  298.         // Decrement seconds
  299.         if(seconds > 0)
  300.         {
  301.             seconds--;
  302.         }
  303.         else
  304.         {
  305.             if(minutes > 0)
  306.             {
  307.                 minutes--;
  308.                 seconds = 59;
  309.             }
  310.             else
  311.             {
  312.                 // Timer finished
  313.                 currentState = STATE_INIT;
  314.                 RELAY = 0;  // Turn off relay
  315.             }
  316.         }
  317.     }
  318.    
  319.     // Reset button debounce flag after 50ms
  320.     if(buttonDebounce && timerCounter % 5 == 0)
  321.         buttonDebounce = 0;
  322. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2025-3-6 20:37:38 | 显示全部楼层
我也不会编程,想搞也得靠AI了
回复 支持 反对

使用道具 举报

发表于 2025-3-7 18:13:27 | 显示全部楼层
wblqx 发表于 2025-2-23 16:54
个人看法,DS顶多解决70%的问题。

主要是问题的提法,提问到位一次就能成功。不要小瞧这玩意的狠劲,码农觉得天都要塌了,主要是她还会各种复杂的算法。
回复 支持 反对

使用道具 举报

发表于 2025-3-7 18:14:53 | 显示全部楼层
mmxx2015 发表于 2025-2-23 17:49
不知道DS抄的是谁的程序。

抄个鬼,别人自己学习的。这个坛子的所有帖子他都学习了
回复 支持 反对

使用道具 举报

发表于 2025-3-7 18:21:32 | 显示全部楼层
lht 发表于 2025-2-27 20:12
请问楼主是否需要先给DeepSeek提供具体的硬件电路图?至少电路图能用来确定单片机各引脚的接法和功能吧,不 ...

上个月丢了张这坛子的一张mppt模拟电路图给她了,几秒钟就分析出来这是个mppt电路,且还能分析工作点。单片机的没有试验,反正丢个芯片型号给她她知道是干嘛,这功能超级好,免得满世界找pdf资料了
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-9 01:37 , Processed in 0.109200 second(s), 10 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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