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 данные на ведомый контроллер.
Спасибо всем за внимание! Ждите следующих уроков!
Отладочную плату STM32F103C8T6 можно приобрести здесь STM32F103C8T6
Программатор недорогой можно купить здесь ST-Link V2
Переходник USB to TTL можно приобрести здесь ftdi ft232rl
Отладочную плату NUCLEO-F303K8 можно купить здесь NUCLEO-F303K8
Модули bluetooth HC-05 и HC-06 можно купить здесь bluetooth HC-05 HC-06
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)





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