矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 1408|回复: 9

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

[复制链接]
     
发表于 2025-2-18 11:51:25 | 显示全部楼层 |阅读模式
以下是一个基于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[4];
    unsigned long N;

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

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

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

/****************** 频率显示函数 ******************/
void DisplayFrequency() {
    char buf[16];
    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的输出的全文。
     
发表于 2025-2-18 14:58:02 | 显示全部楼层
让Deepseek写还不如让豆包写
回复 支持 0 反对 1

使用道具 举报

发表于 2025-2-18 19:17:34 | 显示全部楼层
本帖最后由 girlexplorer 于 2025-2-18 19:34 编辑

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

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

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

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

回复 支持 反对

使用道具 举报

     
发表于 2025-2-18 20:18:07 来自手机 | 显示全部楼层
随便一眼就有逻辑错误:MHz 打印的时候,数值比率换算有误
回复 支持 反对

使用道具 举报

     
发表于 2025-2-18 20:58:29 | 显示全部楼层
本帖最后由 杨白劳 于 2025-2-18 21:03 编辑

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

使用道具 举报

     
 楼主| 发表于 2025-2-19 09:03:35 | 显示全部楼层
t3486784401 发表于 2025-2-18 20:18
随便一眼就有逻辑错误:MHz 打印的时候,数值比率换算有误

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

使用道具 举报

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

这就好比自动驾驶,达不到 L5 就不能说让司机全下岗
回复 支持 反对

使用道具 举报

     
发表于 2025-2-20 21:54:01 | 显示全部楼层
提示: 该帖被管理员或版主屏蔽
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 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[6];
            sprintf(am_freq, "%04dKHz", frequency);
            lcd_string(am_freq);
        }
        else
        {
            lcd_string("FM ");
            char fm_freq[6];
            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;
}

回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2025-2-20 22:54:13 | 显示全部楼层
提示: 该帖被管理员或版主屏蔽
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-26 07:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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