0

我正在尝试通过 TM4C123GH6PM 微控制器控制一些 LED。我编写了一个 Android 应用程序,它通过蓝牙连接到微控制器并将字符串发送到 HC-05。HC-05 通过 UART 向微控制器发送命令。这一切都有效,但由于某种原因,我需要多次发送每个命令(大部分时间 3 次),以便微控制器注册命令。此外,有时我会多次发送绿色命令,直到绿色 LED 亮起,然后发送另一个命令,但微控制器会在新命令注册之前注册新的绿色命令。有谁知道为什么会这样?

更新表格第一个答案:

为了避免 UART 丢失字节,我摆脱了strcmp命令并将其更改为简单的字符而不是字符串,因为我不需要那么多不同的命令,这应该会降低复杂性。但我仍然有同样的问题。现在我有时必须按下按钮/发送 8 次让微控制器注意到它。(命令是无符号字符、ASCII:48 == 0、49 == 1 等...)

#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "driverlib/uart.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include <stdbool.h>
#include <stdint.h>
#include <string.h>

// ONboarLEDS
#define redLED GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1)
#define blueLED GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2)
#define greenLED GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, GPIO_PIN_3)
#define LEDoff                                                                 \
  GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3, 0x00);

// External LEDS:
#define Ligth_on GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, GPIO_PIN_0);
#define Ligth_off GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 0x00);

// Register for UART4 FIFO Data put here will be sent
#define UART4_DR_R (*((volatile uint32_t *)0x40010000))

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

bool alarm_clock = false;

// recived char form UART/Bluetooth
unsigned char rxChar;
unsigned char txChar;

// Interrupts
//////////////////////////////////////////////
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 Uart4InterruptIsr(
    void) // this interrupt routine is to transmit data over bluetooth
{
  // clear the Interrupt FLag
  UARTIntClear(UART4_BASE, UART_INT_TX);
  // DO something?
}

// Do not call write writeStringToUart4 here to avoid missing Bytes
void Uart3InterruptIsr(
    void) // this interrupt routine is for receiving data from bluetooth
{
  // clear the Interrupt FLag
  UARTIntClear(UART3_BASE, UART_INT_RX);

  // write received Byte into an Array
  rxChar = UARTCharGet(UART3_BASE);
}

// When button is pressed
void ex_int_handler(void) {
  GPIOIntClear(GPIO_PORTF_BASE, GPIO_PIN_4);
  // Turn the Tranisistor LED off:
  GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 0x00);
  // Send status
  // writeStringToUart4("\n\r");
  // writeStringToUart4("Ligth off");
  // writeStringToUart4("\n\r");
}

/////////////////////////////////////////////

// Setup
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 setupPeriphals(void) {
  // Peripherals for LED and GPIO
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

  // button
  GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4);
  GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_STRENGTH_2MA,
                   GPIO_PIN_TYPE_STD_WPU);
  // Interrupt for button
  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);

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

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

void setupUART(void) {
  // configure UART 4: (Sending)
  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(), 9600,
      (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

  // Transmit interrupt
  IntMasterEnable();
  UARTIntRegister(UART4_BASE, &(Uart4InterruptIsr));
  UARTIntEnable(UART4_BASE, UART_INT_TX);

  // configure UART 3: (Reciving)
  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(), 9600,
      (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

  // Receive interrupt
  UARTIntEnable(UART3_BASE, UART_INT_RX);
  UARTIntRegister(UART3_BASE, &(Uart3InterruptIsr));
}

///////////////////////////////////////////////////////

// Functions:

void writeCharToUart4(unsigned char a) {
  // puts char in FIFO, when FIFO is full waits.
  // UARTCharPut(UART4_BASE, a);
  while (!UARTSpaceAvail(UART4_BASE))
    ;
  UART4_DR_R = a;
}

void writeStringToUart4(char *str) {
  int i;
  for (i = 0; i < strlen(str); i++)
    writeCharToUart4(str[i]);
}

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 checkCommand() {
  switch (rxChar) {
  case 49:
    LEDoff;
    redLED;
    rxChar = 48;
    break;

  case 50:
    LEDoff;
    blueLED;
    rxChar = 48;
    break;

  case 51:
    LEDoff;
    greenLED;
    rxChar = 48;
    break;

  case 52:

    LEDoff;
    rxChar = 48;
    break;

  default:
    break;
  }
}

/////////////////////////////////////////////////////////
int main(void) {
  // setup
  clockSetup();
  setupPeriphals();
  setupUART();
  writeStringToUart4("Ready");
  writeStringToUart4("\n\r");

  while (1) {
    checkCommand();

    if (alarm_clock) {
      delay_ms(10000);
      Ligth_on;
      LEDoff;
      alarm_clock = false;
    }
  }
}
4

1 回答 1

0

你不应该调用writeStringToUart一个ISR函数。想想这意味着什么:您以每秒约 9600 位的速度接收一个数据字节,然后以每秒约 9600 位的速度在接收函数内部开始传输,因此当您在ISR第一个接收到的字节中传输时,另一个字节是收到但未处理,因为您还没有回来ISR。这样做的长度

LEDoff;
blueLED;
writeStringToUart4("\n\r");
writeStringToUart4("Blue LED ON");
writeStringToUart4("\n\r");

由于您正在传输,您很可能会错过 15 个字节的传入数据。此外,strcmp您所做的也需要相当长的时间。

于 2020-04-17T12:20:38.773 回答