Реклама ⓘ
Главная » Микроконтроллеры
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Реклама ⓘ

Связь по Bluetooth между STM32 и Android

В данной статье показан один из рабочих вариантов связи по Bluetooth соединению между микроконтроллером STM32 (используется плата STM32 Value Discovery) и любым Android-устройством (смартфон, планшет и т.п.). В качестве примера показано управление светодиодом с планшета, а также обратная отправка сообщений в Android.

В качестве Bluetooth модуля используется дешевый китайский модуль HC-06, который был рассмотрен в этой статье.

Bluetooth модули

В качестве Android устройства используется дешевый китайский планшет Ainol Aurora с внешним USB-Bluetooth модулем (т.к. своего нет), подключенным через USB Host.

Схема подключения платы STM32 Discovery к модулю HC-06 проста:

Схема подключения Bluetooth к STM32

Для тех, кто не работал с STM32 лучше сначала прочитать 3 вводные статьи для начинающих по STM32.

Программа для STM32 писалась в среде CooCox CoIDE, на основе стандартного примера STMicroelectronics. ПО для Android писалось в среде Eclipse и основано на коде из этой статьи, за исключением того, что настройки MAC-адреса Bluetooth модуля из тела программы вынесены в меню.

Исходный код программы для STM32:

#include "stm32f10x_usart.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "misc.h"

int i;

//ErrorStatus HSEStartUpStatus;

void NVIC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);
void USART1_IRQHandler(void);
void UARTSend(const unsigned char *pucBuffer, unsigned long ulCount);

int main(void)
{
	usart_rxtx();
    while(1)
    {

    }
}

/******************************************************************************/
/*            STM32F10x Peripherals Interrupt Handlers                        */
/******************************************************************************/

/**
  * @brief  Функция обработчик прерывания USARTx.
  * @param  None
  * @retval None
  */
void USART1_IRQHandler(void)
{
    if ((USART1->SR & USART_FLAG_RXNE) != (u16)RESET)
	{
		i = USART_ReceiveData(USART1);
		if(i == '1'){
			GPIO_WriteBit(GPIOA,GPIO_Pin_8,Bit_SET);		// Устанавливаем '1' на 8 ноге
			UARTSend("LED ON\r\n",sizeof("LED ON\r\n"));	// Выводим надпись в UART
		}
		else if(i == '0'){
			GPIO_WriteBit(GPIOA,GPIO_Pin_8,Bit_RESET);		// Устанавливаем '0' на 8 ноге
			UARTSend("LED OFF\r\n",sizeof("LED OFF\r\n"));
		}
	}
}

void usart_rxtx(void)
{
    const unsigned char welcome_str[] = " Welcome to Bluetooth!\r\n";

    /* Enable USART1 and GPIOA clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

    /* NVIC Configuration */
    NVIC_Configuration();

    /* Configure the GPIOs */
    GPIO_Configuration();

    /* Configure the USART1 */
    USART_Configuration();

    /* Enable the USART1 Receive interrupt: this interrupt is generated when the
         USART1 receive data register is not empty */
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

    /* print welcome information */
    UARTSend(welcome_str, sizeof(welcome_str));
}

/*******************************************************************************
* Function Name  : GPIO_Configuration
* Description    : Конфигурирование GPIO.
*******************************************************************************/
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure); //Сохраняем

  /* Конфигурируем USART1 Tx (нога PA.09) как симметричный (push-pull) пин */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Конфигурируем USART1 Rx (PA.10) как вход без подтяжки */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

/*******************************************************************************
* Function Name  : USART_Configuration
* Description    : Настройка USART1.
*******************************************************************************/
void USART_Configuration(void)
{
  USART_InitTypeDef USART_InitStructure;

/* USART1 configuration ------------------------------------------------------*/
  /* USART1 configured as follow:
        - BaudRate = 9600 baud
        - Word Length = 8 Bits
        - One Stop Bit
        - No parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
        - USART Clock disabled
        - USART CPOL: Clock is active low
        - USART CPHA: Data is captured on the middle
        - USART LastBit: The clock pulse of the last data bit is not output to
                         the SCLK pin
  */
  USART_InitStructure.USART_BaudRate = 9600;		// Скорость передачи
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  USART_Init(USART1, &USART_InitStructure);

  /* Включаем USART1 */
  USART_Cmd(USART1, ENABLE);
}

/**
  * @brief  Настройка прерывания.
  * @param  None
  * @retval None
  */
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Включаем прерывание от USARTx */
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

/*******************************************************************************
* Function Name  : UARTSend
* Description    : Отсылает строку данных по UART.
* Input          : - pucBuffer: buffers to be printed.
*                : - ulCount  : buffer's length
*******************************************************************************/
void UARTSend(const unsigned char *pucBuffer, unsigned long ulCount)
{
    //
    // Loop while there are more characters to send.
    //
    while(ulCount--)
    {
        USART_SendData(USART1, (uint16_t) *pucBuffer++);
        /* Loop until the end of transmission */
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
        {
        }
    }
}

Код достаточно простой, в функции GPIO_Configuration() происходит конфигурирование ног контроллера, в USART_Configuration() настраивается UART, а в функции NVIC_Configuration () происходит настройка прерывания.

Для передачи строки по UART служит функция UARTSend(), а при приеме данных происходит прерывание и срабатывает функция USART1_IRQHandler(). В данной функции, в зависимости от принятой цифры 1 или 0, подается команда на 8-ногу платы для включения или выключения подключенного к ней светодиода. А также, происходит передача строки "LED ON" или "LED OFF" обратно в UART. Как видите ничего сложного нет.

Вид главного активити в Android планшете

Исходный код приложения для Android я приводить не буду, т.к. он большой и основан на этой статье. Расскажу лишь про отличия. Каждое Bluetooth устройство содержит свой уникальный MAC-адрес. В вышеупомянутой статье он задавался в коде программы в виде константы, и чтобы его изменить нужно было ставить среду Eclipse, загружать проект, редактировать эту строчку, компилировать и устанавливать его в устройство. Поэтому я решил вынести установку MAC-адреса в настройки. Для этого я использовал android.preference. Я прилагаю проект в Eclipse и готовый APK файл, если возникнут какие-то вопросы по статье, то спрашивайте ниже в комментариях, либо на форуме по STM32.

Данный проект может быть взят за основу для более серьезного проекта, к примеру построение робота, с управлением от Android (собственно о чем мы и расскажем в следующих статьях), прием данных от уличной метеостанции на ваш телефон и т.п.

Прикрепленные файлы:

Теги:

Опубликована: 04.11.2012 0 0
Я собрал 0 0
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 0 Проголосовало: 0 чел.

Комментарии (6) | Я собрал (0) | Подписаться

0
Андрей #
А можно то же самое сделать только на основе Wi-Fi. Так как, сейчас интересуюсь умным домом. И управление естественно, должно быть через смартфонпланшет. А Bluetooth ограничен в радиусе действия... Или есть возможность расположить несколько передатчиков Bluetooth в разных комнатах?
Ответить
0
taliban #
Можно конечно и Wi-Fi. Но тут еще вопрос в цене, модуль Bluetooth стоит 5$, а самый дешевый модуль Wi-Fi 50$.
Ответить
0
Slava #
Wi-Fi модуль ESP8266 -3$
Ответить
0

[Автор]
talibanich #
Посмотрите дату публикации статьи и погуглите были ли тогда в природе ESP8266
Ответить
0
Еккубовичч #
Встраивать Bluetooth или, тем более WiFi модули в каждое управляемое устройство слишком жирно будет. Забивание большой кувалдой маленьких гвоздиков. Надо попроще что-нибудь. Попроще и поменьше в размерах, радиомодули например. Там радиус действия 50-150 метров.
Ответить
0
sergetk #
Спасибо за пример, но! Без явного конфигурирования альтернативной функции на STM32L152 у меня не заработало:
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
И еще, может я ошибаюсь, но не нужно ли в конце прерывания сбросить флажок?
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическая мощность?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Программатор Pickit3
Программатор Pickit3
200 Вт усилитель класса D на IRS2092 Discovery V8
вверх