66718 发表于 2025-2-18 11:51:25

编程门外汉,让Deepseek帮忙写了一个89C52+LC72131的收音控制程序,不知能不能跑起来

以下是一个基于89C52控制LC72131和LCD1602的AM/FM收音机控制程序框架,需要根据实际硬件连接调整引脚定义和时序参数:

```c
#include <reg52.h>
#include <intrins.h>

/****************** 硬件引脚定义 ******************/
// LC72131控制引脚
sbit LC72131_CLK = P1^0;
sbit LC72131_DATA = P1^1;
sbit LC72131_CE = P1^2;

// LCD1602控制引脚
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
#define LCD_DATA P3

/****************** 全局变量定义 ******************/
unsigned long current_freq = 87500;// 默认FM频率87.5MHz
bit band = 0;// 0=FM, 1=AM

/****************** LCD1602驱动函数 ******************/
void LCD_Delay(unsigned int t) {
    while(t--);
}

void LCD_WriteCmd(unsigned char cmd) {
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_DATA = cmd;
    LCD_EN = 1;
    _nop_();
    LCD_EN = 0;
    LCD_Delay(1000);
}

void LCD_WriteData(unsigned char dat) {
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_DATA = dat;
    LCD_EN = 1;
    _nop_();
    LCD_EN = 0;
    LCD_Delay(1000);
}

void LCD_Init() {
    LCD_WriteCmd(0x38);// 8位模式,2行显示
    LCD_WriteCmd(0x0C);// 显示开,光标关
    LCD_WriteCmd(0x06);// 地址自动增加
    LCD_WriteCmd(0x01);// 清屏
}

void LCD_ShowStr(unsigned char x, unsigned char y, char *str) {
    if(y == 0) LCD_WriteCmd(0x80 + x);
    else LCD_WriteCmd(0xC0 + x);
    while(*str) {
      LCD_WriteData(*str++);
    }
}

/****************** LC72131驱动函数 ******************/
void LC72131_Delay() {
    unsigned char i = 5;
    while(i--);
}

void LC72131_WriteByte(unsigned char dat) {
    unsigned char i;
    for(i=0; i<8; i++) {
      LC72131_CLK = 0;
      LC72131_DATA = (dat & 0x80) ? 1 : 0;
      LC72131_Delay();
      LC72131_CLK = 1;
      dat <<= 1;
      LC72131_Delay();
    }
}

void LC72131_SetFreq(unsigned long freq) {
    unsigned char i;
    unsigned char config;
    unsigned long N;

    if(!band) { // FM模式
      N = (freq * 1000) / 50; // 假设参考频率50kHz
    } else {    // AM模式
      N = freq / 9;         // 假设参考频率9kHz
    }

    config = 0x80; // 控制寄存器地址
    config = 0x00; // FM模式配置(根据手册调整)
    config = (N >> 8) & 0xFF; // N值高位
    config = N & 0xFF;      // N值低位

    LC72131_CE = 1;
    for(i=0; i<4; i++) {
      LC72131_WriteByte(config);
    }
    LC72131_CE = 0;
}

/****************** 频率显示函数 ******************/
void DisplayFrequency() {
    char buf;
    if(!band) { // FM显示
      sprintf(buf, "FM:%3d.%1dMHz",
               (unsigned int)(current_freq/100),
               (unsigned int)(current_freq%100)/10);
    } else {    // AM显示
      sprintf(buf, "AM:%4dkHz", (unsigned int)current_freq);
    }
    LCD_ShowStr(0, 0, buf);
}

/****************** 主函数 ******************/
void main() {
    // 初始化
    LCD_Init();
    LC72131_CE = 0;
   
    // 设置初始频率
    LC72131_SetFreq(current_freq);
   
    while(1) {
      DisplayFrequency();
      // 此处可添加按键扫描和频率调整逻辑
      // 示例:按需调用LC72131_SetFreq()更新频率
    }
}
```

注意事项:
1. 需要根据实际电路连接修改引脚定义
2. LC72131的配置参数(参考频率、分频比等)需要根据具体电路设计调整
3. 需要添加按键扫描逻辑实现频率调整和波段切换
4. 需要根据LC72131数据手册完善寄存器配置参数
5. 频率计算部分需要根据实际使用的参考频率和分频比进行修改

建议进一步开发步骤:
1. 添加按键扫描函数实现频率加减操作
2. 增加波段切换功能
3. 添加信号强度检测显示
4. 增加自动搜台功能
5. 添加存储电台功能

实际使用时需要根据LC72131数据手册和具体硬件设计调整寄存器配置参数和频率计算方法。


以上是完全粘贴Deepseek的输出的全文。

JuncoJet 发表于 2025-2-18 14:58:02

让Deepseek写还不如让豆包写

girlexplorer 发表于 2025-2-18 19:17:34

本帖最后由 girlexplorer 于 2025-2-18 19:34 编辑

看样子,即使AI的编程超级神勇,仍无法取代人工。

因为只有人工的水平比AI高,才能检查出AI程序是否正确。而且,如果代码数量上万,检查出别人程序的错误,比自己写还难。

几十行程序还行,大型软件几百万行,几十人协同开发。

Windows的做法最好,程序组件开发好了后就不动,不改、不删、不加,保证各种前后几十年的程序兼容性。能用的就继续用,不用重新写。

t3486784401 发表于 2025-2-18 20:18:07

随便一眼就有逻辑错误:MHz 打印的时候,数值比率换算有误

杨白劳 发表于 2025-2-18 20:58:29

本帖最后由 杨白劳 于 2025-2-18 21:03 编辑

正好路过,呵呵,就这么几句代码能用就见鬼了:lol我的72131和1602代码光是旋转编码器指令行都比这个多

66718 发表于 2025-2-19 09:03:35

t3486784401 发表于 2025-2-18 20:18
随便一眼就有逻辑错误:MHz 打印的时候,数值比率换算有误

这个程序是不能真正运行的,DeepSeek在最后面已经有提示了,LC72131的频率算法,它并没有写进去。
还有按键等等功能都没写。
只是感叹于,随着人工智能的发展,程序员的大部分工作,会被AI替代。

t3486784401 发表于 2025-2-19 14:36:22

66718 发表于 2025-2-19 09:03
这个程序是不能真正运行的,DeepSeek在最后面已经有提示了,LC72131的频率算法,它并没有写进去。
还有 ...

这就好比自动驾驶,达不到 L5 就不能说让司机全下岗

杨白劳 发表于 2025-2-20 21:54:01

66718 发表于 2025-2-20 22:37:31

让豆包也写了一个,看看哪个更完善?
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>

// LC72131控制引脚定义
sbit SCK = P1^0;// 串行时钟
sbit SDA = P1^1;// 串行数据
sbit CS = P1^2;   // 片选信号

// LCD1602控制引脚定义
sbit RS = P2^0;
sbit RW = P2^1;
sbit E= P2^2;
#define LCD_DATA P0

// 旋转编码器引脚定义
sbit ENC_A = P3^2;
sbit ENC_B = P3^3;

// 按键引脚定义
sbit BAND_SWITCH = P3^4;// 波段切换按键

// 其他全局变量定义
unsigned char band = 0;// 0: AM, 1: FM
unsigned int frequency = 530;// AM初始频率530kHz, FM初始频率8750 (87.50MHz)
bit enc_flag = 0;// 旋转编码器标志位

// 函数声明
void delay(unsigned int ms);
void lcd_command(unsigned char cmd);
void lcd_data(unsigned char dat);
void lcd_init();
void lcd_string(char *str);
void write_lc72131(unsigned char addr, unsigned char data);
unsigned char read_lc72131(unsigned char addr);
void set_frequency(unsigned int freq);
void enc_interrupt();

void main()
{
    lcd_init();
    // 初始化LC72131
    CS = 1;
    // 初始化旋转编码器中断
    IT0 = 1;// 下降沿触发
    EX0 = 1;// 使能外部中断0
    EA = 1;   // 使能总中断

    while (1)
    {
      if (enc_flag)
      {
            enc_flag = 0;
            // 处理旋转编码器调整频率
            if (ENC_A == 1)// 假设顺时针旋转
            {
                if (band == 0)// AM波段
                {
                  frequency += 10;// AM频率步进10kHz
                  if (frequency > 1610) frequency = 1610;// AM频率上限
                }
                else// FM波段
                {
                  frequency += 100;// FM频率步进100kHz
                  if (frequency > 10800) frequency = 10800;// FM频率上限
                }
            }
            else// 逆时针旋转
            {
                if (band == 0)// AM波段
                {
                  frequency -= 10;// AM频率步进10kHz
                  if (frequency < 530) frequency = 530;// AM频率下限
                }
                else// FM波段
                {
                  frequency -= 100;// FM频率步进100kHz
                  if (frequency < 8750) frequency = 8750;// FM频率下限
                }
            }
            set_frequency(frequency);
      }

      if (BAND_SWITCH == 0)// 检测波段切换按键
      {
            delay(20);// 消抖
            if (BAND_SWITCH == 0)
            {
                band = ~band;// 切换波段
                if (band == 0)
                {
                  frequency = 530;// AM初始频率
                }
                else
                {
                  frequency = 8750;// FM初始频率
                }
                set_frequency(frequency);
                while (!BAND_SWITCH);// 等待按键释放
            }
      }

      // 显示频率和波段信息到LCD1602
      lcd_command(0x80);// 第一行起始位置
      lcd_string("Freq: ");
      if (band == 0)
      {
            lcd_string("AM ");
            char am_freq;
            sprintf(am_freq, "%04dKHz", frequency);
            lcd_string(am_freq);
      }
      else
      {
            lcd_string("FM ");
            char fm_freq;
            sprintf(fm_freq, "%02d.%02dMHz", frequency / 100, frequency % 100);
            lcd_string(fm_freq);
      }
    }
}

// 延时函数
void delay(unsigned int ms)
{
    unsigned int i, j;
    for (i = 0; i < ms; i++)
      for (j = 0; j < 123; j++);
}

// LCD1602写命令函数
void lcd_command(unsigned char cmd)
{
    RS = 0;
    RW = 0;
    LCD_DATA = cmd;
    E = 1;
    _nop_();
    _nop_();
    E = 0;
    delay(2);
}

// LCD1602写数据函数
void lcd_data(unsigned char dat)
{
    RS = 1;
    RW = 0;
    LCD_DATA = dat;
    E = 1;
    _nop_();
    _nop_();
    E = 0;
    delay(2);
}

// LCD1602初始化函数
void lcd_init()
{
    lcd_command(0x38);// 8位模式,2行显示,5x7字体
    delay(5);
    lcd_command(0x38);
    delay(5);
    lcd_command(0x38);
    delay(5);
    lcd_command(0x0C);// 显示开,光标关,闪烁关
    delay(5);
    lcd_command(0x06);// 光标右移,字符不移
    delay(5);
    lcd_command(0x01);// 清屏
    delay(5);
}

// LCD1602显示字符串函数
void lcd_string(char *str)
{
    while (*str)
    {
      lcd_data(*str++);
    }
}

// 向LC72131写数据函数
void write_lc72131(unsigned char addr, unsigned char data)
{
    unsigned char i;
    CS = 0;
    for (i = 0; i < 8; i++)
    {
      SCK = 0;
      SDA = addr & 0x80;
      addr <<= 1;
      SCK = 1;
    }
    for (i = 0; i < 8; i++)
    {
      SCK = 0;
      SDA = data & 0x80;
      data <<= 1;
      SCK = 1;
    }
    CS = 1;
}

// 从LC72131读数据函数
unsigned char read_lc72131(unsigned char addr)
{
    unsigned char i, data = 0;
    CS = 0;
    for (i = 0; i < 8; i++)
    {
      SCK = 0;
      SDA = addr & 0x80;
      addr <<= 1;
      SCK = 1;
    }
    for (i = 0; i < 8; i++)
    {
      SCK = 0;
      SDA = 1;// 释放数据线准备读
      _nop_();
      _nop_();
      if (SDA) data |= 0x01;
      if (i < 7) data <<= 1;
      SCK = 1;
    }
    CS = 1;
    return data;
}

// 设置LC72131的频率函数
void set_frequency(unsigned int freq)
{
    unsigned char data;
    if (band == 0)// AM
    {
      // 根据LC72131的AM频率设置方法计算并写入数据
      // 这里假设LC72131的频率设置寄存器为0x01
      data = (freq - 530) / 10;// 简单计算频率对应的寄存器值
      write_lc72131(0x01, data);
    }
    else// FM
    {
      // 根据LC72131的FM频率设置方法计算并写入数据
      // 这里假设LC72131的频率设置寄存器为0x02
      data = (freq - 8750) / 100;// 简单计算频率对应的寄存器值
      write_lc72131(0x02, data);
    }
}

// 旋转编码器中断服务函数
void enc_interrupt() interrupt 0
{
    enc_flag = 1;
}

66718 发表于 2025-2-20 22:54:13

页: [1]
查看完整版本: 编程门外汉,让Deepseek帮忙写了一个89C52+LC72131的收音控制程序,不知能不能跑起来