前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >FIFO 在 LHE3301 中的工作原理

FIFO 在 LHE3301 中的工作原理

作者头像
云深无际
发布于 2025-03-20 05:57:38
发布于 2025-03-20 05:57:38
9400
代码可运行
举报
文章被收录于专栏:云深之无迹云深之无迹
运行总次数:0
代码可运行

领慧立芯LHE3302:电化学模拟前端(AFE)我前几天写了这个,但是不知道开发板什么时候到,就写写。

FIFO(First In, First Out)在 LHE3301 芯片中主要用于缓冲 ADC 采样数据,可以降低 MCU 读取数据的频率,提高功耗优化效率。

FIFO 的深度为 256×24bit,即最多存储 256 组 24-bit 数据。

当数据满足中断要求,就会通知MCU:

如果一有数据就中断,会让主机很累,那就先存一段多的。这个模型就很简单。

FIFO 就像一个 队列(排队的队伍),数据先进去的必须先出来,不会被跳过。

  1. 写指针(WR_PTR,FIFO_WR_PTR)👉 记录下一个数据应该存在哪里
  2. 读指针(RD_PTR,FIFO_RD_PTR)👉 记录下一个要被读取的数据位置

去银行取号排队办业务:

写指针就像银行的叫号机,它负责发号(存数据)。

读指针就像柜台工作人员,他们会按顺序叫号(取数据)。

如果叫号机快(数据写入快),但柜台慢(数据读取慢),排队人数会越来越多(FIFO 变满)。

如果柜台叫号快,但叫号机发号慢,那么有时候柜台可能会没有号码可叫(FIFO 为空)。

  1. FIFO_WR_PTR(写指针)自动递增:每次 ADC 采样完成后,芯片自动把数据存入 FIFO,并让写指针 WR_PTR+1。
  2. 如果 FIFO 满了(256 组数据),写指针会停止增长,直到 MCU 读取数据。
  3. FIFO_RD_PTR(读指针)自动递增:每次 MCU 读取 FIFO 一条数据,芯片自动让读指针 RD_PTR+1。

如果 FIFO 为空,读取无效,读指针不会增长。

MCU 不用手动修改指针,芯片会自动管理读写指针的增长。MCU 只需要读取 FIFO 计数器,判断数据量是否足够。

大致来说就是写入数据和输出数据:

(1) 数据写入 FIFO

  1. ADC 采样完成后,转换数据(16-bit)+ 数据标签(4-bit)+ 状态标志(4-bit) 一起写入 FIFO。
  2. FIFO 自动管理写指针(WR_PTR),每写入一组数据,WR_PTR 自增。
  3. 当 FIFO 满时,新数据不会覆盖旧数据,需要 MCU 读取后才能继续写入。

(2) 数据读取 FIFO

  1. MCU 通过 SPI 读取 FIFO 数据寄存器(FIFO_DATA),每次读取 3 个字节(24-bit)。
  2. FIFO 读指针(RD_PTR) 记录当前读取位置,每读取一组数据,RD_PTR 自动自增。
  3. 读取完成后,可通过 FLUSH_FIFO 清空 FIFO,防止数据不一致。

根据FIFO设计相关的操作

ADC 采样数据写入 FIFO:采样完成后,数据自动存入 FIFO,FIFO_WR_PTR 自增。

读取 FIFO_COUNTER,查看 FIFO 中有多少数据:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
uint16_t fifo_count = (FIFO_COUNTER0 << 8) | FIFO_COUNTER1;

然后就是读取了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
uint8_t data[3];
spi_read(FIFO_DATA, data, 3);

接下来就把FIFO里面的数据还原我们感兴趣的样子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
uint32_t fifo_word = (data[0] << 16) | (data[1] << 8) | data[2];
uint16_t adc_value = fifo_word & 0xFFFF;  // 低 16 位为 ADC 数据
uint8_t tag = (fifo_word >> 16) & 0x0F;   // 4-bit 通道标签
uint8_t flag = (fifo_word >> 20) & 0x01;  // ADC 是否饱和

可能读比写超前,那就读取不到啊,都没数据,所以要判断。

读取数据前,检查 FIFO_COUNTER 确保 FIFO 非空。读完 FIFO 后,清空缓冲区。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define FIFO_MAX_COUNT 256  // FIFO 最大存储 256 组数据
void read_fifo_data() {
    uint16_t fifo_count = (read_register(FIFO_COUNTER0) << 8) | read_register(FIFO_COUNTER1);
    if (fifo_count > 0) {
        for (int i = 0; i < fifo_count; i++) {
            uint8_t data[3];
            spi_read(FIFO_DATA, data, 3);
            uint32_t fifo_word = (data[0] << 16) | (data[1] << 8) | data[2];
            uint16_t adc_value = fifo_word & 0xFFFF;
            uint8_t tag = (fifo_word >> 16) & 0x0F;
            uint8_t flag = (fifo_word >> 20) & 0x01;
            printf("ADC Value: %u, Channel: %d, Saturation: %d\n", adc_value, tag, flag);
        }
    }
    // 清空 FIFO,避免数据重复
    write_register(FIFO_CFG, FLUSH_FIFO);
}

两个芯片没有大区别

随便一个SPI都可以控制

采用单字节寄存器地址 + 单字节数据的 SPI 结构。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[写指令 | 地址] -> [数据]

写命令,格式 :1AAA AAAA 前面的1代表写入,后面的额7bit是地址,在什么地方写入。加一个数据

简单

最高位是0 ,读取:

LHE3301 采用 24-bit 数据格式 存储 ADC 采样数据:

解出来用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
uint8_t cmd = 0x0B;
uint8_t fifo_data[3];
spi_read(cmd, fifo_data, 3);
uint32_t adc_value = (fifo_data[0] << 16) | (fifo_data[1] << 8) | fifo_data[2];

简单

FIFO 采用 环形结构,写入数据后 写指针 (WR_PTR) 自动增加

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-03-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云深之无迹 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档