Вывод FLOAT на LCD WINSTAR + Термометр с точность 0.1 градус

Поговорим о том как вывести float на дисплеи WINSTAR в CVAVR. Всё началось с того что мне нужно было вывести температуру с датчика ds18b20, как плюсовую, — так и минусовую, плюс ко всему с точностью в 0.1 градус. Так вот стандартным методом:

lcd_gotoxy(0,0);
sprintf(buff,"Т %u", temper); // вывод
lcd_puts(buff); // вывод на дисплей

этого сделать не получится , даже если применит «%f». Конешно можно пойти другим путём — с помощью деления и вывода отдельно целой части от дробной но мне захотелось использовать именно float. Оказывается для экономии места, в компиляторе по умолчанию отключена функция вывода float. Чтобы включить эту функцию нужно сделать пару простых действий: 1 – Зайти в настройки проекта.float_1 2 – Найти строчку с функцией sprintf и переключить её на значение float.float_2 После этих нехитрых манипуляций мы можем использовать строчку вида:

sprintf(buff," TEMP %.1f\xdfC ",t); // вывод

где 1 означает количество знаков после запятой, а эта комбинация «\xdfC « выводит значок градусов.lcd В этом простом решении есть лишь один недостаток – после включения этой функции мой код «пожирнел»  аж  на 20% . Ну и на последок рабочий проект термометра с применение данной функции. Но он скорей для изучения чем для сборки — так как в железе не собирался!ds18b20_atmega8 Пожалуйста учтите что рисунок выше НЕ СХЕМА  — а модель для Proteus! Для электрической схему потребуется стандартная обвязка МК и дисплея. Исходный код программы:

/*****************************************************
Chip type               : ATmega8
Program type            : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/
#include <mega8.h>
#asm
.equ w1_port=0x15 ;PORTB
.equ w1_bit=0
#endasm
#include <1wire.h>          //библиотека для работы с 1wire
#include <ds18b20.h>        //библиотека для работы с ds18b20
#include <delay.h>          //библиотека задержки
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x12 //PORTD
#endasm
#include <alcd.h>
#include <stdio.h>

#define DEL 250       //период обновления данных (в мс)

char buff [99];  //буфер дисплея
unsigned char ds=0;
unsigned int ds_t=0;
unsigned int i=0;
float t1=0,t=0;;
unsigned char devices;  //количество устройств на линии
unsigned char RomCode[5][9];  //массив ром-кодов датчиков

void lcd()
{

lcd_gotoxy(0,0);
if(ds==0)
{
sprintf(buff," TEMP %.1f\xdfC     ",t);  // вывод
}
if(ds==1)
{
sprintf(buff," IS NOT DS18B20!!! ",);  // вывод
}
if(ds==2)
{
sprintf(buff," SCAN DS18B20.......",);  // вывод
}
lcd_puts(buff);  //  вывод на дисплей
}

void temp()
{
if(ds==0){ devices=w1_search( DS18B20_SEARCH_ROM_CMD, RomCode );} //поиск датчиков на линии 1-wire если нет датчиков
if(devices==1)  //если датчик есть
{
ds=0;
delay_ms(10);
ds18b20_init( &RomCode[0][0], 30, 60, DS18B20_12BIT_RES );  //12 битный режим
delay_ms(10);
t1 = ds18b20_temperature( &RomCode[0][0] );   //считывам температуру
if( t1 > 1000 )   //если температура минусовая
{
t1 = 4096 -  t1;
t1 = - t1;
}
if(t1!=-9999){  t = t1; }  //отсекаем ошибки
}
else
{
ds_t++;
if(ds_t<2){ds=1;} //выводим сообщение об ошибке
if(ds_t>=2&&ds_t<=4)
{
ds=2; //выводим сообщение о сканировании шины
devices=w1_search( DS18B20_SEARCH_ROM_CMD, RomCode ); //поиск датчиков на линии 1-wire
}
if(ds_t>4)
{
ds_t=0;
}
}
}

void main(void)
{
// Port B initialization
PORTB=0x00;
DDRB=0x00;

// Port C initialization
PORTC=0x00;
DDRC=0x00;

// Port D initialization
PORTD=0x00;
DDRD=0xFF;

// 1 Wire Bus initialization
w1_init();

// Alphanumeric LCD initialization
lcd_init(16);

while (1)
{
i++;
lcd();
delay_ms(1);
if(i>=DEL){i=0; temp();}   //вызываем с определенной переодичностью

}
}

Скачать проект Atmega8+LCD+DS18B20 Скачали 935 раз

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

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