0

TM4C123GH6PM マイクロコントローラーを介していくつかの LED を制御しようとしています。Bluetooth 経由でマイクロコントローラーに接続し、文字列を HC-05 に送信する Android アプリを作成しました。HC-05 は UART 経由でコマンドをマイクロコントローラに送信します。それはすべて機能しますが、何らかの理由で、マイクロコントローラーがコマンドを登録するために、すべてのコマンドを複数回 (ほとんどの場合 3 回) 送信する必要があります。また、緑色の LED が点灯するまで緑色のコマンドを複数回送信してから別のコマンドを送信しても、新しいコマンドが登録される前にマイクロコントローラーが新しい緑色のコマンドを登録することがあります。なぜこれが当てはまるのか、誰にもアイデアがありますか?

UPDATEフォームの最初の回答:

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