RP2040下的I2S Slave Out,PIO状态机(四)

        晚上回家后,进行硬件的实际调试,测试的时候我发现一个问题,输出有点不对劲,BCK和LRCK都是正确的,我用192k的fs,16bit的位深,按道理,发送数据的pin上的信号频率应该是介于BCK和LRCK之间的,但是DOUT的频率示波器测试大概是2K多一点,BCK是6.144Mhz,LRCK是192K,这个数据明显不对。我检查了线路,没有明显的缺陷,我想大概率问题还是在代码上。我又仔细检查了代码。我发现一个问题,DMA的双缓冲区是INT32类型的,而我需要发送的是16位数据。在初始化状态机的代码里面我发现这样的信息:

static inline void i2s_out_slave_init( PIO pio, uint sm, uint offset, uint dout_pin, uint bit_depth) 
{
    // 自动推导连续时钟引脚(硬件设计常见布局)
    uint bck_pin  = dout_pin + 1;   // BCK 紧邻 DOUT
    uint lrck_pin = dout_pin + 2;  // LRCK 紧邻 BCK
    // 初始化所有引脚功能
    pio_gpio_init(pio, dout_pin);  // DOUT
    pio_gpio_init(pio, bck_pin);    // BCK(输入)
    pio_gpio_init(pio, lrck_pin);   // LRCK(输入)
    // 核心配置(与标准实现一致)
    pio_sm_config c = i2s_slave_out_program_get_default_config(offset);
    sm_config_set_out_pins(&c, dout_pin, 1);          // DOUT 绑定
    sm_config_set_in_pins(&c, bck_pin);               // BCK 为时钟源
    sm_config_set_jmp_pin(&c, lrck_pin);              // LRCK 用于声道同步

    sm_config_set_out_shift(&c, false, false, bit_depth); // 左移(MSB先出),禁用 autopull
    sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);    // 合并 FIFO

    // 应用配置状态机
    pio_sm_init(pio, sm, offset, &c);

    // 统一设置初始电平和引脚方向
    pio_sm_set_pins_with_mask( pio, sm, 0, (7u << dout_pin) );  // zero output
    pio_sm_set_pindirs_with_mask( pio, sm, (1u << dout_pin), (7u << dout_pin) );
}

        其中一行代码如下:

sm_config_set_out_shift(&c, false, false, bit_depth); // 左移(MSB先出),禁用 autopull

        这里面有注释,MSB先出,发送16位就终止,这个是I2S标准的格式,意思就是先从高位发送,如果我给的16位有效值都在低位,那岂不是根本发不出去?我想了一下,这个环节我的确还没处理,我想了一下,我应该可以在创建正弦表的时候处理这个问题。我改了一下代码,在生成正弦值之后,把数据左移16位,把有效位放在高16位上,代码如下:

// 生成正弦波表(预计算优化)
bool CSineWave::GenerateSineTable() 
{
    if( bit_depth == 0 ) {
        return false;
    }

    uint shift = 32 - bit_depth;

    const double amplitude = static_cast<double>( ( uint32_t(1) << (bit_depth - 1) ) - 1 );
    for( uint32_t i = 0; i < SINE_TABLE_LENGTH; ++ i ) 
    {
        int32_t value = static_cast<int32_t>( std::round(
            amplitude * sin( 2.0 * M_PI * static_cast<double>(i) / SINE_TABLE_LENGTH ) ) );
        sine_table[i] = value << shift;    
    }
    return true;
}

        编译之后,再次测试,OUTPIN输出在示波器上显示出正确的波形。

轴飞行器】非线性三自由度轴飞行器模拟器研究(Matlab代码实现)内容概要:本文围绕非线性三自由度轴飞行器模拟器的研究展开,重点介绍了基于Matlab的建模与仿真方法。通过对轴飞行器的动力学特性进行分析,构建了非线性状态空间模型,并实现了姿态与位置的动态模拟。研究涵盖了飞行器运动方程的建立、控制系统设计及数值仿真验证等环节,突出非线性系统的精确建模与仿真优势,有助于深入理解飞行器在复杂工况下的行为特征。此外,文中还提到了多种配套技术如PID控制、状态估计与路径规划等,展示了Matlab在航空航天仿真中的综合应用能力。; 适合人群:具备一定自动控制理论基础和Matlab编程能力的高校学生、科研人员及从事无人机系统开发的工程技术人员,尤其适合研究生及以上层次的研究者。; 使用场景及目标:①用于轴飞行器控制系统的设计与验证,支持算法快速原型开发;②作为教学工具帮助理解非线性动力学系统建模与仿真过程;③支撑科研项目中对飞行器姿态控制、轨迹跟踪等问题的深入研究; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注动力学建模与控制模块的实现细节,同时可延伸学习文档中提及的PID控制、状态估计等相关技术内容,以全面提升系统仿真与分析能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值