STM Урок 99. HC-05. Master. Соединяем два МК. Часть 2

 

 

 

В предыдущей части нашего занятия мы настроили модуль HC-05 для работы в режиме ведущего устройства, также настроили контроллер, к которому мы будем подключать данный модуль, для работы с дисплеем.

 

Пока не будем подключать модуль, а настроим наш дисплей. Мы сделаем вывод пришедших к нам из модуля строк в нижнюю строку дисплея, при этом верхние мы будем сдвигать. Сначала у меня была задумка считать память из дисплея и затем сдвигать строки. но считать данную память мне, к сожалению, через переходник не удалось, поэтому я решил всё таки три нижние строки хранить в массиве на 60 символов. Думаю, для памяти невелика потеря, да и работать будет копирование в памяти гораздо быстрее, чем считывание через I2C её из дисплея. А верхнюю строку нам хранить ни к чему, так как она все равно заменится более нижней. Поэтому давайте перейдём в файл lcd.c и добавим данный массив

 

uint8_t portlcd; //ячейка для хранения данных порта микросхемы расширения

char str2[60]={0};

 

Заполним его пробелами в функции инициализации LCD_ini

 

setwrite();//запись

//Запишем пробелы в строковый массив

memset((void*)str2,(uint8_t)' ',60);

 

Выше функции инициализации добавим функцию вывода строки вниз дисплея

 

//------------------------------------------------

void LCD_StrBottom(char* st)

{

  uint8_t i=0,j=0,str_cnt=0;

}

//------------------------------------------------

 

И начнём писать её тело. Так как мы условились, что мы храним нижние три строки, то выведем их теперь в верхние три строки

 

uint8_t i=0,j=0,str_cnt=0;

//Выведем ранее заготовленные верхние три строки на дисплей

for(j=0;j<3;j++)

{

  LCD_SetPos(0,j);

  for(i=0;i<20;i++)

  {

    sendbyte(str2[j*20+i],1);

  }

}

 

Далее мы выведем нижнюю строку из пришедшего массива

 

    sendbyte(str2[j*20+i],1);

  }

}

//выведем последнюю строку

LCD_SetPos(0,3);

while((st[str_cnt]!=0)&&(st[str_cnt]!=0x0D)&&(st[str_cnt]!=0x0A))

{

  sendbyte(st[str_cnt],1);

  str_cnt++;

}

 

Оставшуюся часть строки в дисплее заполним пробелами, так как там могут остаться символы от той строки, которая уже там была

 

  str_cnt++;

}

//остальное - пробелы

for(i=str_cnt;i<20;i++)

{

  sendbyte((uint8_t)' ',1);

}

 

Дальше мы должны сохранить три нижние строки в массиве на следующий раз. Сначала в массиве две нижние строки сдвигаем вверх

 

  sendbyte((uint8_t)' ',1);

}

//сдвигаем 2 нижние строки вверх в массиве

for(i=0;i<2;i++){

  memcpy((void*)(str2+i*20),(void*)(str2+i*20+20),20);

}

 

А затем мы оставшуюся строку скопируем в третью (нижнюю) часть массива, и также заполним оставшиеся байты пробелами

 

    memcpy((void*)(str2+i*20),(void*)(str2+i*20+20),20);

  }

  //скопируем выводимую строку в последнюю (третью строку массива)

  memcpy((void*)(str2+40),(void*)st,str_cnt);

  //оставшуюся часть строки заполним пробелами

  memset((void*)(str2+40+str_cnt),(uint8_t)' ',20-str_cnt);

}

 

Создадим на данную функцию прототип в заголовочном файле и испытаем нашу функцию в main(), Изменив там соответствующим образом код

 

HAL_UART_Receive_IT(&huart1,(uint8_t*)str1,1);

sprintf(str1,"String 1");

LCD_StrBottom(str1);

sprintf(str1,"String 2");

LCD_StrBottom(str1);

sprintf(str1,"String 3");

LCD_StrBottom(str1);

sprintf(str1,"String 4");

LCD_StrBottom(str1);

/* USER CODE END 2 */

 

Как мы видим на экране дисплея — наш код работает

 

 

 

Подключим теперь наш модуль к отладочной плате, также поглядывая на рисунок из мануала платы и в Cube MX (нажмите на картинку для увеличения изображения)

 

 

Код, который мы добавили для теста в main(), можно удалить. Теперь займёмся USART-ом, чтобы поймать строки, которые нам придут с ведомого устройства. Добавим глобальную структуру и переменную её типа

 

char str1[21];

typedef struct USART_prop{

  uint8_t usart_buf[23];

  uint8_t usart_cnt;

  uint8_t is_tcp_connect;//статус попытки создать соединение TCP с сервером

  uint8_t is_text;//статус попытки передать текст серверу

} USART_prop_ptr;

USART_prop_ptr usartprop;

 

Добавим функцию разбора строки, в которой сегодня просто отправим в дисплей пришедшую в функцию строку

 

/* USER CODE BEGIN 0 */

//-----------------------------------------------

void string_parse(char* buf_str)

{

  LCD_StrBottom(buf_str);

}

//-----------------------------------------------

/* USER CODE END 0 */

 

И также добавим привычную уже нам функцию обработки байта, пришедшего по USART

 

//-----------------------------------------------

void UART1_RxCpltCallback(void)

{

  uint8_t b;

  b = str1[0];

  //если вдруг случайно превысим длину буфера

  if (usartprop.usart_cnt>22)

  {

    usartprop.usart_cnt=0;

    HAL_UART_Receive_IT(&huart1,(uint8_t*)str1,1);

    return;

  }

  usartprop.usart_buf[usartprop.usart_cnt] = b;

  if(b==0x0A)

  {

    usartprop.usart_buf[usartprop.usart_cnt+1]=0;

    string_parse((char*)usartprop.usart_buf);

    usartprop.usart_cnt=0;

    HAL_UART_Receive_IT(&huart1,(uint8_t*)str1,1);

    return;

  }

  usartprop.usart_cnt++;

  HAL_UART_Receive_IT(&huart1,(uint8_t*)str1,1);

}

//-----------------------------------------------

 

И также добавим обработчик прерывания от USART

 

/* USER CODE BEGIN 4 */

//-----------------------------------------------

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

  if(huart==&huart1)

  {

    UART1_RxCpltCallback();

  }

  }

//-----------------------------------------------

/* USER CODE END 4 */

 

Включим нашу схему, также включим схему с ведомым модулем. Соберём код. прошьём контроллер. И, как только модули соединятся, то мы начнём получать строки вот таким вот образом (нажмите на картинку для увеличения изображения)

 

 

Таким образом, нам в данном уроке удалось настроить модуль bluetooth HC-05 в режиме ведущего устройства, также подключить его к контроллеру, соединить по воздуху два модуля, подключенные каждый к своему контроллеру, а также передать данные по bluetooth с помощью данных модулей от одного микроконтроллера к другому  и отобразить их на дисплее. Теперь мы можем спокойно подключить к ведомому контроллеру, например, любые датчики и передавать по bluetooth данные на ведомый контроллер.

Спасибо всем за внимание! Ждите следующих уроков!

 

Предыдущая часть Программирование МК STM32 Следующий урок

 

Исходный код

 

 

Переходник USB to TTL можно приобрести здесь ftdi ft232rl

Модуль bluetooth HC-05 можно купить здесь bluetooth HC-05

Отладочную плату STM32F103C8T6 можно приобрести здесь STM32F103C8T6

Отладочную плату NUCLEO-F303K8 можно купить здесь NUCLEO-F303K8

Программатор недорогой можно купить здесь ST-Link V2

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

STM HC-05. Master. Соединяем два МК

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*