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-TM4C1294XL:UART 接收中断

Guru**** 2448780 points
Other Parts Discussed in Thread: EK-TM4C1294XL

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/622381/rtos-ek-tm4c1294xl-uart-receive-interrupt

器件型号:EK-TM4C1294XL

工具/软件:TI-RTOS

我将继续对使用两个 EK-TM4C1294XL 的设置进行故障排除。

两个 EKS 设置为8位 UART 模式、在 UART 接收时产生中断。 我有 中断

用于在 startup_ccs.c 文件中设置 UART 和计时器。

EK1每10秒发送一个字节、由一个周期定时器确定。 我设置了一个 LED

在 EK2接收到该字节时闪烁。 此 LED 会切换状态一次、而不是每10秒切换一次

和预期的一样。 为什么 UART 接收中断不会重复触发?  我同时附上了这两份文件

发送器和接收器 EK 文件。 在示波器上、我可以看到来自 EK1的发送字节、

在 EK2上 U5Rx 的示波器上看不到字节。

谢谢、

Priya

EK1发送器:

//
//
// uart_echo.c -从中的 UART 读取数据并向其中写入数据的示例
//              中断驱动方式。
//
//版权所有(c) 2013-2017 Texas Instruments Incorporated。  保留所有权利。
//软件许可协议
//
//德州仪器(TI)仅提供和使用此软件
//专门用于 TI 的微控制器产品。 该软件归其所有
// TI 和/或其供应商、受适用版权保护
//法律。 您不能将此软件与"病毒"开源软件结合使用
//软件,以便形成一个更大的程序。
//
//此软件按“原样”提供,且存在所有故障。
//不作任何明示、暗示或法定的保证,包括但
//不限于对适销性和适用性的暗示保证
//此软件的特定用途。 TI 不得以任何方式进行
//情况,对特殊、偶然或从属事件负责
//任何原因造成的损害。
//
//这是 EK-TM4C1294XL 固件包版本2.1.4.178的一部分。
//
//

#include
#include
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/timer.h"
#include "utils/uartstdio.h"

//
//
//! \addtogroup example_list
//!

UART 回波(UART_ECHO)


//!
//! 此示例应用利用 UART 来回显文本。  第一个 UART
//! (连接到评估板上的 USB 调试虚拟串行端口)
//! 将配置为115、200波特、8-n-1模式。  接收到的所有字符
//! UART 被发送回 UART。
//
//

//
//
//系统时钟速率,单位为 Hz。
//
//
uint32_t g_ui32SysClock;

unsigned char txcomplete = 0;
unsigned char timerComplete = 0;
静态 uint8_t TrxBuffer[1]={0x43};
uint8_t i = 0;
void UARTSend (const uint8_t * pu16Buffer、uint32_t ui32Count);

//
//
//驱动程序库遇到错误时调用的错误例程。
//
//
#ifdef 调试
无效
_error__(char * pcFilename、uint32_t ui32Line)

#endif

//
//
//向 UART 发送字符串。
//
//
无效
UARTSend (const uint8_t * pui8缓冲器、uint32_t ui32计数)

   //
   //循环,同时有更多字符要发送。
   //

   while (ui32Count---)
   {
       //
       //将下一个字符写入 UART。

       ROM_UARTCharPutNonBlocking (UART5_BASE、* pu8Buffer++);

   }


//
//
// UART 中断处理程序。
//
//
无效
UARTIntHandler (空)

   uint32_t ui32Status;

   //
   //获取中断状态。
   //
   ui32Status = UARTIntStatus (UART5_BASE、TRUE);

   //
   //清除已发出的中断。
   //
   ROM_UARTIntClear (UART5_BASE、ui32Status);

   if ((((UART_INT_RX 和 ui32Status)== UART_INT_RX)||((UART_INT_RT 和 ui32Status)== UART_INT_RT)))(

       //接收 UART 字符
            while (ROM_UARTCharsAvail (UART5_BASE))
            {
                //
                //从 UART 读取下一个字符并将其写回 UART。
                //

                ROM_UARTCharGetNonBlocking (UART5_BASE);


                //uint32_t c = UARTCharGet (UART5_BASE);

                //
                //闪烁 LED 以显示字符传输正在发生。
                //
                IF (GPIOPinRead (GPIO_PORTN_BASE、GPIO_PIN_1))
                            {
                                GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_1、0);
                            }
                其他
                            {
                                GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_1、2);
                            }
            }


      }

空 Timer2IntHandler (空)

   //清除计时器中断
   ROM_TimerIntClear (TIMER2_base、TIMER_TINA_TIMEOUT);
   I = 0;

   UARTSend (TrxBuffer、1);

   //闪烁 LED 以显示字符传输正在发生。
   //

   IF (GPIOPinRead (GPIO_PORTN_BASE、GPIO_PIN_1))
               {
                   GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_1、0);
               }
   其他
               {
                   GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_1、2);
               }

   timerComplete = 1;

//
//
//此示例演示了如何将一串数据发送到 UART。
//
//
内部
main (空)

   uint32_t ui32Period;

   //
   //将时钟设置为直接从频率为120MHz 的晶体运行。
   //
   G_ui32SysClock = MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
                                            SYSCTL_OSC_MAIN |
                                            SYSCTL_USE_PLL |
                                            SYSCTL_CFG_VCO_480)、120000000);
   //
   //启用用于板载 LED 的 GPIO 端口。
   //
   ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPION);
   //
   //为 LED (PN0)启用 GPIO 引脚。
   //
   ROM_GPIOPinTypeGPIOOutput (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1);


   ROM_SysCtlPeripheralEnable (SYSCTL_Periph_TIMER2);
   ROM_IntMasterEnable();

   //定时器配置(TIMER2_base、TIMER_CFG_ONE_SHOT);
   ROM_TimerConfigure (TIMER2_base、TIMER_CFG_PERIODICASE);

//   ui32Period = g_ui32SysClock/200;// 5ms 一次性计时器

   ui32Period = 5*g_ui32SysClock;
//   ui32Period = 3*g_ui32SysClock;
   ROM_TimerLoadSet (TIMER2_base、timer_A、ui32Period);

   ROM_IntEnable (INT_TIMER2A);
   ROM_TimerIntEnable (TIMER2_base、TIMER_TINA_TIMEOUT);


   ROM_TimerEnable (TIMER2_base、TIMER_A);


   //
   //启用此示例使用的外设。
   //
   ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART5);
   ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOC);

   ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
   ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);


   //
   //将 GPIO A0和 A1设置为 UART 引脚。
   //
   ROM_GPIOPinConfigure (GPIO_PC6_U5RX);
   ROM_GPIOPinConfigure (GPIO_PC7_U5TX);
   ROM_GPIOPinTypeUART (GPIO_PORTC_BASE、GPIO_PIN_6 | GPIO_PIN_7);


   //
   //将 UART 配置为9600、8-N-1操作。
   //
   ROM_UARTConfigSetExpClk (UART5_BASE、g_ui32SysClock、9600、
                           (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                            UART_CONFIG_PAR_NONE));


   ROM_GPIOPinConfigure (GPIO_PA0_U0RX);
   ROM_GPIOPinConfigure (GPIO_PA1_U0TX);
   ROM_GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);

   UARTStdioConfig (0、9600、g_ui32SysClock);

//   UART9BitAddrSet (UART5_BASE、0x43、0xFF);
//   UART9BitEnable (UART5_BASE);

   ROM_UARTEnable (UART5_BASE);
   ROM_UARTFIFODisable (UART5_BASE);
//   UART9BitAddrSend (UART5_BASE、0x43);

   //
   //启用 UART 中断。
   //
   ROM_IntEnable (INT_UART5);

//   UARTIntEnable (UART5_BASE、UART_INT_RX | UART_INT_RT | UART_INT_9BIT);
     ROM_UARTIntEnable (UART5_BASE、UART_INT_RX | UART_INT_RT);
//   ROM_UARTIntEnable (UART5_BASE、UART_INT_TX | UART_TXINT_MODE_EOT | UART_INT_9BIT);
//   ROM_UARTIntEnable (UART5_BASE、UART_INT_TX|UART_TXINT_MODE_EOT | UART_INT_9BIT | UART_INT_RX|UART_INT_RT);


//   UARTSend (TrxBuffer、1);


//   while (!(txcomplete));
   while (1);

EK2接收器:

//
//
// uart_echo.c -从中的 UART 读取数据并向其中写入数据的示例
//              中断驱动方式。
//
//版权所有(c) 2013-2017 Texas Instruments Incorporated。  保留所有权利。
//软件许可协议
//
//德州仪器(TI)仅提供和使用此软件
//专门用于 TI 的微控制器产品。 该软件归其所有
// TI 和/或其供应商、受适用版权保护
//法律。 您不能将此软件与"病毒"开源软件结合使用
//软件,以便形成一个更大的程序。
//
//此软件按“原样”提供,且存在所有故障。
//不作任何明示、暗示或法定的保证,包括但
//不限于对适销性和适用性的暗示保证
//此软件的特定用途。 TI 不得以任何方式进行
//情况,对特殊、偶然或从属事件负责
//任何原因造成的损害。
//
//这是 EK-TM4C1294XL 固件包版本2.1.4.178的一部分。
//
//

#include
#include
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/timer.h"
#include "utils/uartstdio.h"

//
//
//! \addtogroup example_list
//!

UART 回波(UART_ECHO)


//!
//! 此示例应用利用 UART 来回显文本。  第一个 UART
//! (连接到评估板上的 USB 调试虚拟串行端口)
//! 将配置为115、200波特、8-n-1模式。  接收到的所有字符
//! UART 被发送回 UART。
//
//

//
//
//系统时钟速率,单位为 Hz。
//
//
uint32_t g_ui32SysClock;

unsigned char txcomplete = 0;
unsigned char timerComplete = 0;
uint8_t TrxBuffer[1]={0x21};
uint8_t i = 0;
void UARTSend (const uint8_t * pui8Buffer、uint32_t ui32Count);
空 Timer3IntHandler (空);


//
//
//驱动程序库遇到错误时调用的错误例程。
//
//
#ifdef 调试
无效
_error__(char * pcFilename、uint32_t ui32Line)


#endif

//
//
//向 UART 发送字符串。
//
//
无效
UARTSend (const uint8_t * pui8缓冲器、uint32_t ui32计数)

   //
   //循环,同时有更多字符要发送。
   //

   while (ui32Count---)
   {
       //
       //将下一个字符写入 UART。

       ROM_UARTCharPutNonBlocking (UART5_BASE、* pu8Buffer++);
//       UARTprintf ("%x "、TrxBuffer[i++]);

   }

空 Timer3IntHandler (空)

   //清除计时器中断
   ROM_TimerIntClear (TIMER3_base、TIMER_TINA_TIMEOUT);

   //闪烁 LED 以显示字符传输正在发生。
/*
   IF (GPIOPinRead (GPIO_PORTN_BASE、GPIO_PIN_1))
           {
               GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_1、0);
           }
   其他
           {
               GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_1、2);
           }
*
   UARTSend (TrxBuffer、1);
   I = 0;

   timerComplete = 1;

//
//
// UART 中断处理程序。
//
//
无效
UARTIntHandler (空)

   uint32_t ui32Status;

   //
   //获取中断状态。
   //
   ui32Status = UARTIntStatus (UART5_BASE、TRUE);

   //

   //
   //清除已发出的中断。
   //
   ROM_UARTIntClear (UART5_BASE、ui32Status);

//   if (interrupt_type = 1){
   if ((((UART_INT_RX 和 ui32Status)== UART_INT_RX)||((UART_INT_RT 和 ui32Status)== UART_INT_RT)))(
       //接收 UART 字符
            while (ROM_UARTCharsAvail (UART5_BASE))
            {
                //
                //从 UART 读取下一个字符并将其写回 UART。
                //
//                UARTCharPut (UART5_BASE、UARTCharGet (UART5_BASE));
                ROM_UARTCharGetNonBlocking (UART5_BASE);
            }

   IF (GPIOPinRead (GPIO_PORTN_BASE、GPIO_PIN_1))
       {
           GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_1、0);
       }
   其他
       {
           GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_1、2);
       }
   }

//
//
//此示例演示了如何将一串数据发送到 UART。
//
//
内部
main (空)

   uint32_t ui32Period;

   //
   //将时钟设置为直接从频率为120MHz 的晶体运行。
   //
   G_ui32SysClock = MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
                                            SYSCTL_OSC_MAIN |
                                            SYSCTL_USE_PLL |
                                            SYSCTL_CFG_VCO_480)、120000000);
   //
   //启用用于板载 LED 的 GPIO 端口。
   //
   ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPION);
   //
   //为 LED (PN0)启用 GPIO 引脚。
   //
   ROM_GPIOPinTypeGPIOOutput (GPIO_PORTN_BASE、GPIO_PIN_0|GPIO_PIN_1);


   //
   //启用此示例使用的外设。
   //
   ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART5);
   ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOC);

   ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
   ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);

   //
   //启用处理器中断。
   //
   ROM_IntMasterEnable();

#if 0
       SysCtlPeripheralEnable (SYSCTL_Periph_TIMER3);
//       TimerConfigure (TIMER3_base、TIMER_CFG_ONE_SHOT);
       TimerConfigure (TIMER3_base、TIMER_CFG_PERIODICASE);


       ui32Period = g_ui32SysClock/2;// 1ms 一次性计时器

//       ui32Period = 5*g_ui32SysClock;
       TimerLoadSet (TIMER3_base、timer_A、ui32Period-1);

       IntEnable (INT_TIMER3A);
       TimerIntEnable (TIMER3_base、TIMER_TINA_TIMEOUT);
       IntMasterEnable();

       TimerEnable (TIMER3_base、TIMER_A);
#endif

   //
   //将 GPIO A0和 A1设置为 UART 引脚。
   //
   ROM_GPIOPinConfigure (GPIO_PC6_U5RX);
   ROM_GPIOPinConfigure (GPIO_PC7_U5TX);
   ROM_GPIOPinTypeUART (GPIO_PORTC_BASE、GPIO_PIN_6 | GPIO_PIN_7);


   //
   //将 UART 配置为9600、8-N-1操作。
   //
   ROM_UARTConfigSetExpClk (UART5_BASE、g_ui32SysClock、9600、
                           (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                            UART_CONFIG_PAR_NONE));


   ROM_GPIOPinConfigure (GPIO_PA0_U0RX);
   ROM_GPIOPinConfigure (GPIO_PA1_U0TX);
   ROM_GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);

   UARTStdioConfig (0、9600、g_ui32SysClock);

//   UART9BitAddrSet (UART5_BASE、0x43、0xFF);
//   UART9BitEnable (UART5_BASE);

   ROM_UARTEnable (UART5_BASE);

   ROM_UARTFIFODisable (UART5_BASE);

   //
   //启用 UART 中断。
   //
   ROM_IntEnable (INT_UART5);
//   UARTIntEnable (UART5_BASE、UART_INT_RX | UART_INT_RT | UART_INT_9BIT);
   ROM_UARTIntEnable (UART5_BASE、UART_INT_RX | UART_INT_RT);
//   ROM_UARTIntEnable (UART5_BASE、UART_INT_TX | UART_TXINT_MODE_EOT | UART_INT_9BIT);
//   ROM_UARTIntEnable (UART5_BASE、UART_INT_TX|UART_TXINT_MODE_EOT | UART_INT_9BIT | UART_INT_RX|UART_INT_RT);

//   UARTSend (TrxBuffer、1);


//   while (!(txcomplete));
   while (1);

谢谢、

Priya

 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Priya、
    首先、我看到在 EK1的发送端、您的定时器周期为5s、而不是中所示的10s ui32Period = 5*g_ui32SysClock;
    ,对吗?
    2.您是否也在监控发送端的 LED? 假设您从 LED 关闭开始。 当您收到计时器中断时、您将在发送字符后打开 LED。 但是、在接收中断中、您将再次关闭同一 LED。 因此、LED 导通时间的持续时间将是一个 UART 字符传输的长度。 如果您只依靠 LED 接通时间来在传输成功时解密、那么 LED 上的闪烁将在人眼上太短。
    3.我认为 EK1根据每个计时器超时发送字符。 在 EK2中、它只是接收字符。 如果是这种情况、为什么要设置 TIMER3? 您不应在 EK2的接收侧设置计时器。 EK2应该只等待字符进入并生成接收中断。
    4.独立于 LED,EK2是否接收到来自 EK1的字符?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    首先、我看到在 EK1的发送端、您的定时器周期是5s、而不是10s、就像 ui32Period = 5*g_ui32SysClock 中那样;
    ,对吗?

    我的计算周期可能不准确、5s 或10s 可以满足我当前的工作。

    2.您是否也在监控发送端的 LED? 假设您从 LED 关闭开始。 当您收到计时器中断时、您将在发送字符后打开 LED。 但是、在接收中断中、您将再次关闭同一 LED。 因此、LED 导通时间的持续时间将是一个 UART 字符传输的长度。 如果您只依靠 LED 接通时间来在传输成功时解密、那么 LED 上的闪烁将在人眼上太短。

    在发送器 EK1中、我设置了 LED 来在定时器处理程序中断和 UART 中断处理程序中切换。

    3.我认为 EK1根据每个计时器超时发送字符。 在 EK2中、它只是接收字符。 如果是这种情况、为什么要设置 TIMER3? 您不应在 EK2的接收侧设置计时器。 EK2应该只等待字符进入并生成接收中断。

    我没有在 EK2接收器中启用定时器。 我在这里有一个计时器、因为我在周期计时器的末尾还有一个 EK2发送。 当我在示波器上查看这个传输字节时、我可以清楚地看到它。

    4.独立于 LED,EK2是否接收到来自 EK1的字符?
    当我探测到 EK2 U5 Rx 时、在示波器上看不到这种情况的证据。 在我看来、UART 接收中断没有触发。

    谢谢、
    Priya
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    由于频繁运输以使用示波器、因此 EK 上的跳线完全混合在一起。
    LED 按应有的方式闪烁、我可以在示波器上看到接收到的字节。 我现在是
    希望在9位模式下也能正常工作。
    谢谢、
    Priya
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    很高兴您的问题得到解决!