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.

[参考译文] TM4C129ENCPDT:GPIO 切换速度非常慢

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/768188/tm4c129encpdt-gpio-toggling-very-slow

器件型号:TM4C129ENCPDT

您好!

我正在尝试切换 GPIO 引脚、它看起来非常慢。

我的微控制器主时钟为120MHz。

我删除了中间延迟、但仍然非常慢。

下面是我的时钟的配置方式。 我已通过读取 uint32_t sys_clock 来验证时钟是否为120MHz。

//将系统时钟初始化为120MHz
// uint32_t sys_clock;
SYS_CLOCK = ROM_SysCtlClockFreqSet (
(SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN |
SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、
System_clock);
assert (sys_clock == system_clock);


以及用于切换引脚的代码;

void adc_conv_start (void)
{
GPIOPinWrite (ADC_CTRL1_PORT、ADC_CNVSTARTA |ADC_CNVSTARTB、0);
//for (i=0;i<1;i++){}
//SysCtlDelay (1);
GPIOPinWrite (ADC_CTRL1_PORT、ADC_CNVSTARTA | ADC_CNVSTARTB、ADC_CNVSTARTA | ADC_CNVSTARTB);
} 

这里是示波器的快照、显示延迟为3.9微秒。

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

    您好、Sahil、

    我同意速度相当慢、您是否有任何可能占用 MCU 的中断或其他进程在运行?

    您是否可以尝试将时钟设置 API 与我们的闪烁项目一起使用,删除 main()中的延迟环路,并报告您在那里看到的结果? 如果我们看到在这种情况下进行较高速度的切换、这将表示从 GPIO 触发某项操作并导致延迟。 您可能需要将引脚从 N0更改为易于访问的内容、如进行此测试的 N2。

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

    我也可以尝试一下、但在这里我运行的是节拍率设置为100Hz 的 FreeRTOS。
    加上我的 GPIO 切换直接位于中断内部。 除了以100Hz 的频率运行 SysTick 和以10Hz 的频率运行 timer0A 中断之外、没有其他中断。

    这是整个图片;

    #include
    #include
    #include "main.h"
    #include "drivers/pinout.h"
    #include "utils/uartstdio.h"


    // TivaWare 包括
    #include "driverlib/sysctl.h"
    #include "driverlib/debug.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/inc/hw_memmap.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/ssi.h"
    #include "driverlib/inc/hw_ssi.h"
    #include "driverlib/inc/hw_types.h"
    #include "driverlib/timer.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/tm4c129encpdt.h"

    // FreeRTOS 包括
    #include "FreeRTOSConfig.h"
    #include "freertos.h"
    #include "task.h"
    #include "queue.h"

    #define NUM_SSI_DATA 3.

    //一般函数声明
    void adc_init (void);
    void sys_init (void);
    void timer0_init (void);
    void adc_collect_data (void);
    void adc_conv_start (void);

    // FreeRTOS 任务声明
    void blinkLED0_Task (void *pvParameters);
    void SerialTask(void *pvParameters);
    void Timer0IntTask (void *pvParameters);


    //FreeRTOS 句柄
    TaskHandle_t Timer0IntTask_Handle;


    void spi0_transmit (void *pvParameters);


    volatile uint32_t sys_clock;
    易失性 uint32_t 计数器;
    易失性 uint32_t ch0、ch1、ch2、ch3、ch4、ch5、ch6、ch7;

    //uint32_t data[16];
    UNION{
    uint32_t ui32value[8];
    uint8_t ui8byte[32];
    }数据;
    //主函数
    int main (空)

    //将系统时钟初始化为120 MHz
    // uint32_t sys_clock;
    SYS_CLOCK = ROM_SysCtlClockFreqSet (
    (SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN |
    SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、
    System_clock);
    assert (sys_clock == system_clock);


    //初始化除 USB 和以太网外连接到 Launchpad 的所有外设、例如 LED、用户按钮和 UART0
    PinoutSet (false、false);

    //初始化系统
    sys_init();


    //创建任务

    xTaskCreate (blinkLED0_Task、(const portCHAR *)"BLNKLED0"、
    configMINIMAL_STACK_SIZE、NULL、1、NULL);

    xTaskCreate (SerialTask、(const portCHAR *)"Serial"、
    configMINIMAL_STACK_SIZE、NULL、1、NULL);

    xTaskCreate (spi0_transmit、(const portCHAR *)"SPI0"、
    configMINIMAL_STACK_SIZE、NULL、2、NULL);

    xTaskCreate (Timer0IntTask、(const portCHAR *)"Timer0IntTask"、
    configMINIMAL_STACK_SIZE、NULL、3、Timer0IntTask_Handle);

    vTaskStartScheduler();
    返回0;



    //在 launchpad 上闪烁 LED0
    空 blinkLED0_Task (空*pv 参数)

    对于(;)

    GPIOPinWrite (LED0_PORT、LED0、LED0);
    vTaskDelay (500);
    GPIOPinWrite (LED0_PORT、LED0、0);
    vTaskDelay (500);




    //在 launchpad 上闪烁 LED1
    void blinkLED1_Task (void *pvParameters)

    对于(;)

    GPIOPinWrite (LED1_PORT、LED1、LED1);
    vTaskDelay (500);
    GPIOPinWrite (LED1_PORT、LED1、0);
    vTaskDelay (500);



    //在 launchpad 上闪烁 LED2
    void blinkLED2_Task (void *pvParameters)

    对于(;)

    GPIOPinWrite (LED2_PORT、LED2、LED2);
    vTaskDelay (500);
    GPIOPinWrite (LED2_PORT、LED2、0);
    vTaskDelay (500);




    //在 launchpad 上闪烁 LED3
    void blinkLED3_Task (void *pvParameters)

    对于(;)

    GPIOPinWrite (LED3_PORT、LED3、LED3);
    vTaskDelay (500);
    GPIOPinWrite (LED3_PORT、LED3、0);
    vTaskDelay (500);



    //通过 Stellaris 调试接口 UART 端口编写文本
    空串行任务(空*pv 参数)



    对于(;)

    UARTprintf ("\r\nSystem Clock:\t\t%dMHz"、sys_clock/1000000);
    //UARTprintf ("\r\ndata.ui32value[0]= 0x%X、data.ui8byte[3]= 0x%X、data.ui8byte[2]= 0x%X、data.ui8byte[1]= 0x%X、data.ui8byte[0]= 0x%X"、data.ui8byte2[0]ui8byte.ui8byte.ui2[0]、ui8byte.ui8byte[0]、ui2ui8byte.uData.ui8byte[0]、ui2ui2u.ui2u.u.u.

    vTaskDelay (1000 / portTIK_PERIOD_MS);




    void sys_init (void)

    uint32_t i;

    //设置连接到虚拟 COM 端口的 UART
    UARTStdioConfig (UART0、UART0_BAUD_RATE、SYSTEM_CLOCK);
    //
    //必须启用 SSI0外设才能使用。
    //
    SysCtlPeripheralEnable (SYSCTL_Periph_SSI0);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOM);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPION);

    //
    //为端口 A2、A3、A4和 A5上的 SSI0功能配置引脚复用。
    //如果您的器件不支持引脚复用、则无需执行此步骤。
    // TODO:更改此选项以选择您正在使用的端口/引脚。
    //
    GPIOPinConfigure (GPIO_PA2_SSI0CLK);
    GPIOPinConfigure (GPIO_PA3_SSI0FSS);
    GPIOPinConfigure (GPIO_PA4_SSI0RX);
    GPIOPinConfigure (GPIO_PA5_SSI0TX);

    //
    //配置 SSI 引脚的 GPIO 设置。 该函数也会提供
    将这些引脚的//控制到 SSI 硬件。 请参阅中的数据表
    //查看每个引脚分配的函数。
    //引脚分配如下:
    // PA5 - SSI0Tx
    // PA4 - SSI0Rx
    // PA3 - SSI0Fss
    // PA2 - SSI0CLK
    // TODO:更改此选项以选择您正在使用的端口/引脚。
    //
    GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 |
    GPIO_PIN_2);

    #if defined (target_IS_TM4C129_RA0)|| \
    已定义(TARGET_IS_TM4C129_RA1)|| \
    已定义(TARGET_IS_TM4C129_RA2)
    SSIConfigSetExpClk (SSI0_BASE、SYS_CLOCK、SSI_FRF_MOTO_MOTO_MODE_2、
    SSI_MODE_MASTER、SPI0_CLK_SPEED、SPI0_DATA_width);
    其他
    SSIConfigSetExpClk (SSI0_BASE、SysCtlClockGet ()、SSI_FRF_MOTO_MODE_0、
    SSI_MODE_MASTER、1000000、8);
    #endif
    //启用 SSI0模块。
    //
    SSIEnable (SSI0_BASE);
    adc_init();
    timer0_init();


    对于(i=0;i<8;i++){data.ui32value[i]= 0x3FFFF;}//使用一些数据填充数组、仅用于仿真










    void spi0_transmit (void *pvParameters)

    //uint32_t data[8]、temp1;
    uint8_t i;

    对于(;)

    //
    //显示 SSI 正在发送数据的指示。
    //
    //UARTprintf ("'\r\n0x%X 发送到 MOSI'"、计数器);



    对于(i = 0;i<1;i++)


    //数据 ui32value 0
    SSIDataPut (SSI0_BASE、data.ui8byte[2]);//msb
    SSIDataPut (SSI0_BASE、data.ui8byte[1]);
    SSIDataPut (SSI0_BASE、data.ui8byte[0]);//LSB

    //数据 ui32value 1.
    SSIDataPut (SSI0_BASE、data.ui8byte[6]);
    SSIDataPut (SSI0_BASE、data.ui8byte[5]);
    SSIDataPut (SSI0_BASE、data.ui8byte[4]);

    //数据 ui32值2.
    SSIDataPut (SSI0_BASE、data.ui8bytes[10]);
    SSIDataPut (SSI0_BASE、data.ui8byte[9]);
    SSIDataPut (SSI0_BASE、data.ui8byte[8]);

    //数据 ui32值3.
    SSIDataPut (SSI0_BASE、data.ui8bytes[10]);
    SSIDataPut (SSI0_BASE、data.ui8byte[9]);
    SSIDataPut (SSI0_BASE、data.ui8byte[8]);

    //数据 ui32value 4.
    SSIDataPut (SSI0_BASE、data.ui8byte[2]);//msb
    SSIDataPut (SSI0_BASE、data.ui8byte[1]);
    SSIDataPut (SSI0_BASE、data.ui8byte[0]);//LSB

    //数据 ui32值5.
    SSIDataPut (SSI0_BASE、data.ui8byte[6]);
    SSIDataPut (SSI0_BASE、data.ui8byte[5]);
    SSIDataPut (SSI0_BASE、data.ui8byte[4]);

    //数据 ui32value 6.
    SSIDataPut (SSI0_BASE、data.ui8bytes[10]);
    SSIDataPut (SSI0_BASE、data.ui8byte[9]);
    SSIDataPut (SSI0_BASE、data.ui8byte[8]);

    //数据 ui32value 7.
    SSIDataPut (SSI0_BASE、data.ui8bytes[10]);
    SSIDataPut (SSI0_BASE、data.ui8byte[9]);
    SSIDataPut (SSI0_BASE、data.ui8byte[8]);



    //while (SSIBusy (SSI0_BASE)){}
    //SSIDataGetNonBlocking (SSI0_BASE、&DATA[i]);//(0b01000101 << 8)=(0b100010100000000)


    //while (SSIBusy (SSI0_BASE)){}

    vTaskDelay (1000);






    void ADC_init (void)

    ROM_GPIOPinTypeGPIOOutput (ADC_CTRL1_PORT、ADC_OS0 | ADC_OS1 | ADC_OS2 | ADC_CNVSTARTA | ADC_CNVSTARTB | ADC_RANGE | ADC_RESET);
    ROM_GPIOPinTypeGPIOOutput (ADC_CTRL2_PORT、ADC_CS | ADC_READ);

    ROM_GPIOPinTypeGPIOInput (ADC_CTRL1_PORT、ADC_BUSY);//将 ADC_BUSY 引脚配置为输入
    ROM_GPIOPinTypeGPIOInput (ADC_MSB_PORT、0xFF);//将 ADC MSB 数据引脚配置为输入
    ROM_GPIOPinTypeGPIOInput (ADC_LSB_PORT、0xFF);//将 ADC LSB 数据引脚配置为输入

    GPIOPadConfigSet (ADC_CTRL1_PORT、ADC_CNVSTARTA | ADC_CNVSTARTB、GPIO_Strength _2mA、GPIO_PIN_TYPE_STD);

    GPIOPinWrite (ADC_CTRL2_PORT、ADC_CS | ADC_Read、ADC_CS | ADC_Read);//将 ADC_CS 和 ADC_Read 拉为高电平
    GPIOPinWrite (ADC_CTRL1_PORT、ADC_CNVSTARTA | ADC_CNVSTARTB、ADC_CNVSTARTA | ADC_CNVSTARTB);




    void adc_conv_start (void)

    GPIOPinWrite (ADC_CTRL1_PORT、ADC_CNVSTARTA |ADC_CNVSTARTB、0);
    //for (i=0;i<1;i++){}
    //SysCtlDelay (1);
    GPIOPinWrite (ADC_CTRL1_PORT、ADC_CNVSTARTA | ADC_CNVSTARTB、ADC_CNVSTARTA | ADC_CNVSTARTB);


    void adc_collect_data (void)

    uint32_t i = 0、ch = 0;
    adc_conv_start ();
    if ((GPIOPinRead (ADC_CTRL1_PORT、ADC_BUSY)!= 0)&(I!= 600)){i++;}

    //读取 ADC 通道0
    for (ch=0;ch<8;ch++)

    GPIOPinWrite (ADC_CTRL2_PORT、ADC_CS | ADC_READ、0);//将 ADC_CS 和 ADC_READ 拉低以读取 MSB 16位
    //data.ui32value[ch]=(((GPIOPinRead (ADC_MSB_port、0xFF))和0xFF)|(0xFF));//读取全部8个引脚((((GPIOPinRead (ADC_MSB_port、0xFF)))和0xFF)|(0xFF));
    //UARTprintf ("\r\n 左移前的值:0x%X"、data.ui32value[ch]);
    //data.ui32value[ch]= data.ui32value[ch]<< 8;
    //UARTprintf ("\r\n 左移后的值:0x%X"、data.ui32value[ch]);
    //data.ui32value[ch]|=(((GPIOPinRead (ADC_LSB_port、0xFF))和0xFF)|(0xFF));//读取全部8个引脚((((GPIOPinRead (ADC_LSB_port、0xFF)))和0xFF)|(0xFF);
    //UARTprintf ("\r\n 第二个左移之前的值:0x%X"、data.ui32value[ch]);
    GPIOPinWrite (ADC_CTRL2_PORT、ADC_CS | ADC_Read、ADC_CS | ADC_Read);//将 ADC_CS 和 ADC_Read 拉为高电平
    //data.ui32value[ch]= data.ui32value[ch]<< 2;
    //UARTprintf ("\r\n 第二个左移后的值:0x%x"、data.ui32value[ch]);
    GPIOPinWrite (ADC_CTRL2_PORT、ADC_CS | ADC_READ、0);//将 ADC_CS 和 ADC_READ 拉低以读取剩余的2个 LSB 位
    //data.ui32value[ch]|=(((GPIOPinRead (ADC_LSB_port、0x3))和0x3)|(0x3));//读取 ADC 第17位和第18位的2个 LSB
    //UARTprintf ("\r\n 完全调整后的值:0x%x"、data.ui32value[ch]);
    GPIOPinWrite (ADC_CTRL2_PORT、ADC_CS | ADC_Read、ADC_CS | ADC_Read);//将 ADC_CS 和 ADC_Read 拉为高电平






    void timer0_init (void)

    uint32_t ui32Period;
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);
    TimerConfigure (TIMER0_BASE、TIMER_CFG_PERIODICASE);

    //ui32Period =(sys_clock/10)/2;
    ui32Period =(sys_clock/100);
    UARTprintf ("\r\nPeriod =%d"、ui32Period);

    TimerLoadSet (TIMER0_BASE、TIMER_A、ui32Period -1);

    IntEnable (INT_TIMER0A);

    TimerIntEnable (TIMER0_BASE、TIMER_TINA_TIMEOUT);

    IntMasterEnable();

    TimerEnable (TIMER0_BASE、TIMER_A);



    空 Timer0IntHandler (空)

    //清除计时器中断
    TimerIntClear (TIMER0_BASE、TIMER_TINA_TIMEOUT);
    //读取 GPIO 引脚和的当前状态
    //写回相反的状态
    adc_collect_data();
    basetype_t checkIfYieldRequired;
    CheckIfYieldRequired = xTaskResumeFromISR (Timer0IntTask_Handle);
    portYIELD_FER_ISR (checkIfYieldRequired);
    //GPIOPinWrite (LED2_PORT、LED2、((~LED2)& 0x10));


    空 Timer0IntTask (空*pv 参数)

    uint32_t i = 0;
    while (1)

    vTaskSuspend (NULL);//挂起本身
    //adc_collect_data();


    //UARTprintf ("\r\n%d Timer0IntTask\n\n\RDATA.ui32value[0]= 0x%X、data.ui8byte[3]= 0x%X、data.ui8byte[2]="
    //"0x%X、data.ui8byte[1]= 0x%X、data.ui8byte[0]= 0x%X"、\
    i++、data.ui32value[0]、data.ui8byte[3]、data.ui8byte[2]、data.ui8byte[1]、data.ui8byte[0]);


    //UARTprintf ("\r\n\r\n 这是打印表单 Timer0IntTask"、i++);











    /* assert()错误函数
    *
    在此函数中执行来自 driverlib/debug.h 的* Failed asserts()
    *
    void __error__(char *pcFilename、uint32_t ui32Line)

    //在此处放置一个断点以捕获错误,直到日志记录例程完成
    while (1)


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您可以看到切换直接在中断例程内;
    如下文所示;

    空 Timer0IntHandler (空)

    //清除计时器中断
    TimerIntClear (TIMER0_BASE、TIMER_TINA_TIMEOUT);
    adc_collect_data();
    basetype_t checkIfYieldRequired;
    CheckIfYieldRequired = xTaskResumeFromISR (Timer0IntTask_Handle);
    portYIELD_FER_ISR (checkIfYieldRequired);
    //GPIOPinWrite (LED2_PORT、LED2、((~LED2)& 0x10));
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    请注意在 Timer0IntHandler ()内调用 ADC_collect_data()来调用 ADC_conv_start (),这是一个用于切换引脚的简单直接函数。 如下所示;


    void adc_conv_start (void)

    GPIOPinWrite (ADC_CTRL1_PORT、ADC_CNVSTARTA |ADC_CNVSTARTB、0);
    //for (i=0;i<1;i++){}
    //SysCtlDelay (1);
    GPIOPinWrite (ADC_CTRL1_PORT、ADC_CNVSTARTA | ADC_CNVSTARTB、ADC_CNVSTARTA | ADC_CNVSTARTB);
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如您所建议。 我尝试了闪烁项目、它工作正常、因为在120MHz 时钟下、需要156nsec 来切换 LED、而在将 LED 设置为高电平和低电平之间没有任何延迟环路。 我尝试了用于切换目的的端口 M、并且端口 M 也在156nsec 切换。 这听起来不错。

    这是快照;

    但是、由于没有中断将处理器拉出、我仍然看不到我的项目有任何问题。

    由于工程是独立的、这意味着所有库都位于工程文件夹中、不需要调整编译器包含路径或任何其他工作。 它只是包含和运行某种项目。 我在这里作为压缩文件附加。

    e2e.ti.com/.../3683.Project0.zip

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

    您好!

    我已通过将代码缩减为更短的程序来进一步简化代码。 仍然不幸运。 我非常怀疑它与 FreeRTOS 有关系。

    这是整个代码;

    #include 
    #include 
    #include "main.h"
    #include "drivers/pinout.h"
    #include "utils/uartstdio.h"
    
    
    // TivaWare 包含
    #include "driverlib/sysctl.h"
    #include "driverlib/debug.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_decute.h
    
    
    
    
    
    
    
    
    
    
    
    命令#include "driverlib#define rtos"#define rtos void #define #include "driverlib/rtos"#defconfig #define #define #task#define #define #define rtos #include "#define #tog.000task#define #include "#include "driverlib_rtos"
    
    
    //主函数
    int main (void)
    {
    //将系统时钟初始化为120 MHz
    uint32_t output_clock_rate_Hz;
    output_clock_rate _Hz = ROM_SysCtlClockFreqSet (
    (SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN |
    SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、
    System_clock);
    assert (output_clock_rate _Hz = system_clock);
    
    //初始化 Launchpad 的 GPIO 引脚
    PinoutSet (false、false);
    
    ROM_GPIOPinTypeGPIOOutput (GPIO_PORTM_BASE、GPIO_PIN_4 | GPIO_PIN_5);
    GPIOPadConfigSet (GPIO_PORTM_BASE、GPIO_PIN_4 | GPIO_PIN_5、GPIO_Strength _2mA、GPIO_PIN_TYPE_STD);
    //创建演示任务
    xTaskCreate (demLEDTask、(const portCHAR *)"LED"、
    configMINIMAL_STACK_SIZE、NULL、2、NULL);
    
    xTaskCreate (demSerialTask、(const portCHAR *)"Serial"、
    configMINIMAL_STACK_SIZE、NULL、1、NULL);
    
    vTaskStartScheduler();
    返回0;
    
    }
    
    
    //刷写 launchpad
    上的 LED void demoLEDTask (void *pvParameters)
    {
    
    对于(;)
    
    {
    GPIOPinWrite (GPIO_PORTM_BASE、GPIO_PIN_4 |GPIO_PIN_5、0);
    //for (i=0;i<1;i++){}
    //SysCtlDelay (1);
    GPIOPinWrite (GPIO_PORTM_BASE、GPIO_PIN_4 | GPIO_PIN_5、GPIO_PIN_4 | GPIO_PIN_5);
    // //打开 LED 1
    // LEDWrite (0x0F、0x01);
    // vTaskDelay (100);
    //
    //打开 LED 2
    // LEDWrite (0x0F、0x02);
    // vTaskDelay (100);
    //
    //打开 LED 3
    // LEDWrite (0x0F、0x04);
    // vTaskDelay (100);
    //
    //打开 LED 4
    // LEDWrite (0x0F、0x08);
    // vTaskDelay (100);
    }
    }
    
    
    //通过 Stellaris 调试接口 UART 端口编写文本
    void SerialdemTask (void *pvParameters)
    {
    
    //设置连接到虚拟 COM 端口的 UART
    UARTStdioConfig (0、57600、system_clock);
    
    
    对于(;)
    {
    UARTprintf ("\r\nHello、World from FreeRTOS 9.0!");
    vTaskDelay (5000 / portTIK_PERIOD_MS);
    }
    }
    
    
    /* assert() Error 函数
    *
    来自 driverlib/debug.h 的 failed assert()在该函数中执行
    */
    void __error__(char *pcFilename,uint32_t ui32Line)
    {
    //在此处放置一个断点以捕获错误,直到日志记录例程完成
    while (1)
    {
    }
    } 

    有任何提示吗?

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

    感谢您发布该项目。 我真的不确定自己会发生什么情况。 我完成了附加项目的反汇编、看不到任何其他中断或函数被调用。 此外、修改节拍长度也不会影响延迟。

    从我看到的所有内容中、MCU 正在执行已在其内正确编程的汇编代码、 因此、遗憾的是、我不得不表示不同意、因为我唯一可能认为的问题是 FreeRTOS 的运行方式、因为没有指示 MCU 未正常运行的指示器。 遗憾的是、我们在 FreeRTOS 方面没有足够的经验来确切了解干扰 API 的发生情况。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Ralph、

    感谢您抽出宝贵的时间。
    我仍然希望使该线程至少保持打开一段时间、因为我确实需要对其进行修复。
    我可以从项目中删除 FreeRTOS、但我必须坚持使用 FreeRTOS、因为我稍后还将实施 Telnet 服务器。

    如果 Amit Ashara 能帮你解决问题的话,这家酒店会很棒。

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

    很遗憾 Amit 搬到了 TI 的另一个团队,不再支持 TM4C MCU :(我们都很想念他的专业知识。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我明白了。

    我有他,听从他的摆布……

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

     您好!

    我通过注释掉大部分代码来缩小问题范围。 我已经注释掉了所有 FreeRTOS 包括的内容。 我甚至禁用 了运行 FreeRTOS 调度程序的 port.c 中的 SysTick 计时器、并且还对该调度程序进行了注释。  通过这种方法、我完全隔离了 FreeRTOS 部件。

    我只需在代码中看到一个 while (1)循环。 现在、我的代码非常短、但问题仍然存在。

    它表示代码末尾带有 void __error__(char *pcFilename、uint32_t ui32Line)函数的某些内容。

    但是、当我尝试注释掉此函数时、编译器会给出以下错误。

    但是、如果我不注释掉上述函数。 它在编译时没有任何错误、并产生3.125usec 的缓慢延迟。 此外、我的项目包含所有 c 文件以及包含.h 文件的文件、并且不需要在链接器路径中包含 driverlib.lib。

    这是注释掉所有 FreeRTOS 内容后的代码。 此消息随附了同一项目。

    #include 
    #include 
    void include "main.h"
    #include "drivers/pinout.h"
    #include "utils/uartstdio.h"
    
    
    // TivaWare 包含
    #include "driverlib/sysctl.h"
    //#include "driverlib/debug.h"
    #include "driverlib/rom_demo.h"/#include
    "task/freepdt/#include
    "out/void trabout.trabout/#tog/#def/#t/#def_trabout/#tog/#def_trl.statement/#include "#t/#def_trates/#definc/trates#def_true/#tog./#def_true/#tog./#include "#definc/#def_true/#tage/#tog./#definc/#defintrue/#tog/#tage/#def_statement/#tes#def/#def_trines#tes#tes#tage/
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    uint32_t i;
    I = 0;
    //将系统时钟初始化为120 MHz
    uint32_t output_clock_rate_Hz;
    output_clock_rate _Hz = ROM_SysCtlClockFreqSet (
    (SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN |
    SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、
    System_clock);
    //assert (output_clock_rate _Hz = system_clock);
    
    //初始化 Launchpad 的 GPIO 引脚
    //PinoutSet (false、false);
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOM);
    
    ROM_GPIOPinTypeGPIOOutput (GPIO_PORTM_BASE、GPIO_PIN_4 | GPIO_PIN_5);
    //GPIOPadConfigSet (GPIO_PORTM_BASE、GPIO_PIN_4 | GPIO_PIN_5、GPIO_Strength _2mA、GPIO_PIN_TYPE_STD);
    //创建演示任务
    // xTaskCreate (demLEDTask、(const portCHAR *)"LEDs"、configMINIMAL_STACK_SIZE、NULL、2、 空);
    //
    // xTaskCreate (demSerialTask、(const portCHAR *)"Serial"、configMINIMAL_STACK_SIZE、NULL、 1、NULL);
    while (1)
    {
    GPIOPinWrite (GPIO_PORTM_BASE、GPIO_PIN_4 |GPIO_PIN_5、0);
    //for (i=0;i<2;i++){}
    //SysCtlDelay();
    GPIOPinWrite (GPIO_PORTM_BASE、GPIO_PIN_4 | GPIO_PIN_5、GPIO_PIN_4 | GPIO_PIN_5);
    }
    
    //vTaskStartScheduler();
    返回0;
    
    }
    
    
    //刷写 launchpad 上的 LED
    //void demLEDTask (void *pvParameters)
    //(;
    
    )//
    
    //{
    ////// GPIOPinWrite (GPIO_PORTM_BASE、GPIO_PIN_4 |GPIO_PIN_5、0);
    // //for (i=0;i<1;i++){}
    // //SysCtlDelay (1);
    // GPIOPinWrite (GPIO_PORTM_BASE、GPIO_PIN_4 | GPIO_PIN_5、GPIO_PIN_4 | GPIO_PIN_5);
    // //打开 LED 1
    // LEDWrite (0x0F、0x01);
    // vTaskDelay (100);
    //
    //打开 LED 2
    // LEDWrite (0x0F、0x02);
    // vTaskDelay (100);
    //
    //打开 LED 3
    // LEDWrite (0x0F、0x04);
    // vTaskDelay (100);
    //
    //打开 LED 4
    // LEDWrite (0x0F、0x08);
    // vTaskDelay (100);
    //}
    //
    
    
    通过 Stellaris 调试接口 UART 端口写入文本
    // void SerialTask (void *pvParameters)
    //{
    //
    ////////////设置连接到虚拟 COM 端口的 UART
    // UARTStdioConfig (0、57600、system_clock);
    //
    //
    (针对
    //)
    UARTprintf ("\r\nHello、World from FreeRTOS 9.0!");
    // vTaskDelay (5000 / portTIK_PERIOD_MS);
    //}
    //}
    
    
    //* assert() Error 函数
    *
    从 driverlib/debug.h 中执行失败的断言()在此函数中
    */
    void __error_(* pcchar、uint32_t ui32Line)
    {
    //在此处放置一个断点以捕获错误,直到日志记录例程完成
    while (1)
    {
    }
    }
    

    e2e.ti.com/.../FreeRTOS_5F00_tiva_5F00_demo.zip

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

    您好!

    [引用 USER="Sahil]void adc_conv_start (void)

    GPIOPinWrite (ADC_CTRL1_PORT、ADC_CNVSTARTA |ADC_CNVSTARTB、0);
    //for (i=0;i<1;i++){}
    //SysCtlDelay (1);
    GPIOPinWrite (ADC_CTRL1_PORT、ADC_CNVSTARTA | ADC_CNVSTARTB、ADC_CNVSTARTA | ADC_CNVSTARTB);
    }[/报价]

    可能会尝试切换函数的静态 void? 很明显、它被切换之间的另一个调用中断、或者操作系统任务处理程序计时器的运行速度低于 GPIO 切换速率。 请注意、从 非按位和 "((~LED)& 0x10)"切换 LED 可能会产生意外结果。 和按位非"&(~pin)"应 用于反转位、但 CCS 编译器似乎从未 按预期反转引脚。 GPIOPinWrite()在使用 kiss 方法时效果更好,只使用十六进制值,不 按位,不使用 OR,并添加到语法中。

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

    您遇到的有趣结果。 我继续、再次导入您的项目并进行了一些测试。 如果您删除预定义的符号"debug"、切换时间看起来不错。

    我最奇怪的是、__error__函数需要位于 main.c 文件中、并且它不会看到 driverlib 调试文件。 我不知道为什么会出现这种情况。 我认为您的项目可能在某种程度上已经腐败。

    当我创建一个新项目并复制您的代码时、 我不再需要在 main.c 文件中使用__error__-只需包含 debug.h 就足够了-我能够包含调试预定义符号,并且仍然可以快速切换 GPIO (免责声明: 我没有准确地衡量是否存在微小的性能下降来添加它)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Ralph、

    是的、您说得对、我也注意到了同样的情况。
    我还将代码移动到了一个全新的清理项目中、现在运行正常。 它能够在170nsec 时切换。 这仍然是有问题的、因为系统时钟为120MHz、但改进得比3.8usec 大得多。
    我会将您的答案标记为已解决问题。

    感谢你的帮助。

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

    一般而言、由于必须执行的指令数量、GPIO 切换速度会比您看到的慢。 GPIO 切换速度最快的实际上是使用 PWM 模式、最高可达40MHz。 您所看到的内容对我来说听起来很正常、因此如果它足以满足您的应用需求、那么您应该可以继续操作。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Ralph、

    是的、我正在考虑将我的部分引脚移植到芯片的 PWM 引脚。 尤其是在外部连接的 ADC 启动 ADC 转换时所需的时间。

    在处理该问题时、我注意到以下两件事、只是想理解;

    GPIO 切换的部分改进来自于优化部分下的速度与尺寸折衷设置。 如下文所示。 我的问题是这在技术上意味着什么以及它是如何工作的? 已附加快照。

    2.我注意到切换脉冲的间隔不均匀,如下图所示。 由于这两个寄存器都由同一指令驱动,所以写入寄存器的值与不均匀间隔的值是什么不同的? 附加的快照

    GPIOPinWrite (ADC_CTRL2_PORT、ADC_CS | ADC_READ、0);
    //
    GPIOPinWrite (ADC_CTRL2_PORT、ADC_CS | ADC_READ、ADC_CS | ADC_READ); 

    谢谢

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

    您好、Sahil、

    [引用 user="Sahil]1. GPIO 切换的部分改进来自于优化部分下的速度与尺寸折衷设置。 如下文所示。 我的问题是这在技术上意味着什么以及它是如何工作的? 已附加快照。[/quot]

    它与编译器如何实际分解 C 代码并将其转换为 MCU 的程序代码有关。 从较高层次的角度来看、我将描述 优化速度、因为编译器会尝试尽可能地缩短指令执行时间、但代价是在需要时通过重复代码来使用更多空间、以便更快地访问指令。 相反、优化大小使编译器尝试尽可能多地重用代码、但代价是扩展操作会导致某些代码块的访问时间增加、因为需要处理的附加指令会增加执行时间。

    [引用 user="Sahil]2. 我注意到切换脉冲的间隔不均匀、如下图所示。 由于这两个寄存器都由同一指令驱动,所以写入寄存器的值与不均匀间隔的值是什么不同的? 附加的快照[/报价]

    我最初的反应是、该工具的数字部分由于其采样方式可能显示拉伸周期、我在自己的 LSA 上看到了很多(尽管它的功能肯定不如您的示波器那样强大)。 您是否检查了示波器功能的模拟部分上的波形、以查看它们是否与数字部分上显示的波形完全一致?

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

     您好 Ralph、

    很抱歉我迟到了。 我现在有时间用模拟通道对其进行示波、结果如下所示。 这两个延迟之间的差异似乎是真实的。