АвторСообщение



Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 14.02.12 12:48. Заголовок: светодиод в качестве датчика освещенности + pic16f676


Кто нибудь пробовал использовать светодиод в качестве датчика освещенности ?
Что то никак не разберусь с кодом - не хочет работать

светодиод анодом к PORTA,5 , катодом к PORTA,4

void main()
{
init_MCU();

while(1)
{
temp = 0; /*обнуляем*/
bitclr(PORTA,5); /*пин в ноль*/
bitclr(TRISA,4); /*на выход*/
bitset(PORTA,4); /*пин в 1 - заряжаем*/
Delay_us(100); /*сколько заряжать?*/
bitclr(PORTA,4); /*конец зарядки*/
bitset(TRISA,4); /*пин на вход*/

while(RA4_bit){temp++;} /*считаем пока пин не равен 0*/
fl_photo_count++; /*счетчик измерений*/
EEPROM_Write((0x00 + fl_photo_count),temp); /*записываем данные для дальнейшего анализа*/
Delay_us(6000000);
}
}

Спасибо: 0 
Цитата Ответить
Ответов - 45 , стр: 1 2 All [только новые]





Пост N: 2
Зарегистрирован: 21.02.12
Откуда: Луганская обл.
Рейтинг: 0
ссылка на сообщение  Отправлено: 22.02.12 00:11. Заголовок: SanSanich пишет: А..


SanSanich пишет:

 цитата:
А можете проект выложить?


Это с применением белого светодиода на PORTA.4 и PORTA.5 . Много недоработок, но работает в железе пока на 2 датчика.

/*Программа для PIC16F676 + 3 LM335Z. Микроконтроллер после инициализации
производит 64 замера температуры на сенсоре_0 температуры и вычисляется среднее
значение.
Это значение преобразуется в двоично-десятичный код, далее в код
семисегментного индикатора и выводится на индикатор, в это время идет замер на
сенсоре_1. Во время замера на сенсоре_2 идет вывод результата с сенсора_1.И так
по кругу.

По прерыванию от ТMR0 изменяется разряд индикатора.
Раз в 4,5 минуты измеряется освещенность, результат сравнивается с установкой,
записанной в EEPROM и устанавливается соотв. уровень яркости индикатора(значение
TMR1).

По прерыванию от TMR1 тушим все разряды-управляем яркостью.

По прерыванию PORTA.3 записываем текущую освещенность в eeprom как пороговую.
О записи сигнализирует светодиод 2 сек.
*/
#define INV_B(x) ^=(1<<x) /*макрос инвертирования бита*/
#define SET_B(x) |= (1<<x) /*установить бит*/
#define CLR_B(x) &=~(1<<x) /*Очистить бит*/

#define SCR_SZ 3 /*Колличество индикаторов*/
#define DP 4 /*Номер бита точки индикатора (3)*/
#define ADC_AN0 0b10001000 /*аналоговый для ADC AN2(Volt)*/
#define ADC_AN1 0b10000100 /*аналоговый для ADC AN1(Amp)*/
#define COMP_RESET 0X07 /*компаратор выключен*/
#define ind 3 /*колличество знакомест индикатора*/
#define MASK_ADCON1 0b00010000 /*Частота преобразования FOSC/8(4 MHz->2mkc)*/
#define MASK_INTCON 0b11101000 /*прерывания GIE_PEIE_T0IE_RAIE*/
#define MASK_OPTION 0b11000011 /*делитель 1:16 для TMR0(4.096 mcek) */
#define Vref 5 /*опорное напряжение АЦП*/
#define sensor_alarm 5 /*номер датчика для сигнализации*/
#define Const_alarm (4) /*минимальная тепмература для тревоги*/
#define Const_ADC (Vref*10000/1024) /*const для вычисления АЦП*10000*/
#define alarm (Const_alarm+273)*1024/Vref/100 /*Данные АЦП для тревоги*/
#define DATA 2
#define CLK 0
#define SET 1
#define REG_PORT PORTC
#define bitset(port,pin) port |=(0x01<<pin) /*???????????????????*/
#define bitclr(port,pin) port &=~(0x01<<pin)


unsigned char temper[ind]; /*Массив результата температуры в двоично-десятичном коде*/
unsigned char *ptr_temper; /*указатель на массив temper*/
unsigned char temper_seg[ind]; /*Массив результата в коде 7_seg*/
unsigned char *ptr_temper_seg; /*указатель на массив temper_seg*/
unsigned int _TMR1 absolute 0x000E; /*переменная TMR1 для регулировки яркости*/
unsigned int const_TMR1; /*значение для яркости дня и ночи*/
unsigned int temp; /*сумма измерений ADC*/
unsigned int temp1; /*Значение среднего АDC*/
unsigned int counterH; /*счетчики прерываний 65536*/
unsigned char tmp_counterH; /*освещенность*/
unsigned char const_tmp_counterH; /*Уставка освещенности*/
unsigned int photo_tmr; /*Таймер освещенности*/
unsigned char t_C; /*температура в градусах Цельсия*/
unsigned char fl_photo; /*флаг измерения освещенности*/
unsigned char fl_photo_count; /*счетчик измерений освещенности*/
struct {
unsigned char sensor : 3; /*флаг номера датчика температуры*/
unsigned char poz : 2; /* номер индикатора дисплея*/
unsigned char znak : 1; /*Флаг минуса температуры*/
unsigned char adr : 1; /*разрешение записи адресса еепром*/
unsigned char oldstate : 1; /* Флаг кнопки записи установкии*/
} flags;

/*Инициализация микроконтроллера*/
void init_MCU()
{
unsigned char i;
CMCON = COMP_RESET; /*Выключить компараторы*/
PORTA = 0b00010000; /*Выставить уровни на портах*/
PORTC = 0B00000000;
TRISA = 0B00001111; /*AN0 , AN1 и PORTA,2 работа на вход*/
TRISC = 0B00000000; /*Работа на выход*/
//bitset(PORTA,4);
TMR1IE_bit =1;
ADCON0 = ADC_AN0; /* выбор аналогово канала*/
ADCON1 = MASK_ADCON1; /*Частота преобразования FOSC/8(4 MHz->2mkc)*/
OPTION_REG = MASK_OPTION; /*делитель 1:32 для TMR0(8.192 mcek) */
IOCA = 0B00001000; /*Прерывание по PORTA.3*/
ptr_temper = &temper;
ptr_temper_seg = &temper_seg;
const_tmp_counterH = EEPROM_Read(0x00);
for(i = 0;i<3;i++){*(ptr_temper_seg+i) = 0XF7;}
const_TMR1=61500; /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
flags.sensor = 2;
flags.adr = 0;
Delay_us(3000000);
bitclr(PORTA,4);
INTCON = MASK_INTCON; /*Параметры прерываний*/
}
/*Чтение результата ADC*/
unsigned int read_ADC(char sensor)
{
unsigned int date;
date = ADC_Read(sensor);
return date;
}

/*Преобразование в двоично-десятичный код*/
void preobrazov(unsigned int date)
{//unsigned int tempf;
date *=49; /* (Vref/1024*10000) */
if(date>=27315) /*Положительная температура*/
{
date = date-27315;
flags.znak = 0; /*нет знака минуса температуры*/
}
else /*Отрицательная температура*/
{date = (~(date-27315))+1;
t_C = date/100; /*температура в градусах С*/
flags.znak = 1; /*установить флаг минуса*/
}
date/=100;
*(ptr_temper+1) = date/10;
*(ptr_temper+0) = date%10;
}

/*Преобразование двоично-десятичного в код семисегментного индикатора*/
unsigned char _seg7(unsigned char d){
unsigned char s;
switch(d) {
case 0 : {s = 0X18;}break;
case 1 : {s = 0xFA;}break;
case 2 : {s = 0X16;}break;
case 3 : {s = 0X52;}break;
case 4 : {s = 0xF0;}break;
case 5 : {s = 0X51;}break;
case 6 : {s = 0X11;}break;
case 7 : {s = 0X7A;}break;
case 8 : {s = 0X10;}break;
case 9 : {s = 0X50;}break;
case 10 : {s = 0XF7;}break; /*Знак минуса*/
case 11 : {s = 0X8F;}break;
}
return s;
}

/*Получение результата ADC в коде семисегментного индикатора*/
void resuit()
{
/*Преобразуем в код семисегм.инд.*/
unsigned char i;
for(i = 0;i<2;i++){*(ptr_temper_seg+i) = _seg7(temper);}
*(ptr_temper_seg+2)=0xFF;
/*При отрицат.темпер. ставим знак минуса*/
if(flags.znak)
{
if(t_C>10) {*(ptr_temper_seg+2)=0XF7;}
else {*(ptr_temper_seg+1)=0XF7;
*(ptr_temper_seg+2)=0XFF;
}
}
/*не зажигаем левый ноль*/
if(*(ptr_temper_seg+1)==0X18)
{*(ptr_temper_seg+1)=0xFF;}


}


static void shift(unsigned char d){
unsigned char i;
for (i=0; i < 8; i++){
/*устанавливаем нужный уровень DATA*/
if(d & 128){REG_PORT |=(0x01<<DATA);} /*устанавливаем RC1 = 1*/
else {REG_PORT &=~(0x01<<DATA);} /*устанавливаем RC1 = 0*/
REG_PORT |=(0x01<<CLK); /*даем импульс CLK = 1*/
REG_PORT &=~(0x01<<CLK);
d <<= 1; /*сдвигаем данные*/
}
REG_PORT |=(0x01<<SET); /*защелкиваем*/
REG_PORT &=~(0x01<<SET);
}

void main()
{
init_MCU();

while(1)
{
unsigned char i;
/*смена датчиков температуры*/
switch(flags.sensor) {
case 0 : {flags.sensor = 0X01;}break;
case 1 : {flags.sensor = 0X00;}break;
case 2 : {flags.sensor = 0X00;}break;
default : {flags.sensor = 0X01;}
}

temp = 0; /*вычисляем среднее суммы из 64 измерений АЦП*/
for(i=0;i<64;i++)
{
temp += read_ADC(flags.sensor); /*Измерение АЦП*/
delay_ms(64);
}
temp1 = temp>>6; /*temp/64;*/

/*включение сигнализации*/
if(flags.sensor==sensor_alarm && temp1<alarm && !fl_photo) /*выбор датчика для сигнализации*/
{bitset(PORTA,4);} /*Сигнализация On*/
else {bitclr(PORTA,4);} /*Сигнализация Off*/
preobrazov(temp1) ; /*Вычисление и преобразование в двоично-десятичный код*/
resuit(); /*Преобразование в код семисегментного индикатора*/

/*Настроечные данные-удалить*/
if(flags.adr && !fl_photo)
{
flags.adr = 0;
bitset(PORTA,4); /*сигнал о записи в eeprom*/
EEPROM_Write(0x00,const_tmp_counterH);
Delay_us(2000000);
bitclr(PORTA,4); /*eeprom запись закончена*/
}
}
}
/*______________________________________________________________________________*/

void interrupt(void)
{

/* *******************Прерывание по TMR0********************* */
if(T0IF_bit) /*прошло 4096 мкс*/
{
T0IF_bit = 0;
counterH++;
if(fl_photo && !RA5_bit) /*если идет изм.освещ. и RA5_bit==0*/
{
tmp_counterH = counterH>>8; /******запись значения для настройки******/

bitclr(TRISA,5); /*портА,5 на выход*/
if(tmp_counterH<=const_tmp_counterH){const_TMR1=61500;} /*смотрим освещенность,выставляем яркость*/
else {if(tmp_counterH > (const_tmp_counterH+0x05)){const_TMR1=65000;}}
fl_photo = 0; /*cбрасываем флаг измерения освещенности*/
}
if(!counterH) /*Прошло 4096*65535== 268.431360 сек 4.5 мин*/
{
if(flags.sensor!=sensor_alarm && !flags.adr)/*если номер датчика не аварийный-меряем освещенность*/
{
bitset(PORTA,5); /*заряжаем светодиод*/
fl_photo = 1; /*включаем флаг измерения освещенности*/
bitset(TRISA,5); /*переключаем порт на вход*/
bitclr(PORTA,5);
}
}
/*Управление индикацией температуры*/
REG_PORT = REG_PORT&0b11000111; /*Тушим все разряды перед выводом в порт*/
shift(temper_seg[flags.poz]); /*выводим данныев вольт в буфер 74HC595*/

switch(flags.poz) { /* включаем нужный разряд-катод*/
case 2 : {REG_PORT =((REG_PORT&0b11000111) |0b00001000);}break;
case 1 : {REG_PORT =((REG_PORT&0b11000111) |0b00010000);}break;
case 0 : {REG_PORT =((REG_PORT&0b11000111)|0b00100000);}break;
}
_TMR1 = const_TMR1; /*Вводим значение яркости*/
TMR1ON_bit = 1; /*включаем таймер яркости индикатора*/
if(++flags.poz == SCR_SZ) flags.poz = 0;
}

/**************************прерывание по TMR1************************/
if(T1IE_bit && T1IF_bit)
{
T1IF_bit = 0;
TMR1ON_bit = 0;
REG_PORT = REG_PORT&0b11000111; /*Тушим все разряды */
}

/**************************Прерывание по PORTA*************************/
if(RAIE_bit && RAIF_bit)
{
RAIF_bit = 0;
while (Button(&PORTA, 3, 5, 0)) {flags.oldstate = 1;} /*нажата - ждем отжатия*/
if (flags.oldstate && Button(&PORTA, 3, 5, 1)) /*если отжата, то ...*/
{
flags.oldstate = 0;
const_tmp_counterH = tmp_counterH ;
flags.adr = 1; /*разрешение записи еепром*/
}

}


}





Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 3
Зарегистрирован: 21.02.12
Откуда: Луганская обл.
Рейтинг: 0
ссылка на сообщение  Отправлено: 22.02.12 17:48. Заголовок: Вот примерная схема ..


Вот примерная схема этого чуда-термометра
http://shot.qip.ru/005nDs-102N0Ky/

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 4
Зарегистрирован: 21.02.12
Откуда: Луганская обл.
Рейтинг: 0
ссылка на сообщение  Отправлено: 22.02.12 17:54. Заголовок: А это печатка http..


А это печатка
http://shot.qip.ru/005nDs-202N0KX/

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 53
Зарегистрирован: 23.01.11
Откуда: Россия, Респ. Саха Якутия г.Мирный
Рейтинг: 1
ссылка на сообщение  Отправлено: 23.02.12 16:49. Заголовок: anywhere сама идея ..


anywhere сама идея то хорошая, но вот в обычном наблюдении толку мало, тем более что вы же не всегда будете рядом с термометром, а может быть так что он будет вам сигналить о выходе температуры за рамки, а вы не услышите, для этого считаю термодатчик подвала доснабдить термостатом, с выводом состояния нагревателя в семисегменты, для полного счастья.

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 5
Зарегистрирован: 21.02.12
Откуда: Украина, Луганская обл.
Рейтинг: 0
ссылка на сообщение  Отправлено: 23.02.12 19:13. Заголовок: Александр пишет: те..


Александр пишет:

 цитата:
тем более что вы же не всегда будете рядом с термометром, а может быть так что он будет вам сигналить о выходе температуры за рамки, а вы не услышите


Если Вам интересно, то могу найти схему сигнализации на мобильный телефон. Сложного ничего нет - ставим свой номер на быстрый вызов, и подпаиваемся проводами к этой кнопке. При сигнализации контроллер замыкает провода и Вам идет звонок на мобильный. Но это уже из другой темы.Мне был интересен именно вопрос датчика освещенности из светодиода. Для вывода сигнализации с контроллера в моем PIC16F676 уже не осталось ног. Разве что использовать вывод Q7' на 74CH575 и выводить сигнал вместе с значением семисегментного индикатора. Но и память контроллера кончилась , а в Асме я не силен, чтобы сделать меньше код.

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 45 , стр: 1 2 All [только новые]
Ответ:
1 2 3 4 5 6 7 8 9
видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 8
Права: смайлы да, картинки да, шрифты нет, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет



Создай свой форум на сервисе Borda.ru
Текстовая версия