【芯片驱动】1. 详细解析CMT2300A

1. 前言

        半年前曾经接触到微功率无线。其实无关是射频芯片还是普通的采集数据的芯片,大部分都是有相应的总线驱动,而最常使用的就是IIC、SPI之类的通信协议。像一些有特殊功能的芯片,往往是基于这些通信协议,拓展的去进行控制其他的引脚去达到设置某值或者获取某值,这就需要仔细的研读芯片文档以及芯片厂家。

        再回头说说该芯片,国产的,嗯,便宜;文档详细;技术支持人员及时解答疑惑;可以进行快速开发。性能及稳定性,这就要看在什么样的平台上使用。至少接触的这个项目应用上,在有操作系统的平台上,保证了它的性能。

        射频芯片需要进行频点设置、调制解调、数据包格式、发送功率、接收检测等一系列的设置,并且射频芯片是为了适应各种场合的数据包格式,往往是可以灵活的去设置。很多寄存器只需要设置一遍,或者是我们不要去理解的设置。所以,芯片厂家会给开发者配置软件、已经Demo。这些工具可以通过技术支持人员获取,也可以从厂家官网上获取。

        所以接下来,会依次介绍配置软件、调试工具的使用的。配置软件只是介绍常用的,特殊功能的,还是需要详细阅读芯片开发文档。

2. CMOSTEK RFPDK V1.46配置软件的使用

        顾名思义,该软件生成的配置文件,经过转换可以生成.h头文件,应用在项目初始化中。而且该软件还配合厂家的调试板和调试工具,可以快速使用生成的配置文件进行收发测试。调试工具如下图:

2.1 软件的安装及使用

        去官网或者厂家获取软件,默认安装,直至安装完成。

2.2 软件操作及部分关键参数说明

        打开软件,选择芯片,如下图。如果未插入调试板的USB,会有一个弹窗警告,可以忽略。

        点击Next后,进入到设置界面。以下是因为已经有配置过其他的,所以保留了5条配置信息在其中。接下来我配置一个起始频点433.5MHz,GFSK调制解调,有前导码,同步字,数据域白化,数据末尾不进行crc校验(因为校验算法和项目预期的不一样,这一点互联互通的项目可能大几率会遇到)

        中间的RF Setting是射频的基础设置,最下发的可切换板块是具体设置。需要注意的是:OOK调试和GFSK是根据RF Setting的选择进行选择配置了,配置对应的选项就可以了。

        特别注意的是频点和发射功率,这里理论的,实际的值受硬件影响,需要硬件调制晶体进行校正。该芯片内部没有可调电容进行频点的动态调整,在产测的时候就少了校准的这个步骤,这是存在不足的地方的。字节序也需要注意,特别是互联互通时,需要根据约定的协议文档进行相关配置。如下图:        

        Operation Setting类似与一些特殊功能的设置选项,比如低功耗接收功能。注意:这里的设置并非一劳永逸的设置,只是在初始化的时候对其进行设置一遍,如果在项目中一直处于这样的设置状态下进行接收的话(未修改其他寄存器),这样是可以连续只做等待接收。但是如果在实际应用中还要处理其他,比如动态的修改睡眠时间、切换状态、切换频点等,那么相关寄存器就会被修改。所以,最稳妥的方法就是,要着重了解相关功能的寄存器,封装需要的函数。

       这里说的了解寄存器,不要全局理解,技术文档也说明了大部分是不需要用户去了解的,所以这一点不用担心。下面的配置中,我们配置成非低功耗模式,也就是不使用这个特殊功能,用不到则关闭掉即可。如下图:

        Baseband 1 Settings 可以设置数据类型,这里分为固定的包类型,和直发模式。直发模式没使用过,具体需要参看相应的文档。

        这里有开启数据白化,包括设置白化算法,白化种子。收发设置需要匹配,否则数据收发不一致。另外Tx Packet Number这个选项是设置一个数据包发送几次,可根据项目要求进行设置。比如说一个数据包需要重发N次,芯片内部重发,不需要我们重新向fifo写数据进行发送。

        Baseband 2 Setting 如下图。看到我们选择了定长包类型。点击Preamble前导码设置,接收前导码检测一般不需要完整的全部检测,检测几个就好。发射前导码根据需要设置,前导码的值是01010101还是10101010或其他。

        注意:要设置好字节序!

同步字设置,包括同步字长度,同步字的值,同步字容错。这里需要注意的是:同步字的值是倒叙的,需要转换成二进制倒叙来确认。如下图:

payload长度。这里知识为了初始化,或者是项目要求固定长度,以后都不再改的。但是在实际项目中,数据包是变长的,需要修改长度,那时就需要根据需要修改寄存器即可。

CRC检验选择,这里不使用硬件校验。该功能需要实际验证,我这样不使用的原因是:他的硬件校验生成的校验和软件校验不一致,是芯片的原因。芯片文档有说你crc检验成功的中断,关闭该校验就默认关闭那个中断,具体请查看文档。

        Feature Settings设置检测rssi的机制。厂家技术说“RSSI最好收完包在读取,rssi检测滤波需要时间,同步字中断产生后立马读可能不是当时的rssi值”,但是按照他的说法,我实际测试在接收完后进行读取rssi,更加不准确,所以我觉得应该是在读到同步字后读取rssi,因为同步字中断后,后续肯定还有数据接收,只不过是接收数据的长短而已。这句话有待进一步研究。

配置好后,list保存起来。

导出.exp文件。至此,配置文件添加完成。有将.exp文件转换为.h文件的脚本工具。鉴于那么人关注和私信需要脚本文件,我就把源码贴在博客后。

3. CMOSTEK RFPDK V1.46配合原厂调试工具使用

        图一有提到,原厂会给一个调试Demo板。是的,如果有两个,就可以进行无线收发测试。当然,如果只有一个,那么也可以验证自己配置的exp文件频点是否正确。说白了,该工具如果与现有的射频模块进行调试的话,该工具支持单频点的接收、单频点的发射以及单频道的信道扫描(图形化的显示当前频点空中信道是否忙,是否有射频收发)。接下来会依次接收它的使用。

        接上USB,该软件会自动识别该USB串口,不需要我们手动去选择,除非电脑驱动不支持,那么请自己捣鼓支持吧。

        选择list中的某个配置(这里选择433.5MHz),点击Test->RF Communication Test。

        此时会有三个切换窗口,Transmitter,发送数据,注意发送次数和发送间隔。另外,经过我实测,V1.46版本的,只能发送32个字节,不管写多长,不知道是我电脑串口问题还是其他问题。如果你们使用的时候,请注意是否有该问题。灰色部分不能修改,该部分的配置是在上一步设置中配置好的。填好需要发送的数据、发送次数和发送间隔后,点击start,就可以看到正在发送,并且有发送计数。如下图:

        Receiver,接收,点击start则开始监控该信道同步字匹配的数据。这里需要注意两点。第一,接收的包长度是32个字节,灰色不能在这里修改,应该是在配置中修改,我尝试了一下没找到就没继续研究。第二,因为是两个同步字,如果空中不忙的话,刷出来的时候不多,如果是一个同步字的话,空中很多杂波,会被解调匹配,此时会看到接收到很多杂波数据,所以需要自己去看是否有是自己测试发出来的。

        该接收工具不能作为监控数据正确的唯一依据,因为它非常不严谨,它只是把自己收到的东西全部打印出来,不管对错。所以该工具只能说明是否有数据收发,不能说明数据的完全正确。数据的完全正确需要在自己项目中进行严谨的检验判断。

        RSSI Scan 无线信道忙扫描。顾名思义,图形化的显示当前频点上是否有数据正在传输,当RSSI越大,说明该信道在忙,有数据在传输,效果就像是示波器显示一般。该工具只是为证明该信道在某个时间点是否忙,是否有数据传输,传输持续时间。注意:这只是粗略的,因为耦合性较高,依赖与Demo板硬件以及exp配置。所以想知道发送功率已经频点,最稳妥的方式是在频谱仪等专业仪器上检测。

4. 总结

        以上只是介绍了exp文件的生成及相关工具的使用。一般来说,如果是刚刚接触射频,那么就需要去了解射频本身的一些知识,比如说频点、发送功率、接收灵敏度、频偏、数据包格式、前导码、同步字等。了解这些之后才能理解以上的配置,或者是说,多尝试几下就可以理解。如果是老司机,我相信老司机们肯定还做了其他的的射频芯片开发,配置的原理是一样的,相信可以更快的上手。

附上转换的python脚本源码:

若代码格式未对齐,也可到我github下载:https://github.com/ZhenhuaWei/Python-Demo.git

# coding=utf-8
import sys,os
import codecs
import re
		
def cmt2300a_import_hex(strFile):
	input = codecs.open(strFile, 'r', 'utf-8')
	arr8 = [0] * 0x60
	count = 0
	
	for line in input:
		line = line.replace('\r', '').replace('\n', '').replace('\t', '').strip()
		if(line=="") or (line[0]==';') or (line[0]=='[') or (line.find('Addr')>=0):
			continue
		
		arr = re.findall('0[xX][0-9A-Fa-f]+', line)
		
		if len(arr) >= 2:
			addr = int(arr[0], 16)
			arr8[addr] = int(arr[1], 16)
			
	input.close()
	
	return arr8
	
def cmt2300a_convert_hex(strSrcFile, strDstFile, strSubfix):
	output = codecs.open(strDstFile, 'w', 'utf-8')
	arr8 = cmt2300a_import_hex(strSrcFile)
	
	output.write('#ifndef __CMT2300A_PARAMS' +strSubfix.upper()+ '_H\r\n')
	output.write('#define __CMT2300A_PARAMS' +strSubfix.upper()+ '_H\r\n')
	output.write('\r\n')
	
	output.write('/* [CMT Bank] */\r\n')
	output.write('const u8 g_cmt2300aCmtBank' +strSubfix+ '[CMT2300A_CMT_BANK_SIZE] = {\r\n')
	for i in range(0x00, 0x0C):
		str = "    0x%02X," %(arr8[i])
		output.write(str +'\r\n')
	output.write('};\r\n\r\n')
	
	output.write('/* [System Bank] */\r\n')
	output.write('const u8 g_cmt2300aSystemBank' +strSubfix+ '[CMT2300A_SYSTEM_BANK_SIZE] = {\r\n')
	for i in range(0x0C, 0x18):
		str = "    0x%02X," %(arr8[i])
		output.write(str +'\r\n')
	output.write('};\r\n\r\n')
	
	output.write('/* [Frequency Bank] */\r\n')
	output.write('const u8 g_cmt2300aFrequencyBank' +strSubfix+ '[CMT2300A_FREQUENCY_BANK_SIZE] = {\r\n')
	for i in range(0x18, 0x20):
		str = "    0x%02X," %(arr8[i])
		output.write(str +'\r\n')
	output.write('};\r\n\r\n')
	
	output.write('/* [Data Rate Bank] */\r\n')
	output.write('const u8 g_cmt2300aDataRateBank' +strSubfix+ '[CMT2300A_DATA_RATE_BANK_SIZE] = {\r\n')
	for i in range(0x20, 0x38):
		str = "    0x%02X," %(arr8[i])
		output.write(str +'\r\n')
	output.write('};\r\n\r\n')
	
	output.write('/* [Baseband Bank] */\r\n')
	output.write('const u8 g_cmt2300aBasebandBank' +strSubfix+ '[CMT2300A_BASEBAND_BANK_SIZE] = {\r\n')
	for i in range(0x38, 0x55):
		str = "    0x%02X," %(arr8[i])
		output.write(str +'\r\n')
	output.write('};\r\n\r\n')
	
	output.write('/* [Tx Bank] */\r\n')
	output.write('const u8 g_cmt2300aTxBank' +strSubfix+ '[CMT2300A_TX_BANK_SIZE] = {\r\n')
	for i in range(0x55, 0x60):
		str = "    0x%02X," %(arr8[i])
		output.write(str +'\r\n')
	output.write('};\r\n\r\n')
	
	output.write('#endif\r\n')
	
	output.close()
	
cmt2300a_convert_hex('F470p7_DR192_DV100_TxP20_BWauto_Counting.exp', 'cmt2300a_params.h', '')

参考资料:

原厂技术支持提供CMT2300A开发资料包

  • 12
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
首先,需要了解CMT2310A芯片的功能和接口,以及STC8H1K28单片机的IO口和相关寄存器的使用方法。 CMT2310A芯片主要用于驱动蓝牙音频设备,它包含一个32位RISC处理器和完整的蓝牙协议栈。STC8H1K28单片机是一款高性能、低功耗的8位单片机,具有自带ISP(In-System Programming)功能和多个IO口,可以用于控制各种外围设备。 接下来,我们可以按照以下步骤来实现STC8H1K28单片机驱动CMT2310A芯片: 1. 通过STC8H1K28单片机的IO口连接CMT2310A芯片,包括UART、模拟音频输入输出、I2C等。其中,UART用于与CMT2310A芯片进行数据交换,模拟音频接口用于控制音频输入输出,I2C用于配置CMT2310A芯片的相关参数。 2. 在STC8H1K28单片机上编写软件程序,通过读写相关寄存器的方式,实现控制CMT2310A芯片的功能。包括初始化、配置、音频数据输入输出等。 3. 调试和优化程序,确保STC8H1K28单片机与CMT2310A芯片的通信稳定可靠,音频输入输出正常。 4. 可以根据具体的应用需求,增加其他功能,如蓝牙配对、码率控制等。 需要注意的是,在使用STC8H1K28单片机驱动CMT2310A芯片时,需要对CMT2310A芯片进行一定的了解,包括其内部处理器结构、数据传输协议等,才能根据需要进行合理的数据读写操作。同时,还需要注意软件编程的可读性、可维护性和可扩展性,以便后期的调试和维护工作。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值