Главная » Микроконтроллеры
Призовой фонд
на октябрь 2017 г.
1. Термометр Relsib WT51
Рэлсиб
2. 1000 руб
PCBWay
3. Регулируемый паяльник 60 Вт
Паяльник
4. 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
UNI-T UT-61A Ветрогенератор
вверх