Предыдущая часть здесь. Весь список статей здесь.

Приступим к работе с STM32.
Для начала подключим всю необходимую периферию:
#include "stm32f10x.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #include "stm32f10x_usart.h" #include "stm32f10x_i2c.h" #include "stdio.h" #include "string.h" #include "misc.h"
И к ним же подключим библиотеки для работы с пирометром HW-691 (mlx9061) по шине I2C, библиотеку пирометра, библиотеку ds18b20 и для работы с ней OneWire:
#include "Сx.h" // Библиотека для подключения пирометра HW-691 #include "mlx9061x.c" #include "i2cm.h" #include "i2cm.c" #include "ds18b20.h" // Библиотека для работы с ds18b20 #include "ds18b20.c" #include "onewire.h" // Библиотека для подключения ds18b20 к шине OneWire #include "onewire.c"
После чего перед описанием функции инициализации портов создадим переменные для работы с нашими датчиками:
float Ta, To1, To2; // Переменные для работы с пирометром float t1_ds18b20, t2_ds18b20; // Переменные для работы с DS18B20
… сама функция инициализации. В ней инициализация только тех блоков, что требуются для работы с дисплеем и нашими датчиками. Остальное убрано, чтобы не снижать читабельность кода и статьи в целом.
void Init_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //разрешаем тактирование RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //разрешаем тактирование RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //разрешаем тактирование //TX UART. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); //инициализируем //RX UART. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);//инициализируем USART_InitStructure.USART_BaudRate = 9600;// скорость USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8 бит данных 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_Tx; // | USART_Mode_Rx; USART_Init(USART2, &USART_InitStructure); //инизиализируем USART_Cmd(USART2, ENABLE); // запускаем сам USART }
Ну и последние две незамысловатые функции вне основного цикла: первая для отправки символа по интерфейсу UART; вторая для отправки строки (массива символов).
void send_Uart(USART_TypeDef* USARTx, unsigned char c) // отправить байт { while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE)== RESET){} USART_SendData(USARTx, c); } void send_Uart_str(USART_TypeDef* USARTx, unsigned char *s) { while (*s != 0) send_Uart(USARTx, *s++); }
То, что содержит основная функция int main, для понимания будет пояснено в комментариях
int main(void) { int i; // Переменная для использования в примитивной задержке Init_Configuration(); mlx90614_init(I2C1); // Говорим микроконтроллеру на какой шине I2C висит пирометр // USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // Прерывание по приему UART NVIC_EnableIRQ(USART2_IRQn); // Разрешение прерывания по UART - char t0[] = "99"; // Значение в цифровом поле дисплея по дефолту char t1[] = "99"; // Значение в цифровом поле дисплея по дефолту char t2[] = "99"; // Значение в цифровом поле дисплея по дефолту if(ds18b20_init() == 0) { // Если датчики DS18B20 не обнаружены //ERROR NO SENSORS }
Так как за то время пока писалась эта статья, один из датчиков DS18B20 ушел в другой проект, поэтому дальше будет использоваться один, но нам хватит и его (но сам код будет рассчитан на два датчика).
while(1) { ds18b20_start_convert(); // Запуск считывания информации с шины onewire for (i=0; i<1000000; i++); // небольшая задержка t1_ds18b20 = ds18b20_get_temp(0); // получить температуру с первого датчика t2_ds18b20 = ds18b20_get_temp(1); // получить температуру со второго датчика // mlx9061x_ReadTa(I2C1, MLX9061X_I2C_ADDR, &Ta); // Температура измерителя // mlx9061x_ReadTo2(I2C2, MLX9061X_I2C_ADDR, &To2); // Температура по второму ИК измерителю mlx9061x_ReadTo1(I2C1, MLX9061X_I2C_ADDR, &To1); // Температура по первому ИК измерителю for(i=0;i<10000;i++); // небольшая задержка char n0[] = "n0.val="; // Заготовка строки для склеивания и отправки по UART char n1[] = "n1.val="; // Заготовка строки для склеивания и отправки по UART char n2[] = "n2.val="; // Заготовка строки для склеивания и отправки по UART char To1char = (char)To1; char t1char = (char)t1_ds18b20; // Преобразование флоат в char char t2char = (char)t2_ds18b20; // Преобразование флоат в char sprintf(t0, "%d", t1char); // Преобразование в массив char strncat(n0, t0, strlen(t0)); // Склеивание n0 и t0 (n0=n0+t0) send_Uart_str(USART2, n0); // Отправка по UART получившейся строки send_Uart(USART2, 0xff); // Отправка 0xFF три раза send_Uart(USART2, 0xff); // чтобы дисплей "переварил" send_Uart(USART2, 0xff); // полученную информацию sprintf(t1, "%d", t2char); // Преобразование в массив char strncat(n1, t1, strlen(t1)); // Склеивание n0 и t0 (n0=n0+t0) send_Uart_str(USART2, n1); send_Uart(USART2, 0xff); send_Uart(USART2, 0xff); send_Uart(USART2, 0xff); sprintf(t2, "%d", To1char); // Преобразование в массив char strncat(n2, t2, strlen(t2)); // Склеивание n0 и t0 (n0=n0+t0) send_Uart_str(USART2, n2); send_Uart(USART2, 0xff); send_Uart(USART2, 0xff); send_Uart(USART2, 0xff); send_Uart_str(USART2, "n0.pco=2016"); // Установка зеленого цвета send_Uart(USART2, 0xff); send_Uart(USART2, 0xff); send_Uart(USART2, 0xff); } }
Практически каждая строка было прокомментирована, поэтому нет необходимости повторяться, кроме последнего фрагмента, о нем подробнее. Строка
send_Uart_str(USART2, "n0.pco=2016");устанавливает цвет текста, таким образом можно установить практически любой параметр, но чаще используется для шрифта или цвета текста. Посмотреть код цвета и обозначение параметров можно через Nextion Editor:

Таким образом, командой, отправленной с микроконтроллера, можно установить как шрифт, так и его цвет на дисплее Nextion. Чтобы изменить строку “newtxt”, надо отправить следующие команды на дисплей, не забыть экранирование кавычек, чтобы компилятор не заругался:
send_Uart_str(USART2, "t2.txt=\"PIROSENS\""); // Установка значения текста send_Uart(USART2, 0xff); send_Uart(USART2, 0xff); send_Uart(USART2, 0xff);
Следующее повторяем для каждого текста. Я добавил небольшую задержку между каждой отправкой значения на Nextion дисплей, чтобы уменьшить вероятность сбоя.

Все исходники скачать архивом можно здесь
Дисплей прекрасно работает от 3,3 вольт!