找回密码
 立即注册
查看: 133|回复: 5

STC32G12K128, PWM-DAC频率问题?时钟源如何设置

[复制链接]
  • 打卡等级:以坛为家III
  • 打卡总天数:718
  • 最近打卡:2026-07-04 07:01:47

37

主题

173

回帖

1087

积分

金牌会员

积分
1087
发表于 2026-5-11 19:56:04 | 显示全部楼层 |阅读模式
PWM作为载波输出音频信号。目前8位PWM。主频24M .载波频率40Khz.通过二阶阻容滤波效果不好。莎莎声明显。

将主频调高到25M  9位PWM 。此时载波频率大概34K .偏低。但是听感明显比8位PWM好
现在想做10位PWM 。但是主频不能在高。PWM时钟源如何设置?

现在的想法是系统工作主频24M .经过2分频=12M 然后*8 =96M 作为PWM的高级时钟源。通过P34端口输出。这样可以输出11位PWM。载波频率大概在48K左右。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:393
  • 最近打卡:2026-07-04 17:13:30

83

主题

7888

回帖

1万

积分

超级版主

积分
16827
发表于 2026-5-11 22:11:33 | 显示全部楼层
下载下面帖子的例程包,解压缩,参考两个程序:
01B-HSPWMA-4对互补PWM输出P2口
02B-HSPWMB-4个单端PWM输出P2口

HSPWM的时钟是144MHz,40KHz的PWM频率,可以得到幅度为3600的PWM,音质会很好。

STC32G-高级PWM范例程序下载
https://www.stcaimcu.com/thread-1778-1-1.html
(出处: 国芯人工智能技术交流网站)
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:718
  • 最近打卡:2026-07-04 07:01:47

37

主题

173

回帖

1087

积分

金牌会员

积分
1087
发表于 2026-5-12 15:30:14 | 显示全部楼层
梁*** 发表于 2026-5-11 22:11
下载下面帖子的例程包,解压缩,参考两个程序:
01B-HSPWMA-4对互补PWM输出P2口
02B-HSPWMB-4个单端PWM输出 ...

谢谢梁工:已经设置成功。还有一个问题想请教一下。我测试通过CAN发送8点正弦波。非常稳定正常。但是传输实际音频的时候失真很严重,我的音频采集是通过DMA 。转换两次。然后经过A_LOW编码发送。语音采样率8K,每32毫秒采集256字节。通过编码输出128字节。(标准帧32帧)采集和解码都是双缓冲。采集A 发送B 。采集满256字节发送标志==1.在主循环发送32帧。(实际测试接收时间不丢包需要12.5毫秒)。DMA在定时器中断125us触发一次。困惑很久没找到原因。现在真实音频是信号源产生1K正弦波。收到失真抖动。unsigned char ALAW_Encode(int pcm)
{
    unsigned char sign, comp, seg;
    unsigned int temp;

    if (pcm >= 0)
    {
        sign = 0;
        temp = pcm;
    }
    else
    {
        sign = 0x80;
        temp = -pcm;
    }

    if (temp > 32635) temp = 32635;
    temp += 33;

    if (temp >= 16384)      seg = 7;
    else if (temp >= 8192)  seg = 6;
    else if (temp >= 4096)  seg = 5;
    else if (temp >= 2048)  seg = 4;
    else if (temp >= 1024)  seg = 3;
    else if (temp >= 512)   seg = 2;
    else if (temp >= 256)   seg = 1;
    else                    seg = 0;

    comp = (seg << 4) | ((temp >> (seg + 3)) & 0x0F);
    comp ^= 0x55;
    return sign | comp;
}

// A-LAW解码实现
int ALAW_Decode(unsigned char alaw)
{
    unsigned char sign, seg;
    unsigned int temp;

    alaw ^= 0x55;
    sign = alaw & 0x80;
    alaw &= 0x7F;

    seg = (alaw >> 4) & 0x07;
    temp = (0x80 | (alaw & 0x0F)) << (seg + 3);
    temp -= 33;

    if (seg != 0)
        temp += 4 << seg;

    if (sign) return -(int)temp;
    else return (int)temp;
}

// A-LAW块编码:256个PCM样本→256字节A-LAW数据
void alaw_encode_block(int *in, unsigned char *out, unsigned int n)
{
    unsigned int i;
    int sample16;
    for (i = 0; i < n; i++)
    {
        // 原PCM是12bit(-2048~2047),扩展到16bit适配A-LAW
        sample16 = in<< 4;
        out = ALAW_Encode(sample16);
    }
}

// A-LAW块解码:256字节A-LAW→256个PCM样本
void alaw_decode_block(unsigned char *in, int *out, unsigned int n)
{
    unsigned int i;
    int pcm16;
    for (i = 0; i < n; i++)
    {
        pcm16 = ALAW_Decode(in);
        // 还原为12bit PCM
        out = pcm16 >> 2;
    }
}

void prepare_pwm_buf(int *pcm, unsigned int *pwm, unsigned int n)
{
    unsigned int i;
    long val;
//    unsigned long temp;
   
    for (i = 0; i < n; i++)
    {
        val = (long)pcm + 2048;
        if (val < 10)  val = 10;
        if (val > 4085) val = 4085;
//       temp = (unsigned long)(val - 10) * 255;
//        pwm = (unsigned char)(temp / (4085 - 10));
                        pwm = (val - 10) * 511 / 4075;
    }
}  
void Timer0_ISR(void) interrupt 1
{
    // 输出当前采样点的PWM占空比
    PWM_SetDuty(rx_pwm[play_pos]);

    // 播放指针+1
    play_pos++;

    // 播放完一帧256点,回到0重新开始
    if(play_pos >= PCM_SAMPLE_NUM)
    {
        play_pos=0;
        silence_cnt++;  // 静音计数+1

        // 连续多帧没收到新数据 → 填充静音,防止噪音
        if(silence_cnt>3)
        {
            fill_silence(rx_pwm, PCM_SAMPLE_NUM);
            silence_cnt=0;
        }
    }
}  不知道哪里的问题?

点评

还没空详细看代码。 “语音采样率8K,每32毫秒采集256字节。通过编码输出128字节。” 这个是错误的,应该是“语音采样率8K,每32毫秒采集256点512字节,通过A-LAW编码输出256点256字节数据。”  详情 回复 发表于 2026-5-12 16:20
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:393
  • 最近打卡:2026-07-04 17:13:30

83

主题

7888

回帖

1万

积分

超级版主

积分
16827
发表于 2026-5-12 16:20:13 | 显示全部楼层
zhang*** 发表于 2026-5-12 15:30
谢谢梁工:已经设置成功。还有一个问题想请教一下。我测试通过CAN发送8点正弦波。非常稳定正常。但是传输 ...

还没空详细看代码。
“语音采样率8K,每32毫秒采集256字节。通过编码输出128字节。”  这个是错误的,应该是“语音采样率8K,每32毫秒采集256点512字节,通过A-LAW编码输出256点256字节数据。”
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:718
  • 最近打卡:2026-07-04 07:01:47

37

主题

173

回帖

1087

积分

金牌会员

积分
1087
发表于 2026-5-12 18:03:23 | 显示全部楼层
梁*** 发表于 2026-5-12 16:20
还没空详细看代码。
“语音采样率8K,每32毫秒采集256字节。通过编码输出128字节。”  这个是错误的,应 ...

啊 。256点。每个点12位需要两个字节  512字节。我前面说错了。压缩后256字节。发送32帧。每帧8字节。32*8 = 256 没有错

点评

A-LAW是一种折叠码,要处理正确哦,8K采样声音也很好的。  详情 回复 发表于 2026-5-12 18:19
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:393
  • 最近打卡:2026-07-04 17:13:30

83

主题

7888

回帖

1万

积分

超级版主

积分
16827
发表于 2026-5-12 18:19:13 | 显示全部楼层
zhang*** 发表于 2026-5-12 18:03
啊 。256点。每个点12位需要两个字节  512字节。我前面说错了。压缩后256字节。发送32帧。每帧8字节。32* ...

A-LAW是一种折叠码,要处理正确哦,8K采样声音也很好的。
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-7-5 09:48 , Processed in 0.080041 second(s), 71 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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