- 积分
- 67
- 在线时间
- 621 小时
- 最后登录
- 2025-7-12
- 阅读权限
- 50
- 精华
- 0
 
- UID
- 28813
- 帖子
- 62
- 精华
- 0
- 经验
- 67 点
- 金钱
- 63 ¥
- 注册时间
- 2007-10-14
|
根据你所提供的方法思路与要求试着让AI写了代码
#include <STC8H.H>
#include <intrins.h>
// 定义OLED相关引脚
#define OLED_SCL P1_0 // SCL时钟线
#define OLED_SDA P1_1 // SDA数据线
#define OLED_RST P1_2 // 复位引脚
#define OLED_DC P1_3 // 数据/命令选择引脚
// 定义监控引脚
#define LRCK_PIN P2_0 // 左/右时钟引脚
#define BCLK_PIN P2_1 // 位时钟引脚
// 定义音频格式类型
#define FORMAT_UNKNOWN 0
#define FORMAT_PCM 1
#define FORMAT_DSD 2
// 定义静音控制引脚
#define MUTE_PIN P3_0
// 全局变量
unsigned int bclk_counter = 0; // BCLK计数器
unsigned int lrck_counter = 0; // LRCK计数器
unsigned int bclk_flag = 0; // BCLK频率标志
unsigned int lrck_flag = 0; // LRCK频率标志
unsigned int prev_bclk_flag = 0; // 上一次BCLK频率标志
unsigned int format_changed_count = 0; // 格式变化计数
unsigned char audio_format = FORMAT_UNKNOWN; // 当前音频格式
unsigned long sample_rate = 0; // 当前采样率
unsigned char mute_flag = 0; // 静音标志
unsigned char oled_init_flag = 0; // OLED初始化标志
// PCM典型采样率列表
const unsigned long pcm_rates[] = {44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000};
// DSD采样率列表
const unsigned long dsd_rates[] = {2822400, 5644800, 11289600};
// OLED相关函数声明
void OLED_Init(void);
void OLED_Clear(void);
void OLED_ShowString(unsigned char x, unsigned char y, char *str);
void OLED_ShowNum(unsigned char x, unsigned char y, unsigned long num, unsigned char len);
void OLED_Refresh(void);
void OLED_DisplayAudioInfo(void);
// 延时函数
void Delay10us(unsigned int t)
{
unsigned int i, j;
for(i = 0; i < t; i++)
for(j = 0; j < 3; j++);
}
// IIC通信函数
void IIC_Start(void)
{
OLED_SDA = 1;
OLED_SCL = 1;
Delay10us(1);
OLED_SDA = 0;
Delay10us(1);
OLED_SCL = 0;
}
void IIC_Stop(void)
{
OLED_SDA = 0;
OLED_SCL = 1;
Delay10us(1);
OLED_SDA = 1;
Delay10us(1);
}
bit IIC_WaitAck(void)
{
bit ackbit;
OLED_SDA = 1;
OLED_SCL = 1;
Delay10us(1);
ackbit = OLED_SDA;
OLED_SCL = 0;
Delay10us(1);
return ackbit;
}
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i = 0; i < 8; i++)
{
OLED_SCL = 0;
Delay10us(1);
if(byt & 0x80) OLED_SDA = 1;
else OLED_SDA = 0;
Delay10us(1);
OLED_SCL = 1;
byt <<= 1;
Delay10us(1);
}
OLED_SCL = 0;
}
// OLED命令和数据写入函数
void OLED_WriteCmd(unsigned char cmd)
{
IIC_Start();
IIC_SendByte(0x78); // 设备地址
IIC_SendByte(0x00); // 写命令
IIC_SendByte(cmd);
IIC_Stop();
}
void OLED_WriteData(unsigned char data)
{
IIC_Start();
IIC_SendByte(0x78); // 设备地址
IIC_SendByte(0x40); // 写数据
IIC_SendByte(data);
IIC_Stop();
}
// OLED初始化函数
void OLED_Init(void)
{
OLED_RST = 0;
Delay10us(200);
OLED_RST = 1;
OLED_WriteCmd(0xAE); // 关闭显示
OLED_WriteCmd(0xD5); // 设置显示时钟分频/振荡频率
OLED_WriteCmd(0x80);
OLED_WriteCmd(0xA8); // 设置多路复用率
OLED_WriteCmd(0x3F);
OLED_WriteCmd(0xD3); // 设置显示偏移
OLED_WriteCmd(0x00);
OLED_WriteCmd(0x40); // 设置显示开始行
OLED_WriteCmd(0x8D); // 电荷泵设置
OLED_WriteCmd(0x14);
OLED_WriteCmd(0x20); // 内存寻址模式
OLED_WriteCmd(0x00);
OLED_WriteCmd(0xA1); // 段重映射
OLED_WriteCmd(0xC8); // COM输出扫描方向
OLED_WriteCmd(0xDA); // COM硬件配置
OLED_WriteCmd(0x12);
OLED_WriteCmd(0x81); // 对比度控制
OLED_WriteCmd(0xCF);
OLED_WriteCmd(0xD9); // 预充电周期
OLED_WriteCmd(0xF1);
OLED_WriteCmd(0xDB); // VCOMH取消选择级别
OLED_WriteCmd(0x40);
OLED_WriteCmd(0xA4); // 整个显示打开
OLED_WriteCmd(0xA6); // 正常/反转显示
OLED_WriteCmd(0xAF); // 开启显示
OLED_Clear();
oled_init_flag = 1;
}
// OLED清屏函数
void OLED_Clear(void)
{
unsigned char i, n;
for(i = 0; i < 8; i++)
{
OLED_WriteCmd(0xB0 + i);
OLED_WriteCmd(0x00);
OLED_WriteCmd(0x10);
for(n = 0; n < 128; n++)
OLED_WriteData(0x00);
}
}
// OLED显示字符串函数
void OLED_ShowString(unsigned char x, unsigned char y, char *str)
{
unsigned char j = 0;
while(str[j] != '\0')
{
// 这里应该有字符显示的具体实现
// 简化处理,实际应用中需要添加字模数据
j++;
x += 8;
if(x > 120)
{
x = 0;
y += 2;
}
}
}
// OLED显示数字函数
void OLED_ShowNum(unsigned char x, unsigned char y, unsigned long num, unsigned char len)
{
unsigned char t, temp;
for(t = 0; t < len; t++)
{
temp = (num / OLED_Pow(10, len - t - 1)) % 10;
// 这里应该有数字显示的具体实现
// 简化处理,实际应用中需要添加字模数据
x += 8;
}
}
// 计算10的n次方
unsigned long OLED_Pow(unsigned char m, unsigned char n)
{
unsigned long result = 1;
while(n--) result *= m;
return result;
}
// 刷新OLED显示
void OLED_Refresh(void)
{
// 实际应用中需要根据具体的OLED库来实现
}
// 显示音频信息
void OLED_DisplayAudioInfo(void)
{
if(!oled_init_flag) return;
OLED_Clear();
OLED_ShowString(0, 0, "Audio Format:");
if(audio_format == FORMAT_PCM)
{
OLED_ShowString(0, 2, "PCM");
}
else if(audio_format == FORMAT_DSD)
{
OLED_ShowString(0, 2, "DSD");
}
else
{
OLED_ShowString(0, 2, "Unknown");
}
OLED_ShowString(0, 4, "Sample Rate:");
if(sample_rate >= 1000000)
{
OLED_ShowNum(0, 6, sample_rate / 1000000, 1);
OLED_ShowString(8, 6, ".");
OLED_ShowNum(16, 6, (sample_rate % 1000000) / 100000, 1);
OLED_ShowString(24, 6, "MHz");
}
else if(sample_rate >= 1000)
{
OLED_ShowNum(0, 6, sample_rate / 1000, 3);
OLED_ShowString(24, 6, "kHz");
}
else
{
OLED_ShowNum(0, 6, sample_rate, 3);
OLED_ShowString(24, 6, "Hz");
}
OLED_Refresh();
}
// 设置静音
void SetMute(unsigned char state)
{
if(state)
{
MUTE_PIN = 1;
mute_flag = 1;
}
else
{
MUTE_PIN = 0;
mute_flag = 0;
}
}
// 判断音频格式
void DetectAudioFormat(void)
{
unsigned char i;
unsigned char is_pcm = 0;
unsigned char is_dsd = 0;
// 先判断是否为PCM典型频率
for(i = 0; i < sizeof(pcm_rates)/sizeof(pcm_rates[0]); i++)
{
if(lrck_flag == pcm_rates[i])
{
audio_format = FORMAT_PCM;
sample_rate = lrck_flag;
is_pcm = 1;
break;
}
}
// 如果不是PCM典型频率,判断是否为DSD
if(!is_pcm && lrck_flag > 384000)
{
for(i = 0; i < sizeof(dsd_rates)/sizeof(dsd_rates[0]); i++)
{
if(lrck_flag >= dsd_rates[i] * 0.95 && lrck_flag <= dsd_rates[i] * 1.05)
{
audio_format = FORMAT_DSD;
sample_rate = lrck_flag;
is_dsd = 1;
break;
}
}
}
// 如果都不是,设置为未知格式
if(!is_pcm && !is_dsd)
{
audio_format = FORMAT_UNKNOWN;
sample_rate = 0;
}
}
// 系统初始化
void SystemInit(void)
{
// 配置GPIO
P2M0 = 0x00; // 设置P2.0和P2.1为输入模式
P2M1 = 0x03;
P3M0 = 0x01; // 设置P3.0为推挽输出模式
P3M1 = 0x00;
// 配置定时器0,用于1ms定时
TMOD = 0x01; // 定时器0工作在模式1
TH0 = 0xFC; // 定时1ms
TL0 = 0x18;
ET0 = 1; // 使能定时器0中断
TR0 = 1; // 启动定时器0
// 配置外部中断0,用于检测BCLK上升沿
IT0 = 1; // 设置为下降沿触发
EX0 = 1; // 使能外部中断0
// 配置外部中断1,用于检测LRCK上升沿
IT1 = 1; // 设置为下降沿触发
EX1 = 1; // 使能外部中断1
EA = 1; // 开总中断
// 初始化OLED
OLED_Init();
// 初始化为静音状态
SetMute(1);
// 初始化音频格式为未知
audio_format = FORMAT_UNKNOWN;
sample_rate = 0;
// 显示初始信息
OLED_DisplayAudioInfo();
}
// 定时器0中断服务程序(1ms)
void Timer0_ISR() interrupt 1
{
TH0 = 0xFC; // 重新加载定时值
TL0 = 0x18;
// 计算频率
bclk_flag = bclk_counter * 1000; // 假设计数器每1ms清零一次
lrck_flag = lrck_counter * 1000;
// 清零计数器
bclk_counter = 0;
lrck_counter = 0;
// 检查频率是否变化
if(bclk_flag != prev_bclk_flag)
{
format_changed_count++;
if(format_changed_count >= 3)
{
// 检测到格式变化,拉静音
SetMute(1);
// 检测音频格式
DetectAudioFormat();
// 重置变化计数
format_changed_count = 0;
}
}
else
{
format_changed_count = 0;
}
prev_bclk_flag = bclk_flag;
// 如果静音标志为1且已经静音了一段时间,解除静音
if(mute_flag)
{
static unsigned int mute_counter = 0;
mute_counter++;
if(mute_counter >= 1000) // 1ms * 1000 = 1s
{
SetMute(0);
mute_counter = 0;
// 更新OLED显示
OLED_DisplayAudioInfo();
}
}
}
// 外部中断0服务程序(BCLK)
void INT0_ISR() interrupt 0
{
bclk_counter++;
if(bclk_counter >= 1024)
{
bclk_counter = 0;
}
}
// 外部中断1服务程序(LRCK)
void INT1_ISR() interrupt 2
{
lrck_counter++;
if(lrck_counter >= 1024)
{
lrck_counter = 0;
}
}
// 主函数
void main()
{
SystemInit();
while(1)
{
// 主循环中可以添加其他任务
// 音频格式检测和显示在中断中完成
}
}
|
|