H C -05 Bluetooth-модуль нуждается в каждой инструкции 3 раза - PullRequest
0 голосов
/ 17 апреля 2020

Я пытаюсь управлять некоторыми светодиодами через микроконтроллер TM4C123GH6PM. Я написал приложение Android, которое подключается к микроконтроллеру через Bluetooth и отправляет строки на H C -05. H C -05 отправляет команды через UART на микроконтроллер. Все это работает, но по какой-то причине мне нужно отправить каждую Команду несколько раз (большую часть времени 3 раза), чтобы микроконтроллер зарегистрировал команду. Кроме того, иногда случается, что я посылаю команду несколько раз зеленым, пока не загорится зеленый светодиод, а затем отправляю другую команду, но микроконтроллер регистрирует новые зеленые команды, прежде чем новая команда будет зарегистрирована. У кого-нибудь есть идея, почему это так?

Форма ОБНОВЛЕНИЯ сначала Ответ:

Чтобы не пропустить пропущенные байты из UART, я избавился от strcmp и изменил свои команды на простые символы вместо строк, так как мне не нужно много разных команд, и это должно уменьшить сложность. Но у меня все еще та же проблема. Теперь мне иногда приходится нажимать кнопку / отправить 8 раз, чтобы микроконтроллер заметил это. (Команды представляют собой неподписанные символы, ASCII: 48 == 0, 49 == 1 и т. Д. c ...)

#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;
    }
  }
}

1 Ответ

0 голосов
/ 17 апреля 2020

Вы не должны вызывать writeStringToUart в функции ISR. Подумайте, что это значит: вы получаете байт данных со скоростью ~ 9600 бит в секунду, затем вы начинаете передачу внутри функции приема со скоростью ~ 9600 бит в секунду, поэтому, пока вы передаете в ISR вашего первого полученного байта другой байт получен, но не обработан, поскольку вы еще не вернулись из ISR. Сделайте это для длины

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

И вполне возможно, что вы пропустите 15 байтов входящих данных, потому что вы передаете. Кроме того, strcmp, который вы делаете, также занимает довольно много времени.

...