Dsp28335开发实例(AD采样)——Spi通信读取ADS8688外设数据
前言:
DSP28335是比较经典的单片机,版主以前只接触过STM芯片,并且自诩其为嵌入式开发,实际上只是皮毛内容,所学到的程序设计和操作方法也都是在大量教程和教学视频中迁移学习的。这次由于需要,再次捡起了嵌入式(或者说单片机)开发。第一阶段,设计了变换器驱动程序,第二阶段,为了保证控制效果,使用了电流闭环,但是由于DSP自带的AD采样出现了不小的问题(跳变严重,达到0.5V量级),因此不得已使用其他AD模块来采样。在此过程中,不仅从稀少的资料中爬了出来,还更加理解了SPI协议的相关内容,特此做一点笔记,从而提醒自己,又帮助后来者。
一、整体概况:
硬件:
DSP28335(Ti公司的主控芯片,整个套件为普中科技售卖的成品)
ADS8688模块(Ti公司的芯片,模块为淘宝xx科技店铺成品)
不含总线解析功能的示波器(哭辽xxxxxx)
软件:
CCS12.5.0
技术目标:
捋清SPI通信逻辑,采用常见的主从模式(单一从设备),实现ad的单路采集(8688本身支持8通道,当然8通道读取和1通道也没啥差别,只是多一块分时复用或者说Auto模式的使用罢了)
最终结果:
读取数据ok,通信正常,【但是从机8688传回来的数据最后一位电平有延迟上拉的情况,比较奇怪。MISO信号线】
二、注意事项:
1、芯片手册:
DSP本身的SPI寄存器说明有点晦涩难懂,部分Reg的使用和Stm系列不太一样,但是秉持着对SPI协议本身的理解,还是在尝试之后找到了适合配置的方式,这里,主要需要注意一下几点;
(1)IO口:dsp的spi属于硬件spi,不需要软件模拟时序,并且附带两套io口(都是SPIA),需要注意其中的复用特征,主要是和SMG、SCI协议等有冲突,因此需要选择没有被占用的端口,特别的,【两套IO口可以混用】;一套为54——57端口,一套为16-19端口,可以灵活替换;
(2)时钟极性:所谓时钟极性,我们需要关注的就是空闲时为何种电平;(由于8688需要低电平,因此对应着进行配置);
(3)时钟相位:在Reg手册说明中,发现涉及到一个【半周期】的说明,其实就是Stm芯片中的选择第几个周期(1or2),因此可以实现在下降沿采样还是上升沿采样;
(4)时钟:另外,我严重怀疑28335的时钟这一块不太对劲,其写道:数据在上升沿输出且在下降沿输入(or opp),这和stm的时序不一样,其输入和输出是在一个边沿处理的:
此图从野火资料中截取,可以看到其MOSI和MISO数据采样边沿是一致的;
此图从28335手册中截取,可以看到明确说明采样边沿不一样;
(5)自测模式:为了调试方便,可以使用自测来检验主机输出数据是否正常;值得注意的是,【其MISO线上的数据和调试中从Rxbuff中读取的结果不一致】,疑似软件内部有猫腻;需要注意在实际通信中屏蔽这个bit;
(6)中断:本工程字符长度有限,不涉及FIFO,也不需要中断来频繁处理,因此只使用默认的发送/接受中断标志位INTFLAG,这就足够我编写数据发送的函数了;
(7)CS片选:由于ADS中数据发送长度不定长,涉及到16bit和32bit数据分别发送;【这里我要说一下ads模块的卖家,提供的其他开放平台例程中说通信使用8bit,这是不准确的,尤其是ads手册本身就没提过8bit,而是正常的16bit数据传输】
因此,为了方便灵活配置片选信号,需要屏蔽硬件SPI的CS口配置,设置为通用IO,上拉、输出;
片选信号示意图以及40us左右的数据传输示意图:
(8)波特率:ADS并没有指定的Baud设置参数,因此可以选择一个速度不是很快的传输,实际试验发现,达到40us级别的传输间隙都是可以实现的;
2、操作时序:
SPI协议与串口、SCI等不太一样,通过Tx-Rx交错连接,并且有校验等功能;整个SPI是一种循环数据传输,通过移位寄存器,由主机端逐位发送给从机,从机也同时发送响应信号,因此同一时间段上SIMO和SOMI上都有数据,但是显然,从机的响应信号并不是与此刻信号对应的,往往是对上一次信号的回应。因此我们会发现,很多程序编写时,会发送一个空信号给从机,然后接受其返回的结果;整个数据移位传输的样子可以从寄存器的比特流传输示意图窥得:
3、ADS的命令配置和操作:
根据手册可以得知,它的SPI操作线不是简单的三线或者四线,因此部分IO口需要额外配置通用io来产生逻辑电平:
其中,SCLK、SDI、SDO、CS都是常见的SPI通信线,额外的RST和DAISY分别为:复位(下电模式)和菊花链接口;其中,RST一般采用拉低一段时间的方法,实现寄存器复位和下电状态,菊花链则在多从机需要串联时用到。
按照以下顺序可以实现ads初始化:
(1)RST合理拉低,实现复位;
(2)DAISY拉低,不使用;
(3)软件复位模式;
(4)设置输入通道;
(5)退出下电模式;
(6)多通道自动排序;
(7)指定通道;
读数据时,按照以下顺序即可:
(1)指定通道——16bit数据输出;
(2)16bit0x0000数据输出,并再次产生时钟信号,接受16bit数据输入;(在同一个CS片选下实现,否则数据错误)
三、程序部分:
void GPIO_ADS8688_Configuration(void) { EALLOW; SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; GpioCtrlRegs.GPBMUX2.bit.GPIO60=0; GpioCtrlRegs.GPBMUX2.bit.GPIO61=0; GpioCtrlRegs.GPBMUX2.bit.GPIO62=0; GpioCtrlRegs.GPBDIR.bit.GPIO60=1; GpioCtrlRegs.GPBDIR.bit.GPIO61=1; GpioCtrlRegs.GPBDIR.bit.GPIO62=1; GpioCtrlRegs.GPBPUD.bit.GPIO60=0; GpioCtrlRegs.GPBPUD.bit.GPIO61=0; GpioCtrlRegs.GPBPUD.bit.GPIO62=0; EDIS; }
void ADS8688_Init(void) { GPIO_ADS8688_Configuration(); SPIA_Init(); RST_L; Delay_1us(20); RST_H; DAISY_L; CS_L; ADS8688_Write_Command(RST); CS_H; Delay_1us(2); ADS8688_Write_Program(CH0_INPUT_RANGE, VREF_B_125); ADS8688_Write_Program(CH_PWR_DN, 0x00); ADS8688_Write_Program(AUTO_SEQ_EN, 0xFF); CS_L; ADS8688_Write_Command(MAN_CH_0); CS_H; Delay_1us(2); }
Uint16 Get_MAN_CH_Data(Uint16 ch) { Uint16 Rxdata; CS_L; SPIA_SendReciveData(ch); CS_H; Delay_1us(20); CS_L; SPIA_SendReciveData(0x0000); Rxdata = SPIA_SendReciveData(0x0000); CS_H; Delay_1us(20); return Rxdata; }
void InitSpiaGpio() { EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0; GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0; GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;
GpioCtrlRegs.GPBPUD.bit.GPIO55 = 0; GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3;GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3;GpioCtrlRegs.GPBQSEL2.bit.GPIO55 = 3; GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1;GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 0; GpioCtrlRegs.GPADIR.bit.GPIO19 = 1; GpioCtrlRegs.GPBMUX2.bit.GPIO55 = 1;
EDIS; }
四、结果图片:
时钟信号与采样信号:
最后,提醒自己,注意寄存器相关说明,并根据个人理解简化,对模糊地方直接试验;
Tip:
参考TI官方文档(TI官网免费下载);
重点推荐符晓编写的<TMS320F28335原理、开发及应用>。
重点不推荐张卿杰的<手把手教你学DSP>。
The END
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)