Нарисовал я схему сам ручками.
Изменил ее под свои задачи: заменил PIC на Atmega8 добавил часы DS1307
сей час пишу програмку возник вопрос, как проще при такой схеме организовать опрос клавиатуры
мой еще не доработанный код
Код:
#include <avr>
#include <avr>
#include <util>
#include "ds1307.c"
#include "1w.h"
#include "ds18x20.h"
#include "1w.c"
#include "7seg.h"
//#include "key.h"
#define F_CPU 8000000 // 8MHz
uint8_t buf[9]; // массив для приема данных из датчика
int t;
int des;
char znak;
volatile int g_cur_val = 0;
static int n = 0;
void initialize_timer0()
{
TCCR0 |= (1 << CS01); // configure the prescaler for timer0
//TCCR1B = (1<<CS12) | (1<<CS10);
TCCR2 |= (1 << CS21);
//TIMSK |= (1 << TOIE0); // enable timer0 interrupt
TIMSK = (1<<TOIE1) | (1<<TOIE0);
TCNT0 = 0; // initialize timer0 counter to 0
TCNT2 = 0x01;
}
/** Получение температуры от датчика DS18S20.
* Функция опрашивает датчик и возвращает ненулевое значение, если считывание успешно.
* Температура возвращается в сотых долях градуса, т.е. значение в 100 раз больше, чем
* температура в градусах цельсия.
* @param temp - указатель на измеренную температуру
* @return - результат опроса датчика (0 - была ошибка)
*/
static uint8_t temp_x100(int *temp) {
uint8_t result = 1, // результат опроса датчика
crc; // контрольная сумма
int16_t *tmp = (void*)buf; // указатель на температуру, принятую из датчика
int t, tt; // вспомогательные переменные
result = 1;
ow_reset(); // сброс 1-wire
ow_write_byte(OW_SKIP_ROM_CMD); // команда "пропустить адрес"
// _delay_ms(1000);
ow_write_byte(CMD_RD_SCRPAD); // команда "считать регистры датчика"
crc = 0;
// чтение данных из датчика
for(uint8_t i=0;i<9>>2); // отбрасываем мл.бит температуры из датчика
// t = tt - 25 + (16 - buf[6])*100/16;
//t = tt - 0.25 + ((buf[7]-buf[6])/buf[7]); // это "стандартный" алгоритм извлечения долей градуса
// t = (buf[0] | (buf[1] <<8>>4) & 0x0F) | (( buf[1]<<4) & 0xF0);
//t = 100 * (*tmp)/16;
t = (buf[0] | (buf[1] << 8));
//znak=(buf[1]); //если 0х00 то + если 0xFF то -
//t = tt - 0.25 + ((buf[7]-buf[6])/buf[7]);
//t=buf[1];
//tt=buf[1];
//t = 100 * (*tmp) / 16;
} else {
// датчик типа DS18B20
// t = 100 * (*tmp) / 16;
}
}
*temp = t; // заносим готовый результат в переменную-приемник
// каков бы ни был результат опроса датчика, делаем повторный запуск измерения
ow_reset(); // сброс 1-wire
ow_write_byte(OW_SKIP_ROM_CMD); // команда "пропустить адрес"
ow_write_byte(CMD_START_CONV); // команда "начать измерение"
ow_reset(); // сброс 1-wire
// возвращаем результат опроса датчика
return result;
}
void dig_temp()
{
switch(n){
case 0:{PORTC = 0x00;
PORTD=znak;
PORTC = 0x08;break;}
case 1:{PORTC = 0x00;
PORTD=0xFF;
if (g_cur_val/10 % 10 <=0)
PORTD=0xFF;
else
seg7_write_digit(g_cur_val/10 % 10);
PORTC = 0x04;break;}
case 2:{PORTC = 0x00;
PORTD=0xFF;
seg7_write_digit(g_cur_val % 10);
PORTC = 0x02;break;}
case 3:{PORTC = 0x00;
PORTD=0xFF;
seg7_write_digit(des);
PORTC = 0x01;break;}
case 4:{ PORTC = 0x00;
PORTD=_comma;
PORTC = 0x02; break;}
}
n++;
if (n==5)
n=0;
}
void dig_time()
{
switch(n){
case 0:{PORTC = 0x00;
seg7_write_digit(hour/10);
PORTC = 0x08;break;}
case 1:{PORTC = 0x00;
seg7_write_digit(hour);
PORTC = 0x04;break;}
case 2:{PORTC = 0x00;
seg7_write_digit(min/10);
PORTC = 0x02;break;}
case 3:{PORTC = 0x00;
seg7_write_digit(min);
PORTC = 0x01;break;}
case 4:{ PORTC = 0x00;
PORTD=_comma;
PORTC = 0x04; break;}
}
n++;
if (n==5)
n=0;
}
ISR(TIMER0_OVF_vect)
{
dig_time();
////_delay_ms(10000);
//dig_temp();
}
ISR(TIMER2_OVF_vect)
{
//dig_time();
////_delay_ms(10000);
dig_temp();
}
int main(void) {
int cnt; // температура в сотых долях градуса
//TCCR0 = _BV(CS01);
//TIMSK = _BV(TOIE0);
// wdt_enable(WDTO_120MS); // включаем WDT
//rtc_set_time(21,42,0,1);
// инициализация периферии
DDRB = ~_BV(0);
DDRD = 0xFF;
DDRC = 0x0F;
PORTD = 0x00;
PORTC = 0; // disable control signals by default
initialize_timer0();
rtc_init(0,1,0);
rtc_set_time(20,42,55,1);
// при сбросе 1-wire происходит и настройка порта
ow_reset();
// первое обращение к датчику вернет ложное значение, но запустит цикл измерения
temp_x100(&t);
sei();
while(1){
rtc_get_date_time();
_delay_ms(20); // задержка в 20 мс
if(!--cnt){ // ведем подсчет 20-мс интервалов
cnt = 40; // если набралось в сумме 800 мс,
if(!temp_x100(&t)){ // то можно читать температуру
continue; // и сразу на начало главного цикла
}
// если ошибки не было и включен 0-й режим - выводим температуру
//if (buf[1]==0xFF)
if (t<0x00)
{
t -= 2;
t ^= 0xFFFF;
g_cur_val=(t/16);
//des=(t & 0x0F)*0.625;
znak=_minus;
}
else
{g_cur_val=t/16;
znak=0xFF;
}
des=(t & 0x0F)*0.625;
// lcd_st(g_cur_val);
}
}
}