Код: Выделить всё
Исходный код программы термометра:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <math.h>
#include "n3310.h"
#include "n3310.c"
int a,l, sx=6, sy=6; //Шаг второй сетки
int t=70; //Граница прорисовки графика
//определяем порт и бит к которому подключено устройство 1-wire
#define W1_PORT PORTD
#define W1_DDR DDRD
#define W1_PIN PIND
#define W1_BIT 2
unsigned int temperature=0;
unsigned char temperature_sign=0;
void time(void);
void pixel (void);
void setka_y (void); //Отрисовка оси X
void setka_x (void); //Отрисовка оси Y
void znacheniya (void); //Вывод значений по осям X и Y
void no_sensor (void);
//функция определяет есть ли устройство на шине
unsigned char w1_find()
{ unsigned char device;
W1_DDR |= 1<<W1_BIT;
_delay_us(485);
W1_DDR &= ~(1<<W1_BIT);
_delay_us(65);
if((W1_PIN & (1<<W1_BIT)) ==0x00)
{ device = 1; }
else
device = 0;
_delay_us(420);
return device;
}
//функция посылает команду на устройство 1-wire
void w1_sendcmd(unsigned char cmd)
{
unsigned char e = 0;
for(e=0; e<8; e++)
{
if((cmd & (1<<e)) == 1<<e)
{
W1_DDR |= 1<<W1_BIT;
_delay_us(2);
W1_DDR &= ~(1<<W1_BIT);
_delay_us(65);
}
else
{ W1_DDR |= 1<<W1_BIT;
_delay_us(65);
W1_DDR &= ~(1<<W1_BIT);
_delay_us(5);
}
}
}
//функция читает один байт с устройства 1-wire
unsigned char w1_receive_byte()
{ unsigned char data;
unsigned char i = 0;
for(i=0; i<8; i++)
{ W1_DDR |= 1<<W1_BIT;
_delay_us(2);
W1_DDR &= ~(1<<W1_BIT) ;
_delay_us(7);
if((W1_PIN & (1<<W1_BIT)) == 0x00)
data &= ~(1<<i);
else
data |= 1<<i;
_delay_us(50);
}
return data;
}
//функция преобразует полученные с датчика 18b20 данные в температуру
int temp_18b20()
{ unsigned char data[2];
int temp = 0;
if(w1_find()==1)//если есть устройство на шине
{
w1_sendcmd(0xcc);//пропустить ROM код, мы знаем, что у нас одно устройство или передаем всем
w1_sendcmd(0x44);//преобразовать температуру
_delay_ms(750);//преобразование в 12 битном режиме занимает 750ms
w1_find();//снова посылаем Presence и Reset
w1_sendcmd(0xcc);
w1_sendcmd(0xbe);//передать байты ведущему(у 18b20 в первых двух содержится температура)
data[0] = w1_receive_byte();//читаем два байта с температурой
data[1] = w1_receive_byte();
//загоняем в двух байтную переменную
temp = data[1];
temp = temp<<8;
temp |= data[0];
//переводим в градусы
temp *= 0.0625;//0.0625 градуса на единицу данных
}
else {no_sensor();}
//возвращаем температуру
return temp;
}
void setka_x (void)
{ int b,p=0;
for (b=0;b<38;b++)
{a=a+2; p=p+sx;
LcdPixel(0,47,PIXEL_ON); //Пиксель в координатах 0,0
LcdPixel(a,47,PIXEL_ON); //Точка через 1 пиксель
LcdPixel(p,46,PIXEL_ON); //Точка через шаг пикселей
} LcdUpdate();}
void setka_y (void)
{ int w,u=0;
for (w=0;w<24;w++)
{l=l+2; u=u+sy;
LcdPixel(0,l,PIXEL_ON); //Точка через 1 пиксель
LcdPixel(1,u,PIXEL_ON); //Точка через шаг пикселей
} LcdUpdate();}
void znacheniya (void)
{ LcdGotoXYFont(1,1); //Установка координат величины по X
LcdFStr(FONT_1X,(unsigned char*)PSTR("T")); //Вывод величины по X
LcdUpdate();
LcdGotoXYFont(12,5); //Установка координат величины по Y
LcdFStr(FONT_1X,(unsigned char*)PSTR("t")); //Вывод величины по Y
LcdUpdate(); }
void no_sensor (void)
{
LcdGotoXYFont(2,2); //Установка координат величины по X
LcdFStr(FONT_1X,(unsigned char*)PSTR("No sensor")); //Вывод величины по X
LcdUpdate();
_delay_ms(500); //Пауза
LcdGotoXYFont(2,2); //Установка координат величины по X
LcdFStr(FONT_1X,(unsigned char*)PSTR(" ")); //Вывод величины по X
LcdUpdate();
}
int main(void)
{
LcdInit(); //Инициализация ЖКИ
LcdClear(); //Очистка ЖКИ
LcdFStr(FONT_1X,(unsigned char*)PSTR("START...")); //Вывод приветствия
LcdUpdate(); //Обновление экрана
_delay_ms(1000); //Пауза
LcdClear(); //Очистка экрана
//setka_x (); //Запуск отрисовки оси X
setka_y (); //Запуск отрисовки оси Y
//znacheniya (); //Вывод значений осей
char buffer[16] = ""; //Переменная температуры char
int temp;
int shag=0; //Переменная шага графика
int tempint; //Значение температуры в int
//int test=20;
sei(); //Разрешение прерываний
while(1)
{
temp = temp_18b20(); //Пишем в переменную значение температуры
if(temp > 1000) //если температура <0
{temp = 4096 - temp; temp = -temp;} //маркировка отрицательной температуры
// sprintf(buffer, "%i.%i", temp, temp%1); //Конвертирование int в char
sprintf(buffer, "%i", temp, temp%1); //Конвертирование int в char
LcdGotoXYFont(5,1); //Установка в координаты 1,1
LcdStr(FONT_1X,(unsigned char*)buffer); LcdUpdate();
tempint = atoi(buffer); //Конвертация char в int
// LcdLine ( shag, 46, shag, 0-tempint, PIXEL_ON); LcdUpdate(); //Вывод прямой на экран
// LcdLine ( shag, 20, shag, test, PIXEL_ON); LcdUpdate(); //Вывод прямой на экран
// LcdPixel (shag, tempint+10, PIXEL_ON); LcdUpdate(); //На экране!!!
// LcdPixel (shag, 60-tempint, PIXEL_ON); LcdUpdate(); //при 5,1 буффер
LcdPixel (shag, 60-tempint, PIXEL_ON); LcdUpdate(); //при 5,1 буффер
shag=shag+1; //Добавляем к переменной Шага 1-цу
LcdLine ( shag, 20, shag, 47, PIXEL_OFF); LcdUpdate(); //Вывод прямой на экран
if(shag==t) //Если достигли границы прорисовки графика
{shag=0;} //Идем в самое начало
}
}