Четвер, 21.11.2024, 09:48
Приветствую Вас Гість | RSS

Radiomanoff+

Меню сайта
Форма входа
Календарь
«  Листопад 2024  »
ПнВтСрЧтПтСбНд
    123
45678910
11121314151617
18192021222324
252627282930

STM32L-DISСOVERY.DS18B20 и встроенный LCD

Cледуюшим шагом моих эксперементов стал датчик ds18b20, а именно вывод его показаний  на экран встроенного LCD.

Как я уже писал в предыдущей статье ,на плате STM32L-DISСOVERY, свободных от "board function" пинов (Free I/O)  - 5 шт (PA5,PA11,PA12,PC13,PD2) ,причем PA11,PA12 аппаратный USB.Я решил подключать датчик на PD2,этот пин согласно мануала толерантен к 5В.Впрочем забегу наперед ,схема работает как от 5В,так и от 3,3В.

В сети есть библиотеки для работы с этими датчиками,но они в основном "заточены" под использование USART.Я же поставил перед собой задачу использовать для вывода информации с датчика - LCD, который идет в комплекте с STM32L-DISСOVERY.А при его использовании, на плате просто не остается свободного USART,все доступные пины заняты на работу с LCD.

На одном из китайских сайтов была найдена подходящая библиотека,и я решил адаптировать ее под свою задачу и под stm32l .Библиотекa имеет два файла : DS18B20.c и DS18B20.h ( скачать).В файле DS18B20.c прописываем пин и порт на который подключен ds18b20:

#define DS_PORT   GPIOD           //DS18B20 разъем
#define DS_DQIO   GPIO_Pin_2      //GPIOD2

#define DS_RCC_PORT  RCC_AHBPeriph_GPIOD

Вообще из всего порта D в нашем микроконтролере физически присутствует только пин PD2 .Поэтому я сконфигурировал все пины порта одинаково (выход с открытым стоком):

void DS18B20_Configuration(void)
{

 RCC_AHBPeriphClockCmd(DS_RCC_PORT, ENABLE);
 //================ GPIOD CONFIGURATION ================
GPIOD->MODER=0x55555555;
GPIOD->OTYPER=0x0000FFFF;
GPIOD->PUPDR=0x00000000;
GPIOD->OSPEEDR=0xFFFFFFFF;
GPIOD->AFR[0]=0x00000000;
GPIOD->AFR[1]=0x00000000;
}

При использовании других пинов .естественно нужно вносить изменения в void DS18B20_Configuration(void).

В стандартном наборе библиотек для STM32L152 идут библиотечные файлы 
stm32l1xx_lcd.h и stm32l1xx_lcd.c
Эти файлы были подключены к проекту без изменений. В них расположены макросы для настроек индикатора, а также функция записи значений в ячейки памяти, отведенные под данные для LCD. Также были использованы библиотечные файлы из демонстрационной программы для STM32L-DISCOVERY 
stm32l_discovery_lcd.h и stm32l_discovery_lcd.c
Здесь как раз и определены массивы значений для букв и цифр (алфавит, естественно, латинский). А также функция, конвертирующая числа из этого массива в другие значения, которые зависят от того, в какую позицию индикатора символ нужно вывести (подробней - http://chipspace.ru/stm32l-discovery-lcd-2/).

Основной проблемой ,для меня ,оказалось вывести значение датчика float на экран LCD при помощи библиотеки stm32l_discovery_lcd.Решение было найдено в разбивке значения float на целую и дробную части (десятая доля):

    int t_int = t; //здесь будет целая часть
    int t_float = ((t*10)-(t_int*10)); //здесь будет дробная часть
    int t_str = (t_int*10) + t_float;
    t_str = t_str*100;

Полный текст программы:


#include "stm32l1xx_conf.h"
#include "stm32l1xx.h"
#include "lcd_gpio_init.h"
#include "stm32l_discovery_lcd.h"

uint16_t strDisp[6]; //Массив символов для вывода на дисплей
static volatile float t;

void ds18b20_init(void);
float ds18b20_read(void);
void convert_into_char(uint32_t number, uint16_t *p_tab);

int main(void)
{
    gpio_init();  //Настройка портов ввода/вывода под работу с LCD
    lcd_init();   //Здесь конфигурируем LCD контроллер
    ds18b20_init();

  while(1)
  {

    t = ds18b20_read();

    int t_int = t; //здесь будет целая часть
    int t_float = ((t*10)-(t_int*10)); //здесь будет дробная часть
    int t_str = (t_int*10) + t_float;
    t_str = t_str*100;

    /*Конвертируем результат преобразования  в массив символов.
    Результат сохраняется в элементах массива 1..4*/
    convert_into_char(t_str, strDisp);
    strDisp[3] = ' '; //Третье знакоместо дисплея оставляем пустым
    strDisp[4] = '°'; //знакт "градус"
    strDisp[5] = 'C'; //В последнее знакоместо дисплея выводим букву C
    strDisp[1] |= DOT; //Десятичная точка

    /*Следующая функция выводит на экран массив strDisp. Еще она позволяет выводить на
    экран десятичную точку или двоеточие  в любой позиции экрана.
    В данном случае команда strDisp[1] |= DOT выводит точку после второй цифры*/
    LCD_GLASS_DisplayStrDeci(strDisp);

  }
}

//************************************************************************************************
//Здесь обрабатывается неудачный результат функций assert_param() из стандартных библиотек
#ifdef  USE_FULL_ASSERT

void assert_failed(uint8_t* file, uint32_t line)
{
  while (1)
  {
  }
}
#endif
//***********************************************************************
//Эта функция конвертирует результат преобразования в массив символов
void convert_into_char(uint32_t number, uint16_t *p_tab)
{
  uint16_t units=0, tens=0, hundreds=0, thousands=0, misc=0;

  units = (((number%10000)%1000)%100)%10;
  tens = ((((number-units)/10)%1000)%100)%10;
  hundreds = (((number-tens-units)/100))%100%10;
  thousands = ((number-hundreds-tens-units)/1000)%10;
  misc = ((number-thousands-hundreds-tens-units)/10000);

  *(p_tab+4) = units + 0x30;
  *(p_tab+3) = tens + 0x30;
  *(p_tab+2) = hundreds + 0x30;
  *(p_tab+1) = thousands + 0x30;
  *(p_tab) = misc + 0x30;
}

В итоге получаем такую картинку

Проект для Em::Blocks 2.20. - http://radiomanoff.at.ua/load/ds18b20_lcd/1-1-0-23

Архив записей
Статистика

Онлайн всього: 1
Гостей: 1
Користувачів: 0