maxq3180微控制器是电表多相模拟前端。它具备现代多功能电表的所有功能。maxq3180通过串行外设互联(spi™)总线将其读数传送给主机微控制器。本应用笔记介绍怎样实现这一接口,演示实例代码以帮助设计人员实现这一通信机制。
spi简介
串行外设接口(spi)是器件间总线协议,实现芯片间的快速、同步、全双工通信。由一个主机驱动同步时钟,选择对哪些从机寻址。每个spi外设含有一个移位寄存器和控制电路,使被寻址的串行外设接口spi外设能够同时发送和接收数据。
图1. spi从机示意图
spi通信采用了四种不同的电路:
sclk:所有器件使用的同步时钟。主机驱动该时钟,从机接收时钟。注意,sclk可以被选通,不需要在spi操作之间进行驱动。
mosi:主机出,从机入。这是主机在spi总线上驱动所有从机的主要数据线。只有所选的从机同步来自mosi的数据。
miso:主机入,从机出。这是所选从机向主机发送时驱动的主要数据线。只有所选的从机可以驱动该电路。实际上,这是spi总线安排中允许从机驱动的唯一电路。
ssel:该信号在每一从机上都不同。当有效(通常为低电平)时,所选从机必须驱动miso。
对于这一讨论,需要特别说明的是,spi外设同时发送和接收。最简单的理解是主机总是发送一个字节,接收一个字节。
有些spi外设牺牲速率以模拟半双工工作。maxq3180微控制器没有采用这一方式,它是真正的全双工spi从机。
本应用笔记的其他部分介绍怎样连接并成功使用spi总线上的maxq3180。
maxq3180通信简介
对于主机,maxq3180看起来象一个存储器阵列,同时含有ram和rom。这是因为maxq3180中的rom固件读取ram的工作参数,将结果放到ram中。因此,配置maxq3180和对ram进行块写入一样简单。
有些maxq3180 “存储”位置触发器件内部操作,“随时”计算电表测量结果。向这些位置写入的是“nop”。对ram和虚拟rom位置特殊功能和目的的讨论已经超出了本文档的范围。此处最重要的是微控制器的确只有两种spi通信操作:读和写。
maxq3180中的每一次操作以主机发送两个字节开始,它含有命令(例如,读或者写)、要访问的地址、访问的字节数。如前所述,每个spi外设对接收到的每个字节返回一个字节。因此,maxq3180在接收到第一个命令字节后返回0xc1,第二个命令字节后返回0xc2。该协议显示在下面的图2中。
图2. 主机向maxq3180读写数据
如果主机读取一个或者多个字节,它必须发送空字节。记住,主机不能接收来自从机的任何信息,除非它发送某些信息:发送一个字节以得到一个字节。但是接收一条命令后,maxq3180要计算结果,当主机发送空字节时,它可能还没有准备好。出于这一原因,maxq3180总是在发送数据之前发送零或者nak字符等多个字节(0x4e或者ascii 'n'),随后是一个ack字符(0x41,或者ascii 'a')。
如果主机写入一个或者多个字节,发送命令后,它立即发送要写入的数据。maxq3180为每一个数据字节返回ack (0x41)。然后,它返回nak (0x4e),直到写周期完成,随后返回最终ack。
注意,最终ack之后,maxq3180立即准备开始下一操作;它不需要进行任何其他等待。它甚至不需要触发ssel以开始下一操作。maxq3180知道第一次操作已经完成,准备进行下一操作。
不论什么原因,如果需要复位主机和maxq3180之间的通信(例如,如果通信是异步的),从第一个命令字节重新启动通信之前,主机只需要等待200ms。200ms延时指示maxq3180,主机放弃了前面的操作。
命令字节
命令字节告诉maxq3180:
申请的操作是read还是write
操作的长度
ram中要改动的地址(或者要读取的虚拟rom地址)
图3. 命令字节结构
第一个命令字节(图3)告诉maxq3180,所申请的操作是read还是write,以及操作的长度。命令字节结构如下:
length code data length
0b00 1 byte
0b01 2 bytes
0b10 4 bytes
0b11 8 bytes
命令字节1的其他部分和所有的命令字节2提供要访问的ram字节的地址(或者一样的虚拟rom功能)。
主机软件设计
虽然maxq3180含有一个硬件spi控制器,rom固件中的软件程序还是要处理每一消息字节。出于这一原因,连续字节之间需要有延时。在当前的maxq3180型号中,这一延时不得小于100µs才能实现可靠的工作。请参考图4和图5。
图4. 读取maxq3180的流程图
图5. 写入maxq3180的流程图
代码清单
提供代码以实现具有内置spi主机的maxq2000微控制器和maxq3180的接口。其他微控制器用户需要提供自己的spi原语,还可能要修改高层子程序。
在下面的清单中,dly_us子程序使程序线程停止执行几个微秒。定义spi_timeout常数以提供比字符超时时间更长的参数。
在高层子程序中,采用enum按名称来选择寄存器。在其他参数中,它提供register_lookup_table阵列的索引,含有每个maxq3180寄存器的寄存器长度。请参考图6、图7和图8。
unsigned char send_spi(unsigned char x){ unsigned char y = 0; int z; int error = 0; spicn = 3; /* mstsm, spien */ z = 0; while ((spicn_bit.stby) && (++z < spi_timeout)); if (z == spi_timeout) error = 1; spicn_bit.spic = 0; /* clear transfer complete flag */ spib = x; z = 0; while ((!spicn_bit.spic) && (++z 8; regadd = reg_addr & 0xff; /* disable spi to reset it */ spicn_bit.spien = 0; for(x=0; x<300; x++); spicn_bit.spien = 1; spi_select_0; i = 0; while((send_spi(command_code)!= 0xc1)&&(++i < spi_command_retries)) spi_comm_timeout(); x = 0xffffffff; if (i == spi_command_retries) goto spierror; send_spi(regadd); i = 0; while((send_spi(0) != 'a') && (++i < spi_retries)); if (i == spi_retries) goto spierror; x = 0; for(i=0; i
8; regadd = reg_addr & 0xff; /* disable spi hardware to reset it */ spicn_bit.spien = 0; for(x=0; x<300; x++); spicn_bit.spien = 1; spi_select_0; i = 0; while((send_spi(command_code)!=0xc1)&&(++i (i * 8)) & 0xff); i = 0; while((send_spi(0) != 'a') && (++i < spi_retries));spierror: spi_deselect_0;} 图8. write_afe (spi_write)子程序代码
磐石测控:深圳转轴扭力试验机有什么介绍?
如何看待纯电动悍马皮卡?
浅谈滤波器在Wi-Fi 6E中的作用
5G+SD-WAN掀起广域网变局,华为打造企业上云的宽管道
5.5G毫米波通信时代,滤波器形态如何?
怎样使用MAXQ3180微控制器的串行外设接口
华为发文感谢库克,有大动作!
真空衰减法药品包装密封性检测仪
同步电路与异步电路有何区别
国内EDA的发展值得期待吗
诺基亚8什么时候上市?诺基亚8能砸核桃?等了这么久的诺基亚8会带给我们什么惊喜呢?
华为P11什么时候上市?华为P11最新消息:华为P11新专利逆天,全面屏配生物压感
外媒:华为MatePadPro平板电脑将会在11月25日推出
PN/PN Coupler使用入门
一文看懂锂离子电池电解液的机理与发展趋势
RFID天线必备的基础知识有哪一些
常见电缆故障_电缆故障点的查找
通过模仿沙漠蚂蚁的能力,设计出一种可以独立移动的机器人
让静电接地桩为你的生产保驾护航
基于CW32 MCU的智能充电宝解决方案