本应用笔记是探讨max3108高性能通用异步接收器/发送器(uart)特性系列笔记中的第一篇,解释了max3108和控制微处理器之间的基本接口。应用笔记简要介绍了通过2、4或6引脚实现硬件连接;实施 31 个寄存器,可通过 spi 或 i 访问2c接口;和三种复位机制。spi 和 i 的更详细解释2c 接口和伪代码示例如下。
介绍
max3108为高性能通用异步收发器(uart),采用晶圆级封装(wlp),理想用于低功耗便携式设备。其高级功能范围从单独的 128 字发送和接收 fifo 到广泛的硬件介导流控制。然而,在应用利用这些特性之前,它必须与max3108及其31个内部寄存器进行可靠的通信。本应用笔记介绍了max3108通信的基本原理。有关伪代码的软件约定显示在附录中。
硬件连接
max3108与微处理器(μp)之间的通信通过2、4或6个引脚进行。两个专用引脚 %-overbar_pre%irq%-overbar_post% 和 %-overbar_pre%rst%-overbar_post% 通常连接到微处理器 gpio 引脚。%-overbar_pre_sentence%irq%-overbar_post% 是微处理器的输入引脚。作为双功能信号,%-overbar_pre%irq%-overbar_post%既指示max3108复位何时完成,又在发生某些可编程uart事件时通知微处理器。%-overbar_pre_sentence%rst%-overbar_post% 是微处理器的输出引脚。它可靠地强制max3108复位至已知状态。尽管可以在不使用这些引脚的情况下实现功能应用程序,但最好连接它们,除非缺少 gpio 引脚。
max3108实现31个寄存器,每个寄存器一个字节宽,可通过spi或i访问。2c 接口,在硬件中选择。由于其更大的带宽和更简单的实现,spi接口更可取。绑定 spi/%-overbar_pre%i2c%-overbar_post% 引脚高电平实现 spi 接口。把它绑得很低,实现了我2c 接口。
max3108 spi接口直接连接到微处理器上常用的spi硬件引擎时效果最佳。
微处理器 spi 引脚 max3108引脚
酱 味噌/自主权达
莫西 莫西/a1
高莱克 sclk/scl
党卫军 /cs/a0
与其他spi接口实现不同,即使max3108是spi总线上唯一的器件,从选择(ss)信号也必须连接到max3108。
同样,i2c 接口在直接连接到 i 时效果最佳2微处理器上的 c 硬件引擎。
微处理器 i2c 引脚 max3108引脚
标准及校正实验所 sclk/scl
自主权评估 味噌/自主权达
与spi接口不同,i2c 接口依赖于总线上具有唯一 i 的每个外设2c 地址。为避免地址冲突,max1 i引脚mosi/a0和%-overbar_pre%cs%-overbar_post%/a3108上的硬件引脚搭接选项固定2c 外设地址为 16 种可能性之一。详情请参考max3108数据资料。
重置
max3108具有三种复位机制,所有这些机制都使max3108处于已知状态,需要后续寄存器设置负载。
第一种复位机制是在上电时自动复位。max3108要完成复位,无需时钟。但是,1.8v电源必须启动并运行。ldoen 必须连接高电平,或者如果 ldoen 连接为低电平,则必须将有效的 1.8v 电源连接到 v18 引脚。仅在复位期间,%-overbar_pre%irq%-overbar_post%引脚不是中断指示器,而是复位完成指示器。一旦%-overbar_pre%irq%-overbar_post%引脚变为高电平,复位完成。如果max3108不存在或未上电,程序流可能会无限期地卡在环路中。如果这是一个问题,请添加一个计时器。如果 %-overbar_pre%irq%-overbar_post% 在 300μs 后仍未出现,您可以假设有问题。为避免在max3108完全就绪之前写入寄存器,应用必须遵循以下步骤。while
/*** wait for the max3108 to come out of reset*/ // wait for the irq pin to come up, as this // indicates that the max3108 reset is complete while (poll_max3108_irq == 0); 第二种复位机制是通过max3108 %-overbar_pre%rst%-overbar_post%引脚进行硬件复位。在这种情况下,手动将%-overbar_pre%rst%-overbar_post%引脚脉冲为低电平,然后为高电平。与上电时自动复位一样,%-overbar_pre%irq%-overbar_post%引脚表示复位完成。如上所述,为防止max3108缺电或未上电时无限期卡在环路中,增加一个延迟最小为300μs的定时器。伪代码见下文。while
/*** perform a hardware reset*/ set_max3108_reset_pin_low; wait (1µs); set_max3108_reset_pin_high; // wait for the irq pin to come up, as this // indicates that the max3108 reset is complete while (poll_max3108_irq == 0); 第三种复位机制是软件控制的复位,它依赖于spi或i2c 访问 max3108。与其他复位一样,max3108寄存器需要在复位完成后重新加载。使用以下伪代码调用重置。
/*** software reset of the max3108*/ max3108_write (max3108r_mode2, 0x01); max3108_write (max3108r_mode2, 0x00); 通过 spi 接口
max3108与微处理器之间的通信通过%-overbar_pre%rst%-overbar_post%引脚、%-overbar_pre%irq%-overbar_post%引脚(均如上所述)以及应用微处理器和max3108寄存器之间的接口进行。此寄存器接口可以是 spi 或 i2c 接口。有关 spi 选项的详细信息显示在此处,而有关 i 的详细信息2c 接口出现在通过 i 接口2c部分。
spi 接口是微处理器上常用的硬件接口。spi接口的另一个优点是它的速度。max3108可支持高达26mbps的spi数据速率,比目前大多数微处理器spi硬件更快。
max3108 spi接口不仅支持单寄存器读写,还支持突发读写。这些突发事务提高了寄存器接口的效率,进一步推开了寄存器接口成为瓶颈的点。
与其他spi方案不同,微处理器上spi主硬件的ss信号必须连接至max3108 %-overbar_pre%cs%-overbar_post%/a0引脚。除了选择spi总线外设的传统用途外,%-overbar_pre%cs%-overbar_post%/a0引脚还向max3108发出spi事务边界信号。%-overbar_pre%cs%-overbar_post%/a0的下降沿向max3108表示spi接口上的下一个字节是max3108寄存器地址。%-overbar_pre%cs%-overbar_post%/a0的上升沿向max3108发出信号,表明spi事务(单次读取、单次写入、突发读取或突发写入)已经结束。
spi 事务本质上是双向的。对于从微处理器写入max3108的每个字节,max3108同时返回一个字节到微处理器。这些往往可以忽略;寄存器写操作忽略max3108的返回字节。类似地,寄存器读取返回其值,微处理器向max3108发送虚拟字节。这些虚拟字节不会降低接口速度,因为它们与有效的寄存器读取或写入数据同时发生。
单 spi 写入
单个写入事务的伪代码如下所示:
/*** write one byte to the specified register in the max3108**** arguments: ** port: max3108 register address to write to (0x00 through 0x1e)** val: the value to write to that register**** return value: true***/bool max3108_spi_write (unsigned int port, unsigned char val) { unsigned int dummy; // indicate the start of a transaction set_max3108_cs_pin_low; // write transaction is indicated by msbit of the // max3108 register address byte = 1. spi return // from the max3108 ignored dummy = spi_send_byte (0x80 | port); // now send the value to write, return value ignored dummy = spi_send_byte (val); // finally, indicate transaction completion set_max3108_cs_pin_high; return true;} 突发 spi 写入
max3108 spi接口还支持突发写入,适用于快速fifo填充或快速寄存器负载。如果寄存器地址为零,则突发写入将填充发送fifo。这允许快速fifo填充,无需切换max3108 %-overbar_pre%cs%-overbar_post%/a0线或为每个写入fifo字节发送寄存器地址。
对于任何其他max3108寄存器地址,寄存器地址随着突发的每个后续字节自动递增,从而允许快速寄存器填充。
突发写入事务的伪代码如下所示:
/*** write a burst of bytes to the max3108**** arguments:** port: max3108 register address to write to** len: number of bytes to send to max3108 registers** ptr: pointer to the bytes to send**** return value: true***/bool max3108_spi_puts (unsigned int port, unsigned int len, unsigned char *ptr) { unsigned int dummy; // indicate the start of a transaction set_max3108_cs_pin_low; // write transaction indicated by msbit of the // max3108 register address byte = 1. spi return // from the max3108 ignored dummy = spi_send_byte (0x80 | port); // covers the case where len==0 while (len--) { dummy = spi_send_byte (*ptr++); // return value ignored } // indicate transaction completion set_max3108_cs_pin_high; return true;} 注意,对于突发写入事务,第一个字节是max3108寄存器地址,所有后续字节都是寄存器值写入。最终寄存器写入由%-overbar_pre%cs%-overbar_post%/a0引脚变为高电平表示。
spi硬件引擎(通常基于dma)也控制max3108 %-overbar_pre%cs%-overbar_post%/a0引脚,通常通过标有overbar_post overbar_pre ss的引脚。当 %-overbar_pre%cs%-overbar_post%/a0 变低时,表示下一个 spi 事务开始。%-overbar_pre%cs%-overbar_post%/a0必须保持较高的最短时间为0ns。此时确保max100识别出交易已完成。
单 spi 读取
通过spi读取寄存器字节涉及发送寄存器地址,后跟虚拟字节。来自虚拟字节的spi反馈是所选max3108寄存器的值。
单次读取的伪代码如下:
/*** read one byte from the specified register in the max3108**** arguments: ** port: max3108 register address to read from**** return value: the register value***/unsigned int max3108_spi_read (unsigned int port) { unsigned int dummy; unsigned int val; // indicate the start of a transaction set_max3108_cs_pin_low; // read transaction indicated by msbit of the // address byte = 0. spi return from the max3108 // ignored dummy = spi_send_byte (port & 0x7f); // now send a dummy byte to collect the // register value val = spi_send_byte (0x00); // finally, indicate transaction completion set_max3108_cs_pin_high; return val;} 突发 spi 读取
max3108 spi接口还支持突发读取,适用于快速fifo清空或快速寄存器扫描。如果寄存器地址为零,则突发读取为空接收fifo。这样就可以快速进行fifo转储,而无需切换max3108 %-overbar_pre%cs%-overbar_post%/a0线或为每个fifo字节读取发送寄存器地址。
对于任何其他max3108寄存器地址,寄存器地址随着突发的每个后续字节自动递增,从而允许快速寄存器扫描。
突发读取事务的伪代码如下:
/*** read a burst of bytes from the max3108**** arguments:** port: max3108 register address to read from** len: number of bytes to get from max3108 registers** ptr: pointer to where to place the bytes**** return value: true***/bool max3108_spi_gets (unsigned int port, unsigned int len, unsigned char *ptr) { unsigned int dummy; // indicate the start of a transaction set_max3108_cs_pin_low; // read transaction indicated by msbit of the // address byte = 0. spi return from the max3108 // ignored dummy = spi_send_byte (port & 0x7f); // covers the case where len==0 while (len--) { *ptr++ = spi_send_byte (0x00); } // indicate transaction completion set_max3108_cs_pin_high; return true;} 注意,对于突发读取事务,第一个字节是max3108寄存器地址,所有后续字节都是假字节,其返回值为寄存器值。最终寄存器读取由%-overbar_pre%cs%-overbar_post%/a0引脚变为高电平表示。
通过 i 接口2c
max3108寄存器和微处理器之间的通信也可以通过i进行。2c 接口。
我2c 接口是微处理器上常见的硬件辅助接口。i 的另一个优点2c接口是它只使用两个引脚。而不是为每个外设选择单独的芯片(如在spi接口的情况下),一个i2c 接口依赖于每个具有唯一 i 的外设2c 地址。为避免与其他 i 发生可能的冲突2同一 i 上的 c 外设2c总线,max3108可通过引脚编程至16个唯一i之一2通过 mosi/a1 和 %-overbar_pre%cs%-overbar_post%/a0 引脚的引脚绑定实现 c 外设地址。在下面的伪代码中,假定预处理器变量max3108_i2c_peripheral_address是用适当的 i 定义的2c 寄存器写入地址,与任何其他 i 的地址是唯一的2同一总线上的 c 外设。
max3108不仅支持标准模式(100kbps)和快速模式(400kbps)i2c,但也有快速模式加 (1mbps) i2c.
the max3108 i2c 接口不仅支持单寄存器读写,还支持突发读写。这些突发事务提高了寄存器接口的效率,进一步推开了寄存器接口成为瓶颈的点。
单 i2c 写入
单个写入事务的伪代码如下所示:
/*** write one byte to the specified register in the max3108**** arguments: ** port: max3108 register address to write to** val: the value to write to that register**** return value: true – register successfully written** false – i2c protocol error of some kind***/bool max3108_i2c_write (unsigned int port, unsigned char val) { // indicate the start of a transaction and send the // max3108 write peripheral address (lsbit = 0) i2c_set_start_condition; i2c_send_byte (max3108_i2c_peripheral_address); // is anybody out there? if (!i2c_test_ack) { i2c_set_stop_condition; // no – close out the return false; // transaction } // the max3108 is out there, now send the max3108 // register to write i2c_send_byte (port); // possibly illegal max3108 register address? if (!i2c_test_ack) { i2c_set_stop_condition; return false; } // now send the byte to write i2c_send_byte (val); // did the max3108 get confused? if (!i2c_test_ack) { i2c_set_stop_condition; return false; } // the max3108 is ok with our write, make it so i2c_set_stop_condition; return true;} 爆裂 i2c 写入
the max3108 i2c 接口还支持突发写入,适用于快速 fifo 填充或快速寄存器加载。如果寄存器地址为零,则突发写入将填充发送fifo。这允许快速填充fifo,而无需i2写入的每个 fifo 字节的 c 前导码开销。
对于任何其他max3108寄存器地址,寄存器地址随着突发的每个后续字节自动递增,从而允许快速寄存器填充。
突发写入事务的伪代码如下所示:
/*** write a burst of bytes to the max3108**** arguments:** port: max3108 register address to write to** len: number of bytes to send to max3108 registers** ptr: pointer to the bytes to send**** return value: true – register successfully written** false – i2c protocol error of some kind***/bool max3108_i2c_puts (unsigned int port, unsigned int len, unsigned char *ptr) { // indicate the start of a transaction and send the // max3108 write peripheral address (lsbit = 0) i2c_set_start_condition; i2c_send_byte (max3108_i2c_peripheral_address); // is anybody out there? if (!i2c_test_ack) { i2c_set_stop_condition; // no – close out the return false; // transaction } // the max3108 is out there, now send the max3108 // register address i2c_send_byte (port); // possibly illegal max3108 register address? if (!i2c_test_ack) { i2c_set_stop_condition; return false; } while (len--) { // now send the byte to write i2c_send_byte (*ptr++); // did the max3108 get confused? if (!i2c_test_ack) { i2c_set_stop_condition; return false; } } // the max3108 is ok with our write, make it so i2c_set_stop_condition; return true;}
注意,对于突发写入事务,第一个字节为max3108 i2c外设地址,第二个字节为max3108寄存器地址,后续所有字节均为寄存器值写入。最终寄存器写入由 stop 条件指示。
单 i2c 读取
通过 i 读取寄存器字节2c涉及发送max3108读寄存器地址,后跟i2c 重新启动条件以转动 i2c总线绕行,从写(到max3108指定max3108寄存器)到读(获取寄存器值)。
单次读取的伪代码如下:
/*** read one byte from the specified register in the max3108**** arguments: ** port: max3108 register address to read from**** return value: the register value (0x00xx)** 0xff00 is there was some error***/unsigned int max3108_i2c_read (unsigned int port) { unsigned int val; // indicate the start of a transaction and send the // max3108 write peripheral address (lsbit = 0) i2c_set_start_condition; i2c_send_byte (max3108_i2c_peripheral_address); // is anybody out there? if (!i2c_test_ack) { i2c_set_stop_condition; // no – close out the return 0xff00; // transaction } // the max3108 is out there, now send the max3108 // register address i2c_send_byte (port); // possibly illegal max3108 register address? if (!i2c_test_ack) { i2c_set_stop_condition; return 0xff00; } // now turn the i2c bus around by sending the max3108 // i2c peripheral read address (lsbit = 1) i2c_set_restart_condition; i2c_send_byte (max3108_i2c_peripheral_address | 0x01); if (!i2c_test_ack) { i2c_set_stop_condition; return 0xff00; } // now get the register value val = i2c_receive_byte; i2c_send_nack; i2c_set_stop_condition; return (val);} 爆裂 i2c 读取
the max3108 i2c 接口还支持突发读取,适用于快速 fifo 清空或快速寄存器扫描。如果寄存器地址为零,则突发读取为空接收fifo。这允许快速 fifo 转储,而不会产生与 i 相关的开销2每个 fifo 字节读取的 c 前导码。
对于任何其他max3108寄存器地址,寄存器地址随着突发的每个后续字节自动递增,从而允许快速寄存器扫描。
突发读取事务的伪代码如下所示:
/*** read a burst of bytes from the max3108**** arguments:** port: max3108 register address to read from** len: number of bytes to get from max3108 registers** ptr: pointer to where to place the bytes**** return value: true – if all read** false – if there was any error***/bool max3108_i2c_gets (unsigned int port, unsigned int len, unsigned char *ptr) { // indicate the start of a transaction and send the // max3108 write peripheral address (lsbit = 0) i2c_set_start_condition; i2c_send_byte (max3108_i2c_peripheral_address); // is anybody out there? if (!i2c_test_ack) { i2c_set_stop_condition; // no – close out the return false; // transaction } // the max3108 is out there, now send the max3108 // register address i2c_send_byte (port); // possibly illegal max3108 register address? if (!i2c_test_ack) { i2c_set_stop_condition; return false; } // now turn the i2c bus around by sending the max3108 // i2c peripheral read address (lsbit = 1) i2c_set_restart_condition; i2c_send_byte (max3108_i2c_peripheral_address | 0x01); if (!i2c_test_ack) { i2c_set_stop_condition; return false; } // now get the register values while (len--) { *ptr++ = i2c_receive_byte; if (len) i2c_send_ack; // all but last read else i2c_send_nack; // last read only } i2c_set_stop_condition; return true;} 注意,对于突发读事务,第一个字节是max3108 i2c外设写地址,第二个字节为max3108寄存器地址,第三个字节为max3108 i2c外设读取地址,并且所有后续字节都是寄存器值读取。微处理器在要读取更多寄存器时,以 ack 条件响应每个字节读取。nack条件表示从max3108读取的最终寄存器。
结论
按照本应用笔记提供的编码指南,可以快速启动并运行微处理器和max3108之间的接口。
本应用笔记中伪代码例程的大部分翻译都是特定于微处理器的。除中断处理程序外,本系列中的其他特定代码应用笔记详细探讨了max3108的特性,几乎不需要转换为特定的目标微处理器。它们将依靠本应用笔记中描述的读、写、获取和放置基元来封装微处理器特有的问题。
附录
本附录包含理解本应用笔记以及本系列其他伪代码所需的定义,详细探讨max3108的特性。
与引脚 i/o 相关的定义
poll_max3108_irq:该伪代码返回max3108 %-overbar_pre%irq%-overbar_post%引脚的数字状态。该引脚需要外部上拉才能正常工作。
set_max3108_cs_pin_high:该伪代码驱动max3108 %-overbar_pre%cs%-overbar_post%/a0引脚高电平。
set_max3108_cs_pin_low:该伪代码驱动max3108 %-overbar_pre%cs%-overbar_post%/a0引脚为低电平。
set_max3108_reset_pin_high:该伪代码驱动max3108 %-overbar_pre%rst%-overbar_post%引脚高电平。
set_max3108_reset_pin_low:该伪代码将max3108 %-overbar_pre%rst%-overbar_post%引脚驱动为低电平。
等:此伪代码至少将以下指令的执行延迟到指定的时间。
与i有关的定义2c 接口
i2c_send_byte:该伪代码通过i向max3108发送一个字节2c总线。
i2c_set_restart_condition:此伪代码在 i 上放置了 restart 条件2c总线。
i2c_set_start_condition:此伪代码在 i 上放置了一个 start 条件2c总线。
i2c_set_stop_condition:此伪代码在 i 上放置了一个 stop 条件2c总线。
i2c_test_ack:如果max3108响应用ack写入的字节,则返回true;如果max3108响应用nack写入的字节,则返回fals。
spi_send_byte:一个字节通过spi接口发送到max3108,同时捕获max3108返回的字节。
与寄存器接口相关的定义
max3108_gets:此例程要么max3108_i2c_gets,要么max3108_spi_gets,具体取决于应用程序中实现的接口。
max3108_puts:此例程要么max3108_i2c_puts,要么max3108_spi_puts,具体取决于应用程序中实现的接口。
max3108_read:此例程max3108_i2c_read或max3108_spi_read,具体取决于应用程序中实现的接口。
max3108_write:此例程是max3108_i2c_write的,也可以是max3108_spi_write的,具体取决于应用程序中实现的接口。
max3108_i2c_gets:本应用笔记描述的本例程通过i接收fifo或其它max3108寄存器的突发读取。2c 接口。
max3108_i2c_puts:本应用笔记中描述的本例程通过i向max3108发送fifo或其它max3108寄存器进行突发写入。2c 接口。
max3108_i2c_read:本应用笔记描述的本例程通过i读取max3108寄存器之一的值。2c 接口。
max3108_i2c_write:本应用笔记描述的本例程通过i向max3108寄存器写入一个值。2c 接口。
max3108_spi_gets:本应用笔记描述了该例程,通过spi接口从max3108接收fifo或其他max3108寄存器进行突发读取。
max3108_spi_puts:本应用笔记描述的本例程通过spi接口对max3108发送fifo或其它max3108寄存器进行突发写入。
max3108_spi_read:本应用笔记描述的该例程通过spi接口读取max3108寄存器之一的值。
max3108_spi_write:本应用笔记描述的本例程通过spi接口向max3108寄存器写入一个值。
北鲲云助力国产 EDA 芯片设计
基于上位机控制的单片机实验现场自动转接线设计电路图
C语言库memcpy和memmove的区别分析
360企业安全荣获VMware年度最佳技术联盟合作奖
胜宏科技六大核心竞争力详解
与MAX3108 UART接口
哈佛商业评论专访美格智能:在“差异化”赛道,锻造出海的核心优势
示波器有什么用 示波器的作用详解
施耐德电气PowerTag终端配电智能化系统特点及应用场景介绍
4525DO-DS3AS015DP差压传感器在管道静压测量的应用
展会直击丨10大系统齐上阵,华成工控精彩亮相DMP工博会
微服务架构下分布式数据库如何支撑千亿级数据
选购电视 首先要知道以下四点
木片机剪刃衬板安装面磨损在线修复全程记录
噪声扬尘监测系统助力环保部门管理工作
线上展厅vr建设未来发展趋势将会是什么样的?
如何从英特尔RealSun获得运动收益
盘点汽车行业MES系统的五大应用方向
人工智能硝烟已然升起 中美激烈竞逐AI市场
物联网的发展对于集成电路行业有什么影响