首页 > 解决方案 > ESP8266-01 对带有 TM4C123GH6PM 的 UART 上的 AT 命令没有反应

问题描述

我正在尝试将 Texas Instruments 的 TM4C123GH6PM 微控制器与我的智能手机连接,并用它来控制闹钟和 LED 灯。(LED 由晶体管控制,晶体管由 GPIO 引脚控制)。我有一些使用 C++ 和 TM4C123GH6PM 编码的经验,但我仍在学习很多东西。所以请原谅我可能犯的一些愚蠢的错误。

我想使用 UART 和 TivaWare 框架将 ESP8266 与微控制器连接起来。我已经编写了一些代码并且我的 UART 工作正常(我通过从 UART 4 到 3 发送字符来测试它)。

根据 ESP8266 的 AT 命令,它应该以“OK”响应“AT”。但是每当我向 ESP 发送一些东西时,它都会准确地回复我发送给它的内容。我检查了接线,这不是问题。或者至少我是这么认为的。如果接线错误,请纠正我。

ESP -> TM4C123GH6PM:
GND -> GND
VCC -> 3.3V
Tx -> Rx (UART3 / PC6)
Rx -> Tx (UART4 / PC5)
CH_PD -> 3.3V

我还检查了 ESP 的功耗。一切都由我笔记本电脑的 USB 端口供电,因为这有助于防止电缆混乱。我使用( https://www.amazon.de/gp/product/B07C8CM5TG/ref=ppx_yo_dt_b_asin_title_o08_s00?ie=UTF8&psc=1 )监控功耗。ESP 从计算机中汲取约 150mA 电流,但端口可以提供更多电流。我检查了一些 LED,400mA 不是问题。

谁能帮我?我现在正在为此工作两天多,但找不到解决方案。ESP 没有正确响应 AT 命令的问题是什么?当代码运行时,蓝色灯为一。

PS:随附的代码还包含闹钟控制和 LED 的代码。我附上了它,因为它可能是问题的一部分,但其中一些被注释掉了,大部分没有使用。

#include<stdint.h>

#include<stdbool.h>

#include"inc/hw_ints.h"

#include"inc/hw_memmap.h"

#include"inc/hw_types.h"

#include"driverlib/gpio.h"

#include"driverlib/sysctl.h"

#include"driverlib/timer.h"

#include"driverlib/interrupt.h"

#include"driverlib/uart.h"

#include"driverlib/pin_map.h"

#include "driverlib/rom.h"

// stores the time since system start in ms
uint32_t systemTime_ms;

//bools or controling the alarm clock and LEDS
bool an_aus = false;
bool alarm_clock = false;

void InterruptHandlerTimer0A (void)
{
    // Clear the timer interrupt flag to avoid calling it up again directly
    TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    // increase the ms counter by 1 ms
    systemTime_ms++;
}

void clockSetup(void)
{
    uint32_t timerPeriod;
    //configure clock
    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ| SYSCTL_OSC_MAIN);
    //activate peripherals for the timer
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    // configure timers as 32 bit timers in periodic mode
    TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
    // set the variable timerPeriod to the number of periods to generate a timeout every ms
    timerPeriod = (SysCtlClockGet()/1000);
    // pass the variable timerPeriod to the TIMER-0-A
    TimerLoadSet(TIMER0_BASE, TIMER_A, timerPeriod-1);
    // register the InterruptHandlerTimer0A function as an interrupt service routine
    TimerIntRegister(TIMER0_BASE, TIMER_A, &(InterruptHandlerTimer0A));
    // activate the interrupt on TIMER-0-A
    IntEnable(INT_TIMER0A);
    // generate an interrupt when TIMER-0-A generates a timeout
    TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    // all interrupts are activated
    IntMasterEnable();
    // start the timer
    TimerEnable(TIMER0_BASE, TIMER_A);
}

void UART (void)
{
       //configure UART 4:
       SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
       SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);
       while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UART4));

       //GPIO pins for transmitting and receiving
       GPIOPinConfigure(GPIO_PC4_U4RX);
       GPIOPinConfigure(GPIO_PC5_U4TX);
       GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5);

       //configure UART 8Bit, no parity, baudrat 38400
       UARTConfigSetExpClk(UART4_BASE, SysCtlClockGet(), 38400, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

       //configure UART 3:
       SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3);
       while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UART3));
       GPIOPinConfigure(GPIO_PC6_U3RX);
       GPIOPinConfigure(GPIO_PC7_U3TX);
       GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7);
       UARTConfigSetExpClk(UART3_BASE, SysCtlClockGet(), 38400, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
}

void delay_ms(uint32_t waitTime)
{
    // Saves the current system time in ms
    uint32_t aktuell = systemTime_ms;
    // Wait until the current system time corresponds to the sum of the time at the start of the delay and the waiting time
    while(aktuell + waitTime > systemTime_ms);
}

void ex_int_handler(void)
{
    // press the button to start timer for alarm clock
    alarm_clock = true;
    GPIOIntClear(GPIO_PORTF_BASE,GPIO_PIN_4);
}

int main(void)
{
    //Peripherals for LED and GPIO
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    //UART
    UART();

    //Timer
    clockSetup();

    // button
    GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,GPIO_PIN_4);
    GPIOPadConfigSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);

    //OnboardLED
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_1);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_3);

    //Interrupt Timer
    GPIOIntDisable(GPIO_PORTF_BASE,GPIO_PIN_4);
    GPIOIntClear(GPIO_PORTF_BASE,GPIO_PIN_4);
    GPIOIntTypeSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_FALLING_EDGE);
    GPIOIntRegister(GPIO_PORTF_BASE,ex_int_handler);
    GPIOIntEnable(GPIO_PORTF_BASE,GPIO_PIN_4);

    //Transistor Gate
    GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_0);
    //GPIOPadConfigSet(GPIO_PORTB_BASE,GPIO_PIN_0,GPIO_STRENGTH_6MA,GPIO_PIN_TYPE_STD_WPU);

    //debugging only: save all the received data from the ESP in an array to look at while debugging
    int32_t data[20] = {0};
    int32_t j = 0;

    //Code for debugging the UART and ESP8266
while(1){

    //Checks for Data in the FIFO
    while(!UARTCharsAvail(UART4_BASE));

    //send AT-command to ESP8266
    UARTCharPut(UART4_BASE, 'A');
    while(UARTBusy(UART4_BASE));
    UARTCharPut(UART4_BASE, 'T');
    while(UARTBusy(UART4_BASE));

    if(UARTCharsAvail(UART3_BASE))
    {
        while(UARTCharsAvail(UART3_BASE))
        {
            //Read data from the FIFO in UART3 -> received from ESP8266
            data[j] = UARTCharGet(UART3_BASE);
            j++;
        }
    }

    //clear array when its full
    if (j >= 20)
    {
        j = 0;
        for(int32_t a = 0; a <21; a++)
        {
            data[a] = 0;
        }
    }
}

//code to run the alarm clock and leds
    /*
    while(1)
    {
        if (alarm_clock)
        {
            GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3,GPIO_PIN_3);
            //Wait
            delay_ms(30600000);
            GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_0,GPIO_PIN_0);
            alarm_clock = false;
            GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3,0x00);
            //Start Red LED blinking when it is finished
             while(1)
            {
                GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,GPIO_PIN_1);
                delay_ms(1000);
                GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,0x00);
                delay_ms(1000);

            }
        }
    }
    */
}

标签: c++cmicrocontrolleresp8266

解决方案


根据 ESP8266 的 AT 命令,它应该以“OK”响应“AT”。但是每当我向 ESP 发送一些东西时,它都会准确地回复我发送给它的内容

带有 AT 命令的调制解调器通常在出厂时会打开回显模式,这样当您通过串口手动与其交互时,它会回显您先发送的字符,然后再发送回复。

因此,当您使该过程自动化时,您首先发送字符,然后等待回复,直到您到达“\r”。好吧,你正在到达一个'\ r',但它来自回声。接下来你可能会有其他角色。你发送AT,你应该先收到AT,然后你就OK了。

要解决此问题,您应该关闭回声模式。关闭回声的命令是ATE0


推荐阅读