Возникла идея создать на данных элементах термометр в баньку. Весь вкус состоял в том что бы испоьзуя attiny45 с его недостатком ног считать с 18b20 температуру и вывести на 7сегментный индикатор используя только одну ИМС сдвигового регистра. Т.к. елементы были в SOP и SOIC корпусах то конечное устройство должно было получиться миниатюрным и влезть в корпус сгоревшей гал.лампочки под 12В , микросхема датчика температуры размещается на плате или выносным монтажем. Плата изготавливалась с помощью фоторезиста, ЛУТ не проходит т.к. очень мелкая детализация - сд.регистр паялся под лупой.
Программу как-то "написал" на AVR C, используя чужие библиотеки 1wire и примеры находящиеся в свободном доступе(не помню чьи) , просьба не ругать а поправить, ну не получается у меня пока разложить 8битовое значение в Atmel Studio - поэтому побитно делал, знаю что некрасиво...
Проект "запустил" в Протеусе. Перенес в жизнь и вот не работает. Подозреваю что 18в20 не отслеживает температуру (если без датчика индикатор выводит 00 что и нужно, при подключение датчика - 88??) Видно временные интервалы расчитал неправильно. Ну что коты поможете?
http://www.pif-paf.com.ua/img/term.jpg
Код: Выделить всё
#include <avr/io.h>
#include <avr/iotn45.h> // библиотека для используемого МК
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#define F_CPU 8000000UL
#define DATA 2 // Подключаем к порту PB2 ножку данных сдвигового регистра
#define CLK 0 // Подключаем к порту PB0 ножку тактовых импульсов сдвигового регистра
#define RES 1 // Подключаем к порту PB1 ножку защёлки сдвигового регистра
#define TRIG 3 // Подключаем к порту PB3 >100/минус
unsigned char led_buff[13];
unsigned char reg_buff[3];
unsigned char buf_temp[4] = {0,0,0,11};
//общий анод
const char pinot[7] = {1,1,1,1,1,1,1}; // Точкa 0x7F
const char one[7] = {1,1,1,1,0,0,1}; // Один 0x4F
const char two[7] = {0,1,0,0,1,0,0}; // Два 0x12
const char three[7] = {0,1,1,0,0,0,0}; // Три 0x30
const char four[7] = {0,0,1,1,0,0,1}; // Четыре 0x19
const char five[7] = {0,0,1,0,0,1,0}; // Пять 0x12
const char six[7] = {0,0,0,0,0,1,0}; // Шесть 0x2
const char seven[7] = {1,1,1,1,0,0,0}; // Семь 0x78
const char eight[7] = {0,0,0,0,0,0,0}; // Восемь 0x0
const char nine[7] = {0,0,1,0,0,0,0}; // Девять 0x04
const char zero[7] = {1,0,0,0,0,0,0}; // Ноль 0x01
const char minus[7] = {0,1,1,1,1,1,1}; // Минус 0x3F
const char blanc[7] = {1,1,1,1,1,1,1}; // Пусто 0x7F
const char reg0[3] = {0,0,0};
const char reg1[3] = {0,1,1}; //Вывод знакомест
const char reg2[3] = {1,0,1};
const char reg3[3] = {1,1,0};
int temp;
void takt() {
PORTB |= _BV(CLK); //установить 1 на PB0
_delay_us(150);
PORTB &= ~_BV(CLK); //установить 0 на РВ0
_delay_us(150);
}
void vpihreg(char digit[3]) {
unsigned char i;
for (i=0;i<2;i++) {
PORTB = (digit[i]<<DATA); // вывод на нужный регистр
takt();
}
}
void vpih(char digit[7]) {
unsigned char i=0;
for (i=0;i<7;i++) {
PORTB = (digit[i]<<DATA); // побитный вывод значения на вывод PB2
takt(); //запуск стробирующего импульса
}
if (temp>99) {
//if (buf_temp[0]<12) {
//PORTB |= _BV(TRIG); //установить 1 PB3
PORTB = (1<<TRIG);
}
else {
//PORTB &= ~_BV(TRIG);//установить 0 PB3
PORTB = (0<<TRIG);
}
PORTB |= _BV(RES); //сигнал защелки на PB1
_delay_us(200);
PORTB &= ~_BV(RES);//снять сигнал защелки на PB1
}
void reg_temp(signed char temp) {
buf_temp[0]=12; //пустое место
if (temp<0) {
temp=-temp;
buf_temp[0]=11; //знак минуса
}
if (temp>100) {
buf_temp[0]=temp/100;
temp=temp-100;
buf_temp[1]=temp/10;
buf_temp[2]=temp%10;
}
else
{
buf_temp[1]=temp/10;
buf_temp[2]=temp%10;
}
_delay_ms(100);
return buf_temp;
_delay_ms(10);
}
ISR (TIMER1_OVF_vect) {
unsigned char i, z;
for (z=0; z<40; z++) {//поставим задержку на 10сек, а после идет обработка сл.прерывания на измерение - измерение темп.каждые 10сек
for (i=0;i<3;i++) {
vpihreg (reg_buff[i]);
vpih (led_buff[buf_temp[i]]);
_delay_ms(10);
}
}
}
ISR (TIMER0_OVF_vect) {
temp = temp_18b20();
if(temp > 1000)//если температура <0
{
temp = 4096 - temp;
temp = -temp;
}
reg_temp(temp);
}
int main(void) {
led_buff[0]=zero;
led_buff[1]=one;
led_buff[2]=two;
led_buff[3]=three;
led_buff[4]=four;
led_buff[5]=five;
led_buff[6]=six;
led_buff[7]=seven;
led_buff[8]=eight;
led_buff[9]=nine;
led_buff[10]=pinot;
led_buff[11]=minus;
led_buff[12]=blanc; //0x00;
reg_buff[0]=reg0;
reg_buff[1]=reg1;
reg_buff[2]=reg2;
reg_buff[3]=reg0;
char buffer[16] = "";
DDRB = 0b00001111; //настроить РВ0-4 на вывод PB5- вход
PORTB = 0b00000000;
temp = temp_18b20();
if(temp > 1000)//если температура <0
{
temp = 4096 - temp;
temp = -temp;
}
reg_temp(temp);//разложение температуры по знакоместам 123 = 1,2,3 - выводит в buf_temp[3]
TCCR1 = (1<<CS10);//коэф деления 8 смотри даташит стр.89
TCCR0B = (1<<CS01)|(1<<CS00);// коэф деления Таймера 0В 64 см.стр.79
TCNT1=0xf3; // 243 коррекция счетчика на 1 сек (243+1)/1000000Гц*4096(коэф деления)= 1сек
TCNT0 = 0xf3;
TIMSK=(1<<TOIE1)|(1<<TOIE0);// включить таймер на внутренние прерывание
sei(); //разрешение прерываний
while(1){ }
}
- Вложения
-
- и.JPG
- (95.95 КБ) 1587 скачиваний
-
- 7seg_AStudio.zip
- Дополнительно проект в atmelStudio
- (44.03 КБ) 176 скачиваний
-
- term.zip
- Во вложении проект и разводка в Протеусе , библиотеки 1wire исходники на Си , *.hex, *.elf
- (219.63 КБ) 175 скачиваний



