Поговорим о том как вывести float на дисплеи WINSTAR в CVAVR. Всё началось с того что мне нужно было вывести температуру с датчика ds18b20, как плюсовую, — так и минусовую, плюс ко всему с точностью в 0.1 градус. Так вот стандартным методом:
lcd_gotoxy(0,0); sprintf(buff,"Т %u", temper); // вывод lcd_puts(buff); // вывод на дисплей
этого сделать не получится , даже если применит «%f». Конешно можно пойти другим путём — с помощью деления и вывода отдельно целой части от дробной но мне захотелось использовать именно float. Оказывается для экономии места, в компиляторе по умолчанию отключена функция вывода float. Чтобы включить эту функцию нужно сделать пару простых действий: 1 – Зайти в настройки проекта.
2 – Найти строчку с функцией sprintf и переключить её на значение float.
После этих нехитрых манипуляций мы можем использовать строчку вида:
sprintf(buff," TEMP %.1f\xdfC ",t); // вывод
где 1 означает количество знаков после запятой, а эта комбинация «\xdfC « выводит значок градусов.
В этом простом решении есть лишь один недостаток – после включения этой функции мой код «пожирнел» аж на 20% . Ну и на последок рабочий проект термометра с применение данной функции. Но он скорей для изучения чем для сборки — так как в железе не собирался!
Пожалуйста учтите что рисунок выше НЕ СХЕМА — а модель для 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 Скачали раз