void logic _analyse r _init (PIO pio , uint
sm , uint pin _base , uint pin _count , float
div) {
41 // Load a program to capture n pins .
This is just a single `in pins, n`
42 // instruction with a wrap .
43 uint16 _t capture _prog _instr = pio _
encode _in (pio _pins , pin _count );
44 struct pio _program capture _prog = {
45 . instructions = &capture _prog _instr ,
46 . length = 1 ,
47 . origin = -1
48 };
49 uint offset = pio _add _program (pio , &
capture _prog );
50
51 // Configure state machine to loop
over this `in` instruction forever,
52 // with autopush enabled.
53 pio _sm _config c = pio _get _default _
sm _config();
54 sm _config _set _in _pins(&c , pin _base);
55 sm _config _set _wrap (&c , offset , off-
set);
56 sm _config _set _clkdiv(&c , div);
57 // Note that we may push at a < 32
bit threshold if pin_count does not
58 // divide 32. We are using shift-to-
right, so the sample data ends up
59 // left-justified in the FIFO in
this case, with some zeroes at the LSBs .
60 sm _config _set _in _shift(&c , true ,
true , bits _packed _per _word(pin _count ));
61 sm _config _set _fifo _join(&c , PIO _
FIFO _JOIN _RX );
62 pio _sm _init (pio , sm , offset , &c);
63 }
这段代码是一个初始化函数,用于设置Raspberry Pi Pico的PIO(Programmable Input/Output)状态机以捕获多个引脚的数据。PIO是RP2040微控制器上的一项功能,允许用户直接控制GPIO引脚,进行高效的数据传输和处理。下面是对这段代码的逐行解释:
函数定义:
void logic_analyser_init(PIO pio, uint sm, uint pin_base, uint pin_count, float div)
这个函数接受五个参数:PIO实例、状态机编号、引脚基础编号、要捕获的引脚数量以及一个浮点数(可能是用于时钟分频的值)。
2. 注释:
// Load a program to capture n pins.
// This is just a single `in pins, n` instruction with a wrap.
这两行注释说明了接下来要加载的程序是为了捕获n个引脚的数据,并且这个程序只包含一个“in pins, n”指令,并带有循环。
3. 编码PIO指令:
uint16_t capture_prog_instr = pio_encode_in(pio_pins, pin_count);
这行代码使用pio_encode_in函数来编码一个PIO指令,该指令用于捕获指定数量的引脚。
4. 定义PIO程序:
struct pio_program capture_prog = {
.instructions = &capture_prog_instr,
.length = 1,
.origin = -1
};
这里定义了一个PIO程序,它只包含一个之前编码的指令。
5. 添加PIO程序到PIO实例:
uint offset = pio_add_program(pio, &capture_prog);
这行代码将之前定义的PIO程序添加到PIO实例中,并返回一个偏移量,该偏移量将用于后续的状态机配置。
6. 配置状态机:
pio_sm_config c = pio_get_default_sm_config();
从PIO实例获取默认的状态机配置。
接下来的几行代码对状态机配置进行了修改:
复制
* 设置要捕获的引脚基础编号。
* 设置循环,使得“in”指令可以无限循环执行。
* 设置时钟分频值。
* 设置数据捕获的位移和打包方式。
* 设置FIFO合并方式。
初始化状态机:
pio_sm_init(pio, sm, offset, &c);
使用之前配置的状态机配置来初始化状态机。
综上所述,这个函数的目的是为Raspberry Pi Pico的PIO设置一个状态机,使其能够无限循环地捕获指定数量的引脚数据,并将这些数据放入FIFO缓冲区中。这对于需要高速数据捕获和处理的场景(如音频、数字信号处理或通信协议)非常有用。