大家好、我使用的是 SPI 从编码器来获取位置数据、我在 TMS320F28335评估板(扩展坞/卡)上编译并运行代码一切都运行正常、现在我要尝试使用 tm32f28335 MCU 在我们自己的 PCB 控制器上实施、 尽管从器件通过 MISO 成功发送数据(通过逻辑分析仪确认)、但 SPI RXBUF 保持高电平、它不接收数据、但 SPI 配置和模式符合从器件(编码器)的要求。
我使用的代码如下
#包含 DSP28x_Project.h
#include stdio.h 设备头文件和示例 include 文件
#包含 global.h
#包含 prj_global.h
针对这个文件内找到的函数的 prototype 语句。
__interrupt void ISRTimer2 (void);
uint16 sdata_1 = 0x00;
uint16 sdata_2=0xA0;
UINT16 Lo_Posi = 200;
int16 Lo_Turn = 1;
Int16 Tu_Turn;
UINT16 POS_RDATA_1=0;
UINT16 POS_RDATA_2=0;
UINT16 Lo_Pos_ rdata_1=0;
UINT16 Lo_Pos_ rdata_2=0;
UINT16 Lo_Turn_ rdata_1=0;
UINT16 Lo_Turn_ rdata_2=0;
UINT16 TUR_RDATA_1;
UINT16 TUR_RDATA_2;
UINT16 TURN_RDATA_1;
UINT16 TURN_RDATA_2;
int LoadTurnFLAG = 0;
int TuneTurnFLAG = 0;
Int16 LoadPrevPosi;
Int16调谐器 PrevPosi;
int DataTuneTurn=2;
int DataLoadTurn=1;
UINT16温度普雷西;
Int16调谐器 PrevPosi;
Int16调谐位置;
Int16 LoadPrevPosi;
Int16 TotLoadPosition;
uint16 sdata_2;发送数据
UINT16 POS_RDATA_1;
UINT16 POS_RDATA_2;
UINT16 TUR_RDATA_1;
UINT16 TUR_RDATA_2;接收到的数据
Int16 Lo_Posi;
Int16 Lo_Turn;
Int16 Tu_Posi;
Int16 Tu_Turn;
Int 模式 ID;
sdata_2=0xA0;
UINT16 SPI_TxRx (UINT16 Tx)
{
SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;设置时钟极性(0表示上升沿、1表示下降沿)
SpiaRegs.SPICCR.bit.SPICHAR = 7;设置字长(7位)
SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
SpiaRegs.SPICCR.bit.SPISWRESET = 1;
while (SpiaRegs.SPISTS.bit.BUFFULL_flag==0)
{
}
while (SpiaRegs.SPISTS.bit.BUFFULL_flag!=0)
{
}
SpiaRegs.SPITXBUF=Tx;发送命令
UINT16 spiStatus = SpiaRegs.SPISTS.bit.INT_flag;
while (spiStatus=0)
{
等待
}
DELAY_US (1);
while (SpiaRegs.SPISTS.bit.INT_flag!=1)
{
}
UINT16 RDATA = SpiaRegs.SPIRXBUF;接收数据
&(((UINT32) 1 8)-1);
SpiaRegs.SPICCR.bit.SPISWRESET = 1;
返回 RDATA;
}
int parityCheck (uint16数据)
{int oddParity = 0;
Int evenParity=0;
INT I;
循环遍历16位数据中的每个位、
for (I = 0;I 13;I=I+2)
{
提取第 ITH 钻头
INT BIT =(DATA I)& 0x01;
用奇偶校验异或操作该位
偶校验^=位;
}
(i = 1;i 14;i=i+2)
{
提取第 ITH 钻头
INT BIT =(DATA I)& 0x01;
用奇偶校验异或操作该位
oddParity ^=位;
}
if ((oddParity===!(data15)&0x01)&&(evenParity===!((data14)&0x01))
{
返回1;
printf (n good);
}
否则
{
返回0;
printf (NBAD);
}
}
空 get_position()
{
GpioDataRegs.GPACLEAR.bit.GPIO19 = 1;
DELAY_US (2.5);
Lo_Pos_ rdata_1=SPI_TxRx (sdata_1);
Lo_Pos_ rdata_2=SPI_TxRx ((sdata_2) 8);
Lo_Turn_ rdata_1=SPI_TxRx (sdata_1);
Lo_Turn_ rdata_2=SPI_TxRx (sdata_1);
GpioDataRegs.GPASET.bit.GPIO19 = 1;
DELAY_US (20);
编码器2
GpioDataRegs.GPACLEAR.bit.GPIO23 = 1;
DELAY_US (2.5);
POS_RDATA_1=SPI_TxRx (sdata_1);
POS_RDATA_2=SPI_TxRx ((sdata_2) 8);
TUR_RDATA_1=SPI_TxRx (sdata_1);
TUR_RDATA_2=SPI_TxRx (sdata_1);
GpioDataRegs.GPASET.bit.GPIO23 = 1;
DELAY_US (20);
检查位
}结束 get_position
Uint16 get_prevPosition (MotID)
{
IF (MotID ==112)调优
{TuneTurnFLAG = 1;
UINT16转弯= TuneData.TurnCount;EEPROM
TemPrePosi=Turn4095;
}
ELSE (MotID =221)调优
{LoadTurnFLAG = 1;
UINT16转弯= LoadData.TurnCount;
010:EEPROM
TemPrePosi=Turn4095;
}
返回 TemPrePosi;
}
空 main (void)
{
uint16 sdata_1;
步骤1. 初始化系统控制
PLL、安全装置、使能外设时钟
此示例函数位于 DSP2833x_SYSCTRL.c 文件中。
InitSysCtrl();
步骤2. 初始化 GPIO
此示例函数位于 DSP2833x_GPIO.c 文件中、
说明了如何将 GPIO 设置为其默认状态。
InitGpio();为此示例跳过
仅设置仅用于 SPI-A 功能的 GP IO
此函数位于 DSP2833x_spi.c 中
InitSpiaGpio();
步骤3. 清除所有中断并初始化 PIE 矢量表
禁用 CPU 中断
Dint;
将 PIE 控制寄存器初始化为默认状态。
默认状态是禁用所有 PIE 中断并设置标志
都会被清除。
此函数位于 DSP2833x_PIECTRL.c 文件中。
InitPieCtrl();
禁用 CPU 中断并清除所有 CPU 中断标志
IER = 0x0000;
IFR = 0x0000;
使用指向 shell 中断的指针初始化 PIE 矢量表
服务例程(ISR)。
这将填充整个表、即使中断已在
未使用共模电压。 这对于调试十分有用。
在 DSP2833x_DefaultIsr.c 文件中可找到 shell ISR 例程。
此函数位于 DSP2833x_PieVect.c 中。
InitPieVectTable();
步骤4. 初始化所有器件外设
此函数可在 DSP2833x_InitPeripherals.c 中找到。
InitPeripherals();本示例不需要
spi_fifo_init ();初始化 SPI FIFO
SPI_init ();初始化 SPI
UINT32 sysclkFreq = CpuSysRegs.CPUCLKCR.bit.SYSCLKOUTDIV;
printf (fre %d、sysclkFreq);
步骤5. 用户特定代码
此示例中未使用中断。
for (;;)
空编码器()
{
发送数据
GpioDataRegs.GPACLEAR.bit.GPIO19 = 1;
DELAY_US (2.5);
SPI_xmit (sdata_1);
DELAY_US (5);等待直到接收到数据
while (SpiaRegs.SPIFFRX.bit.RXFFST!=1){}
检查已发送的数据
RDATA_1 = SpiaRegs.SPIRXBUF6;
DELAY_US (20);
GpioDataRegs.GPASET.bit.GPIO19 = 1;
SPI_xmit (sdata_1);
DELAY_US (5);等待直到接收到数据
RDATA_2 = SpiaRegs.SPIRXBUF2;
DELAY_US (20);
GpioDataRegs.GPASET.bit.GPIO19 = 1;
uint16 posi=((RDATA_1)(RDATA_2))和(0xFFF);
DELAY_US (40);
sdata_2=sdata_28;
编码器1
Lo_Posi =(((Lo_Pos_ rdata_26)(Lo_Turn_ rdata_12)))&(0xFFF);
Lo_Turn =((Lo_Turn_ rdata_2)(POS_RDATA_1))和(0x3FFF);
get_position();
编码器2
A
GpioDataRegs.GPBCLEAR .bit.GPIO57 = 1;
DELAY_US (2.5);
POS_RDATA_1=SPI_TxRx (sdata_1);
DELAY_US (20);
POS_RDATA_2=SPI_TxRx ((0xA0) 8);
DELAY_US (20);
TUR_RDATA_1=SPI_TxRx (sdata_1);
DELAY_US (20);
TUR_RDATA_2=SPI_TxRx (sdata_1);
DELAY_US (25);
GpioDataRegs.GPBSET.bit.GPIO57 = 1;
DELAY_US (40);
检查位
GpioDataRegs.GPACLEAR.bit.GPIO19 = 1;
DELAY_US (2.5);
Lo_Pos_ rdata_1=SPI_TxRx (sdata_1);
DELAY_US (10);
Lo_Pos_ rdata_2=SPI_TxRx ((sdata_2) 8);
DELAY_US (10);
Lo_Turn_ rdata_1=SPI_TxRx (sdata_1);
DELAY_US (10);
Lo_Turn_ rdata_2=SPI_TxRx (sdata_1);
DELAY_US (10);
GpioDataRegs.GPASET.bit.GPIO19 = 1;
DELAY_US (40);
if (parityCheck ((Lo_Pos_ rdata_28)(Lo_Turn_ rdata_1))& parityCheck ((Lo_Turn_ rdata_2) 8 (POS_RDATA_1)))
{
if (parityCheck ((Lo_Turn_ rdata_2) 8 (POS_RDATA_1)){
Lo_Turn =((Lo_Turn_ rdata_28)(POS_RDATA_1))和(0x3FFF);
INT Lo_Posi =(((Lo_Pos_ rdata_2) 6 (Lo_Turn_ rdata_1) 2)和(0xFFF);
IF (Lo_Turn 16127)
{
Lo_Turn = Lo_Turn - 16128;
}
否则
{Lo_Turn = Lo_Turn - 16128;
Lo_Posi = Lo_Posi 452-4095;
}
如果(Lo_Turn == 255)
{
Lo_Turn = 0;
}
if (Lo_Turn ==-256)
{
Lo_Turn =-1;
}
LoadData.TurnCount= Lo_Turn;
Lo_Posi = Lo_Turn Lo_Posi;
while (!TurnLoadFLAG)
{
int modrID =221;负载
LoadPrevPosi=get_prevPosition (modrID);上一个位置
}
LoadTotPosition = Lo_Posi;
Motor_Pos =装载位置;
}
否则
{
转至 A;}
}
否则
{
转至 A;
重新尝试,直到数据正常
编码器2
if (parityCheck ((POS_RDATA_28)(Tur_RDATA_1))和 parityCheck ((Tur_RDATA_28)(Lo_Pos_ rdata_1))
{int Temp_Tu_Posi =(((POS_RDATA_2) 6 (TUR_RDATA_1) 2))&(0xFFF);
if (parityCheck ((TUR_RDATA_28)(Lo_Pos_ rdata_1)){
Tu_Turn =((TUR_RDATA_28)(Lo_Pos_ rdata_1))和(0x3FFF);
Tu_Turn = 150;
IF (Tu_Turn 1000)
{
Tu_Turn = Tu_Turn - 16383;
INT Temp_Tu_Posi = Temp_Tu_Posi-4095;
}
否则{
Tu_Turn = Tu_Turn + 1;
}
TuneData.TurnCount= Tu_Turn;
Tu_Posi = Tu_Turn 4095+ Temp_Tu_Posi;
while (!TuneTurnFLAG)获取上一位置、此代码仅在启动时运行一次
{
内部模式 ID =112;调优
TunePrevPosi=get_warpPosition (modrID);
TunePosition=TunePrevPosi+Tune; Tu_Posi
}
tuneTotPosition = tunePrevPosi+Tune;Tu_Posi
Motor_Pos = TunePrevPosi+Tunesi; Tu_Posi
}
否则
{
转至 A;
}
相对于位置的总位置、与匹配器关闭前的位置相同
}
否则
{
转至 A;
}
}
步骤7. 在此插入所有本地中断服务例程(ISR)和函数
void spi_init()
{
开启复位、上升沿、16位 char 位
SpiaRegs.SPICTL.ALL =0x0006;启用主模式、正常相位、
启用 Talk、并禁用 SPI int。
SpiaRegs.SPIBRR = 0x007F;
SpiaRegs.SPICCR.all =0x009F;从复位撤回 SPI
SpiaRegs.SPIPRI.bit.free = 1;设置为使断点不会干扰 xmission
初始化 SPI 配置寄存器
SpiaRegs.SPICCR.bit.SPISWRESET = 0;
SpiaRegs.SPICCR.all = 0x0007;复位 SPI 配置
SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;设置时钟相位(0表示正常、1表示延迟)
SpiaRegs.SPICTL.bit.CLK_PHASE = 1;设置时钟极性(0表示上升沿、1表示下降沿)
SpiaRegs.SPICCR.bit.SPICHAR = 7;设置字长(7位)
SpiaRegs.SPICCR.bit.SPILBK=0;
SpiaRegs.SPICTL.ALL = 0x0006;复位 SPI 控制
SpiaRegs.SPICTL.bit.talk = 1;启用传输
SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;设置 SPI 模式(1表示主器件、0表示从器件)
SpiaRegs.SPIBRR = 0x000F;设置波特率
SpiaRegs.SPIBRR = 0x0054;
SpiaRegs.SPICTL.ALL = 0x0006;复位 SPI 控制
SpiaRegs.SPIFFTX.ALL = 0xC000;复位 SPI FIFO 发送
SpiaRegs.SPIFFTX.bit.TXFIFO = 1;启用 SPI FIFO 发送
SpiaRegs.SPICCR.all = 0x000F;
SpiaRegs.SPICCR.bit.SPISWRESET = 1;启用 SPI
EALLOW;
启用所选引脚的内部上拉
用户可启用或禁用上拉。
这将启用指定引脚的上拉电阻。
注释掉其他不需要的行。
GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0;启用 GPIO16上的上拉(SPISIMOA)
GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;启用 GPIO17上的上拉(SPISOMIA)
GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;启用 GPIO18上的上拉(SPICLKA)
GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;启用 GPIO19上的上拉(SPISTEA)
GpioCtrlRegs.GPBPUD.bit.GPIO54 = 0;启用 GPIO54上的上拉电阻(SPISIMOA)
GpioCtrlRegs.GPBPUD.bit.GPIO55 = 0;启用 GPIO55上的上拉(SPISOMIA)
GpioCtrlRegs.GPBPUD.bit.GPIO56 = 0;启用 GPIO56上的上拉(SPICLKA)
GpioCtrlRegs.GPBPUD.bit.GPIO57 = 0;启用 GPIO57上的上拉(SPISTEA)
将所选引脚的鉴定设置为仅异步
这将为所选引脚选择异步(无限定条件)。
注释掉其他不需要的行。
GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3;异步输入 GPIO16 (SPISIMOA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3;异步输入 GPIO17 (SPISOMIA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3;异步输入 GPIO18 (SPICLKA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3;异步输入 GPIO19 (SPISTEA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO54 = 3;异步输入 GPIO16 (SPISIMOA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO55 = 3;异步输入 GPIO17 (SPISOMIA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO56 = 3;异步输入 GPIO18 (SPICLKA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO57 = 3;异步输入 GPIO19 (SPISTEA)
使用 GPIO 寄存器配置 SPI-A 引脚
这可以指定哪个 GPIO 引脚将是 SPI
功能引脚。
注释掉其他不需要的行。
GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1;将 GPIO16配置为 SPISIMOA
GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1;将 GPIO17配置为 SPISOMIA
GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1;将 GPIO18配置为 SPICLKA
GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1;将 GPIO19配置为 SPISTEA
GpioCtrlRegs.GPBMUX2.bit.GPIO54 = 1;将 GPIO54配置为 SPISIMOA
GpioCtrlRegs.GPBMUX2.bit.GPIO55 = 1;将 GPIO55配置为 SPISOMIA
GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 1;将 GPIO56配置为 SPICLKA
GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 1;将 GPIO57配置为 SPISTEA
EDIS;
}
void spi_xmit (UINT16 A)
{
}
void spi_fifo_init ()
{
初始化 SPI FIFO 寄存器
SpiaRegs.SPIFFTX.All=0xE040;
SpiaRegs.SPIFFRX.All=0x204f;
SpiaRegs.SPIFFCT.all=0x0;
}
========================================
现在情况变了。
========================================

