Телесистемы
 Разработка, производство и продажа радиоэлектронной аппаратуры
На главную   | Карта сайта | Пишите нам | В избранное
Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс.
e-mail:jobsmp@pochta.ru

Телесистемы | Электроника | Конференция «Микроконтроллеры и их применение»

вот немного :

Отправлено вуфер 19 апреля 2007 г. 12:31
В ответ на: Поделитесь кто может сишным примером работы с DS18S20, плз. отправлено Lexandro 19 апреля 2007 г. 11:35


/*########Dallas 1-wire*/
/*ads1w_dq_outp,ds1w_dq_inp,ads1w_dq_dirp,ds1w_dq_bit - 1-wire out,in,direction port addresses,*/
/*ds1w_dq_bit - 1-wire port bit mask*/
/*ds1w_err stores last 1-wire initialization error*/
/*Define following macro constants before including 1-wire routines :*/
/* ds1w_short_delay - short delay before setting DQ level in wait_short ticks*/
/* ds1w_wr_delay - delay of bit write*/
/* ds1w_rd_delay - belay before bit read*/
/* ds1w_reset_delay - DQ line reset delay in main timer ticks*/
/* ds1w_presence_delay - delay before presence pulse detect after long reset pulse*/
#define _inc_ds1w(ads1w_dq_dirp,ads1w_dq_outp,ads1w_dq_inp,ads1w_dq_bit) \
uint16_t ds1w_dq_outp=(uint16_t)ads1w_dq_outp, /*DQ out register address*/ \
ds1w_dq_inp=(uint16_t)ads1w_dq_inp, /*DQ input register address*/ \
ds1w_dq_dirp=(uint16_t)ads1w_dq_dirp; /*DQ direction register address*/ \
uint8_t ds1w_dq_bit=(1< uint8_t ds1w_err; /*last error */ \
volatile uint8_t ds1w_err_cnt; /*error counter*/ \
\
/*set DQ level to bit 0 of dq_level*/ \
void ds1w_wr_dq(uint8_t dq_level) \
{cli(); /*disable interrupts while accesing to port*/ \
if (dq_level&1) (*(volatile uint8_t*)ds1w_dq_dirp)&=~ds1w_dq_bit; /*if bit 0 = 1,release DQ*/ \
else (*(volatile uint8_t*)ds1w_dq_dirp)|=ds1w_dq_bit; /*if bit 0 = 0,short DQ*/ \
sei(); /*enable interrupts*/ \
} \
/*get DQ level*/ \
uint8_t ds1w_rd_dq(void) \
{return((*(volatile uint8_t*)ds1w_dq_inp)&ds1w_dq_bit); /*return DQ level*/ \
} \
/*write bit 0 of abyte*/ \
void ds1w_wr_bit(uint8_t abyte) \
{wait_tmr(1); /*synchronize to main timer*/ \
cli(); \
ds1w_wr_dq(0); /*set DQ to 0*/ \
wait_short(ds1w_short_delay); /*short bit delay*/ \
ds1w_wr_dq(abyte); /*set DQ level to bit 0 of abyte*/ \
wait_short(ds1w_wr_delay); /*bit write delay*/ \
ds1w_wr_dq(1); /*release DQ line*/ \
sei(); \
} \
/*write byte*/ \
void ds1w_wr_byte(uint8_t abyte) \
{uint8_t uc1; \
for (uc1=8;uc1;uc1--) /*8 bits loop*/ \
{ds1w_wr_bit(abyte); /*write lowest bit*/ \
abyte>>=1; /*shift to next bit*/ \
} \
} \
/*read bit to 7th bit of in_byte*/ \
uint8_t ds1w_rd_bit(uint8_t in_byte) \
{wait_tmr(1); /*synchronize to main timer*/ \
cli(); /*disable interrupts*/ \
ds1w_wr_dq(0); /*set DQ to 0 for short time*/ \
wait_short(ds1w_short_delay); /*short bit delay*/ \
ds1w_wr_dq(1); /*release DQ*/ \
wait_short(ds1w_rd_delay); /*delay before bit read*/ \
if (ds1w_rd_dq()) in_byte|=0x80; else in_byte&=0x7f; /*return input byte with bit 7 set to readed bit*/ \
sei(); /*enable interrupts*/ \
return(in_byte); /*return result*/ \
} \
/*read byte*/ \
uint8_t ds1w_rd_byte(void) \
{uint8_t uc1,uc2; \
uc2=0; /*result byte*/ \
for (uc1=8;uc1;uc1--) /*8 bits loop*/ \
{uc2>>=1; /*shift result right*/ \
uc2=ds1w_rd_bit(uc2); /*read next bit*/ \
} \
return(uc2); \
} \
/*reset 1-wire bus*/ \
/*returns 0 if ACK received,*/ \
/* 1 if no ACK received,DQ floating or shorted to VCC),*/ \
/* 2 if DQ shorted to ground*/ \
uint8_t ds1w_reset(void) \
{uint8_t uc1; \
uc1=0; /*result of operation*/ \
(*(volatile uint8_t*)ds1w_dq_outp)&=~ds1w_dq_bit; /*clear corresponding bit of out port*/ \
ds1w_wr_dq(1); /*release DQ*/ \
wait_short(ds1w_short_delay); /*line setting delay*/ \
wait_tmr(1); /*sync to main timer*/ \
if (!ds1w_rd_dq()) uc1=2; /*if DQ not released (shorted to GND),return error = 2*/ \
else /*else proceed with reset*/ \
{ds1w_wr_dq(0); /*clear DQ*/ \
wait_tmr(ds1w_reset_delay); /*long delay to reset*/ \
cli(); /*disable interrupts*/ \
ds1w_wr_dq(1); /*release DQ*/ \
wait_short(ds1w_presence_delay); /*short delay before presence pulse read*/ \
if (ds1w_rd_dq()) uc1=1; /*if no presence pulse (DQ floating or shorted to VCC),return error = 1*/ \
sei(); \
wait_tmr(1); /*delay after reset*/ \
} \
return(uc1); /*return result of operation*/ \
}
/*convert 2-byte temperature data of ds18b20 to celsius int16_t,one digit after dot*/
#define _inc_ds1w_ds18b20_to_celsius \
int16_t ds1w_ds18b20_to_celsius(uint16_t value) \
{uint8_t uc1; \
uc1=(value>>8)&0x80; \
if (uc1) value=0-value; \
value=(value>>1)+(value>>3); \
if (uc1) value=0-value; \
return(value); \
}
#define trm_not_inited 0x8000 /*thermometer not inited*/
#define trm_sens_VCC 0x8001 /*shorted to VCC or floating*/
#define trm_sens_GND 0x8002 /*shorted to GND*/
/*return 0 if no temperature errors,else return error code*/
/* (1-sensor line floating or shorted to VCC,*/
/* 2-sensor line shorted to GND)*/
#define _inc_trm_err \
uint8_t trm_err(uint16_t therm) \
{if ((therm&0xfff0)==0x8000) return(therm&0x000f); else return(0); \
}
/*return 1 if thermometer inited,0 if not*/
#define _inc_trm_inited \
uint8_t trm_inited(uint16_t therm) \
{if (therm==trm_not_inited) return(0); else return(1); \
}
/*return temperature if no errors,else error code*/
#define _inc_trm_errt \
uint16_t trm_errt(uint16_t trm,uint8_t err) \
{if (err) return(0x8000 | err); else return(trm);\
}

/*psychrometer method humidity calculation,temperatures in 0.1 degree format*/
#define _inc_hum_psych_calc \
/*humidity calculation table for -19.2..172.8 deg 6.4 deg step*/ \
int16_t hum_psych_calc_table[] PROGMEM= \
/*-19.2..172.8*/ \
{12,24,46,56,65,87,115,141,167,187,205,230,300,336,353,367,381,395,407,444,523,555,586,651,711,771,836,902,967,1032,1098}; \
uint16_t hum_psych_calc(int16_t trm_dry,int16_t trm_wet) \
{int16_t result=0; \
if ( (trm_err(trm_dry)) || (trm_err(trm_wet)) ) result=0; \
else \
{if (trm_dry<=trm_wet) result=1000; \
else if ((trm_dry<=1728)&&(trm_dry>=-192)) \
{uint8_t uc1; \
uc1=((trm_dry+192)/64); \
result=(trm_dry/64)*64; \
result=(((int32_t)(pgm_read_word_near(&hum_psych_calc_table[uc1+1])-pgm_read_word_near(&hum_psych_calc_table[uc1])) * \
(int32_t)(trm_dry-result))/((int32_t)64))+pgm_read_word_near(&hum_psych_calc_table[uc1]); \
if ((trm_dry-trm_wet)>=result) result=0; \
else result=1000-(((int32_t)(trm_dry-trm_wet)*(int32_t)1000)/((int32_t)result)); \
}else result=0; \
} \
return(result); \
}



Составить ответ | Вернуться на конференцию

Ответы


Отправка ответа
Имя*: 
Пароль: 
E-mail: 
Тема*:

Сообщение:

Ссылка на URL: 
URL изображения: 

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

Перейти к списку ответов | Конференция | Раздел "Электроника" | Главная страница | Карта сайта

Rambler's Top100 Рейтинг@Mail.ru
 
Web telesys.ru