This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] RTOS/EK-TM4C123GXL:为什么 SPI 不能与计时器配合使用

Guru**** 2460850 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/653895/rtos-ek-tm4c123gxl-why-spi-does-not-work-with-timer

器件型号:EK-TM4C123GXL
Thread 中讨论的其他器件:SYSBIOS

工具/软件:TI-RTOS

尊敬的 TI 团队:

我尝试在 TM4C123GXL 评估套件中将 SPI 与 Timer4A 周期性计时器配合使用。 当我单独运行 SPI 和计时器时、它会起作用。 当我将它组合在一起时、它会失败。 当我运行时、有一个奇怪的行为、

SPI0_init();
Timer4_init();

它的工作原理。 当我跑步时、

Timer4_init();
SPI0_init();

它失败了。 它在行- SPI_TRANSFRAT...中失败。 这是它的输出

系统提供商设置为 SysMin。 停止目标以查看 ROV 中的任何 SysMin 内容。
初始化计时器
完成
打开 SPI [OK]
E:0x20000400。
任务堆栈大小:0x400。
R0 = 0x00000000 R8 = 0x0000842c
R1 = 0x400ff028 R9 = 0xffffffff
R2 = 0x00000001 R10 = 0xffffffff
R3 = 0x00000008 R11 = 0xffffffff
R4 = 0x00008634 R12 = 0x000000a0
R5 = 0x00000000 SP (R13)= 0x20000748
R6 = 0x200007a8 LR (R14)= 0x00003189
R7 = 0x200007c0 PC (R15)= 0x00003188
PSR = 0x01000000
ICSR = 0x0041717
MMFSR = 0x00
BFSR = 0x00
UFSR = 0x0000
HFSR = 0x00000000
DFSR = 0x00000001
MMAR = 0xe000ed34
BFAR = 0xe000ed38
AFSR = 0x00000000
正在终止执行...

在 ROV 调试中、没有 BIOS 错误、但是 HWI 中有一个解码的异常、未定义的 Hwi:23。 下面将更详细地介绍齿槽。

我在 TivaC 版本2.16.1.14、TI 编译器版本5.2.6、CCS 版本6.2.0.00050中使用了 tirtos
我使用 tirtos 空项目模板创建了项目

我的问题是
1) 1)为什么我无法使 SPI 和计时器同时工作?
2) 2)当我运行 Timer4_init ()、然后运行 SPI0_init ()时、是什么原因导致它失败

这是我的完整代码和调试。 请帮助。

谢谢、

Sarawin

//=================== empty.c ==================== /

/* XDCtools 头文件*/
#include
#include

/* BIOS 头文件*/
#include
#include
#include

/* TI-RTOS 头文件*/
#include
#include
//#include
#include
#include
//#include
//#include

#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/interrupt.h"
#include "driverlib/rom.h"
#include "driverlib/timer.h"
#include "driverlib/sysctl.h"

/*板头文件*/
#include "BoardConfig.h"

#define TASKSTACKSIZE  1024

Task_Structtask0_Struct;
char task0_stack[TASKSTACKSIZE];

静态 SPI_Handle spiHandle =空;

静态空 Timer4_init (空);
静态空 Timer4_intHandler (空);
静态空 SPI0_init (空);

静态空 Timer4_init()

 system_printf ("init timer\r\n");
 system_flush();

 SysCtlPeripheralEnable (SYSCTL_Periph_TIMER4);
 TimerConfigure (TIMER4_base、TIMER_CFG_A_PERIODICRACASE);

 // IntPrioritySet (INT_TIMER4A、4<<5);
 TimerIntRegister (TIMER4_base、TIMER_A、Timer4_intHandler);

 uint32_t const freq = SysCtlClockGet ();// freq = 80 000 000 000 = 80MHz
 uint32_t const 周期= freq >> 2;//溢出周期= 1秒
 TimerLoadSet (TIMER4_base、timer_A、period);

 IntMasterEnable();
 TimerIntEnable (TIMER4_base、TIMER_TINA_TIMEOUT);
 IntEnable (INT_TIMER4A);
 TimerEnable (TIMER4_base、TIMER_A);

 System_printf ("done \r\n");
 system_flush();


静态空 Timer4_intHandler (void){
 TimerIntClear (TIMER4_base、TIMER_TINA_TIMEOUT);
 GPIO_TOGGLE (Board_LED1);


静态空 SPI0_init (空)

 SPI_Params spiParams;
 SPI_Params_init (&spiParams);
 spiParams.bitrate = 80000;
 spiParams.frameFormat = SPI_POL0_PHA0;

 spiHandle = SPI_open (Board_SPI0、&spiParams);
 if (spiHandle == NULL){
   System_printf ("打开 SPI [失败]\r\n");
   system_flush();
   while (true);
 }

 System_printf ("打开 SPI [OK]\r\n");
 system_flush();

 SPI_Transaction 事务;
 uint8_t txBuf[4];
 uint8_t rxBuf[4];
 transaction.count = 4;
 transaction.txBuf = txBuf;
 transaction.rxBuf = rxBuf;

 uint8_t addr = 0x00;
 uint32_t val = 0x000000;

 txBuf[0]= addr;
 txBuf[1]=(uint8_t)((val>>16)&0xFF);
 txBuf[2]=(uint8_t)((val>>8)&0xFF);
 txBuf[3]=(uint8_t)((val>>0)&0xFF);

 SPI_transfer (spiHandle、&transaction);

 SPI_Close (spiHandle);


静态空 task0_init (空)

 Timer4_init();
 SPI0_init();


空 task0_fxn (UArg0、UArgarg1)

 task0_init();

 System_printf ("任务启动\r\n");
 system_flush();

 while (1){
   Task_sleep ((UINT) arg0);
   GPIO_TOGGLE (Board_LED0);
 }


/*
 * ==== main ====
 *
int main (空)

   Task_Params taskParams;

   /*呼叫板初始化函数*/
   Board_initGeneral();
   Board_initGPIO();
   // Board_initI2C();
   // Board_initSDSPI();
   Board_initSPI();
   // Board_initUART ();
   // Board_initUSB (Board_USBDEVICE);
   // Board_initWatchdog();
   // Board_initWiFi ();


   /*构造心跳任务 线程*/
   Task_Params_init (&taskParams);
   taskParams.arg0 = 1000;
   taskParams.STACKSIZE = TASKSTACKSIZE;
   taskParams.stack =&task0_Stack;
   Task_construct(&task0_Struct,(Task_Functr) task0_fxn、&taskParams、NULL);

   /*打开用户 LED */
   GPIO_WRITE (Board_LED0、Board_LED_ON);

   system_printf ("启动示例\n 系统提供程序设置为 SysMin。 "
                 "停止目标以查看 ROV 中的任何 SysMin 内容。\n");
   /* SysMin 仅在您调用 flush 或 exit 时才会打印到控制台*/
   system_flush();

   /*启动 BIOS */
   BIOS_start();

   返回(0);



//=== BoardConfig.c 中的 SPI 部分=== //

#if defined (__TI_Compiler_version__)
#pragma DATA_SECTION (SPI_CONFIG、".CONST:SPI_CONFIG")
#pragma DATA_SECTION (spiTivaDMAHWAttrs、".const:spiTivaDMAHWAttrs")
#endif

#include
#include

SPITivaDMA_Object spiTivaDMAObjects[Board_SPICOUNT];

#if defined (__TI_Compiler_version__)
#pragma DATA_ALIGN (spiTivaDMAscratchBuf、32)
#Elif defined (_IAR_systems_icc_)
#pragma DATA_alignment=32
#Elif defined (_GNU_)
__attribute__((对齐(32)))
#endif
uint32_t spiTivaDMAscratchBuf[Board_SPICOUNT];

CONST SPITivaDMA_HWAttrs spiTivaDMAHWAttrs[Board_SPICOUNT]={
   {
       baseAddr = SSI0_BASE、
       .intNum = INT_SSI0、
       .intPriority =(~0)、
       .scratchBufPtr =&spiTivaDMAscratchBuf[0]、
       defaultTxBufValue = 0、
       .rxChannelIndex = UDMA_CHANGE_SSI0RX、
       txChannelIndex = UDMA_CHANGE_SSI0TX、
       channelMappingFxn = uDMAChannelAssign、
       .rxChannelMappingFxnArg = UDMA_CH10_SSI0RX、
       txChannelMappingFxnArg = UDMA_CH11_SSI0TX
   }、
};

CONST SPI_Config SPI_CONFIG[]={
   {
       fxnTablePtr =&SPITIvaDMA_fxnTable、
       .object =&spiTivaDMAObjects[0]、
       hwAttrs =&spiTivaDMAHWAttrs[0]
   }、
   {NULL、NULL、NULL}、
};

void Board_initSPI (void)

   /* SPI0 */
   SysCtlPeripheralEnable (SYSCTL_Periph_SSI0);

   /*需要解锁 PF0 */
   GPIOPinConfigure (GPIO_PA2_SSI0CLK);
   GPIOPinConfigure (GPIO_PA3_SSI0FSS);
   GPIOPinConfigure (GPIO_PA4_SSI0RX);
   GPIOPinConfigure (GPIO_PA5_SSI0TX);

   GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5);

   Board_initdma();
   spi_init();


//=== BoardConfig.h 中的 SPI 部分=== //

typedef 枚举 Board_SPIName{
   Board_SPI0 = 0、

   Board_SPICOUNT
} Board_SPIName;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Sarawin、

    问题是您正在调用 TimerIntRegister。 请查看此主题的最后一篇文章 :e2e.ti.com/.../2347913

    其中讨论了为何不能使用 driverlib 的 IntRegister 在 TI-RTOS 应用中插入向量。 注意:TimerIntRegister 调用 IntRegister。 在基于 TI-RTOS 的应用程序中、您不应调用 IntMasterEnable。

    Todd
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这种诊断似乎是最合理的-海报声称 是"呼叫顺序"-(只有一个这样的顺序)这一事实使人感到厌恶

    按照的直接引述: "在我跑步时、有一种奇怪的行为、

    SPI0_init();
    Timer4_init();

    它的工作原理。 当我跑步时、

    Timer4_init();
    SPI0_init();

    失败"

    不允许的"IntRegister"-以及同样不允许的"IntMasterEnable"-都被调用-与 "调用顺序"无关吗?   (因此不应"任意一个命令"失败?)