|

楼主 |
发表于 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;
}
|
|