Вт июн 14, 2022 00:13:15
Вт июн 14, 2022 00:15:44
Вт июн 14, 2022 00:17:08
... недостатки DS18B20 не менее значимы.
Вт июн 14, 2022 00:19:48
Вт июн 14, 2022 00:20:26
... Очень медленная реакция.
Вт июн 14, 2022 00:23:12
Вт июн 14, 2022 00:25:32
Вт июн 14, 2022 00:32:02
StartAdcConversion(ADC_CHSELR_CHSEL3 | ADC_CHSELR_CHSEL2 | ADC_CHSELR_CHSEL1 | ADC_CHSELR_CHSEL0,
ADC_SMPR_SMP_2 | ADC_SMPR_SMP_1 | ADC_SMPR_SMP_0); // tCONV = 18 usec);
#include <inttypes.h>
#include "stm32f0xx.h"
#include "main.h"
#include "analog.h"
#include "ntc.h"
volatile
ChData_TypeDef ChData [ChDataSize] __attribute__ ((aligned (sizeof(AdcChData_TypeDef))));
ChData_TypeDef samRntc [NUM_ADC_SAMPLES] __attribute__ ((aligned (sizeof(AdcChData_TypeDef))));
const uint16_t RA [NUM_ADC_CHANELS] __attribute__ ((aligned (sizeof(AdcChData_TypeDef)))) =
{3297u, 3298u, 3300u, 3300u};
void StartAdcConversion(uint32_t ch, uint8_t stime)
{
startADC1((void*)ChData, sizeof(ChData) / sizeof(AdcChData_TypeDef), ch, stime);
}
// Sample No
static uint8_t samNo = 0;
void CalcAvrNTC(void)
{
// Расчёт средних измеренных значений R_NTC
for(uint8_t ch = 0 ; ch < NUM_ADC_CHANELS; ch++) {
uint32_t sch = 0;
const ChData_TypeDef* pch = (const ChData_TypeDef*)ChData;
for(uint16_t sample = 0; sample < sizeof(ChData) / sizeof(ChData[0]); sample++, pch++) {
sch += pch->chd[ch];
}
sch += (sizeof(ChData) / sizeof(ChData[0])) >> 1;
sch >>= (ChDataBits - 1);
uint16_t div = 8191 - sch;
samRntc[samNo].chd[ch] = ((sch + 1) * RA[ch] + (div >> 1)) / div;
}
if(++samNo >= NUM_ADC_SAMPLES) {
samNo = 0;
}
}
void CalcAvrTemperature(void)
{
// Расчёт измеренных значений температуры
for(uint8_t ch = 0 ; ch < NUM_ADC_CHANELS; ch++) {
uint32_t sch = 0;
for(uint8_t sample = 0; sample < NUM_ADC_SAMPLES; sample++) {
sch += samRntc[sample].chd[ch];
}
sch += NUM_ADC_SAMPLES >> 1;
sch /= NUM_ADC_SAMPLES;
// температуры в контрольных точках по номерам каналов
Temper01[ch] = CalcTemperature01((uint16_t)sch);
}
}
#define TEMPERATURE_START 0 // от 0 гр.С
#define TEMPERATURE_END 1000 // до 100 гр.С
#define TEMPERATURE_STEP 10 // с шагом 0.1 гр.С
// Значения сопротивления NTC терморезистора MF52 10k 5% B25/50=3950K от 0°C до 100°C с шагом 1°C
// Индекс элемента - температура, значение элемента - сопротивление NTC при этой температуре
const uint16_t R_NTC_table[] __attribute__ ((aligned (sizeof(uint16_t)))) = {
/* 0 */ 32960, 31308, 29749, 28279, 26891, 25580, 24334, 23158, 22046, 20994,
/* 10 */ 20000, 19057, 18164, 17319, 16518, 15760, 15039, 14356, 13708, 13093,
/* 20 */ 12510, 11955, 11428, 10927, 10452, 10000, 9569, 9160, 8771, 8400,
/* 30 */ 8048, 7711, 7391, 7086, 6795, 6518, 6253, 6001, 5760, 5531,
/* 40 */ 5312, 5102, 4902, 4711, 4528, 4354, 4187, 4027, 3874, 3728,
/* 50 */ 3588, 3454, 3326, 3204, 3086, 2974, 2866, 2762, 2663, 2567,
/* 60 */ 2476, 2388, 2304, 2224, 2146, 2072, 2001, 1932, 1867, 1804,
/* 70 */ 1743, 1685, 1629, 1575, 1523, 1473, 1425, 1379, 1334, 1291,
/* 80 */ 1250, 1210, 1172, 1135, 1099, 1065, 1032, 1000, 969, 940,
/* 90 */ 911, 883, 857, 831, 806, 782, 759, 737, 715, 695,
/*100 */ 674
};
int16_t CalcTemperature01(uint16_t rntc)
{
uint8_t l = 0;
uint8_t r = (sizeof(R_NTC_table) / sizeof(R_NTC_table[0])) - 1;
// Проверка выхода за пределы и граничных значений
if(rntc <= R_NTC_table[r]) {
return TEMPERATURE_END;
} else if(rntc >= R_NTC_table[l]) {
return TEMPERATURE_START;
}
// Двоичный поиск по таблице
while((r - l) > 1) {
uint8_t m = (l + r) >> 1;
if(rntc > R_NTC_table[m]) {
r = m;
} else if(rntc < R_NTC_table[m]) {
l = m;
} else { // наткнулись
l = r = m;
break;
}
}
int16_t result;
if(rntc >= R_NTC_table[l]) { // наткнулись или ошибка в таблице
result = TEMPERATURE_START + TEMPERATURE_STEP * l;
} else {
uint16_t vd = R_NTC_table[l] - R_NTC_table[r];
result = TEMPERATURE_START + r * TEMPERATURE_STEP;
if(vd) {
// Линейная интерполяция
result -= ((TEMPERATURE_STEP * (rntc - R_NTC_table[r]) + (vd >> 1)) / vd);
}
}
return result;
}
#include "stm32f0xx.h"
#include "analog.h"
volatile uint8_t bConversionComplete;
// DMA1 Channel 1 interrupt handler
#ifdef __cplusplus
extern "C"
#endif
void DMA1_Channel1_IRQHandler(void)
{
// A Transfer Complete or Transfer Error flag
if(READ_BIT(DMA1->ISR, DMA_ISR_TCIF1 | DMA_ISR_TEIF1) != RESET) {
// ADC stop
stopADC1();
if(READ_BIT(DMA1->ISR, DMA_ISR_TCIF1) != RESET)
bConversionComplete = SET;
// Disable DMA1 Channel1
CLEAR_BIT(DMA1_Channel1->CCR, DMA_CCR_EN);
// Channel1 clear interrupt flags
SET_BIT(DMA1->IFCR, DMA_IFCR_CGIF1 | DMA_IFCR_CTCIF1 | DMA_IFCR_CHTIF1 | DMA_IFCR_CTEIF1);
}
}
// ADC start
void startADC1(void* pData, uint16_t num, uint32_t ch, uint8_t stime)
{
// ADC stop
stopADC1();
// Sampling time selection, Fadc = 14 MHz
// SMP Sampling tCONV,
// time,cycles usec
// 000 1,5 1,00
// 001 7,5 1,43
// 010 13,5 1,86
// 011 28,5 2,93
// 100 41,5 3,86
// 101 55,5 4,86
// 110 71,5 6,00
// 111 239,5 18,00
MODIFY_REG(ADC1->SMPR, ADC_SMPR_SMP, stime);
// ADC channel selection
MODIFY_REG(ADC1->CHSELR, ADC_CHSELR_CHSEL, ch);
// Analog watchdog disabled, ADC group regular sequencer discontinuous mode disabled,
// DR register is preserved with the old data when an overrun is detected,
// Hardware trigger detection disabled, Right alignment, Data resolution 12 bits,
// Scan sequence direction Upward, DMA one shot mode selected,
// ADC low power auto power enabled, Wait conversion mode on,
// Continuous conversion mode enabled, DMA enabled
MODIFY_REG(ADC1->CFGR1, ADC_CFGR1_AWD1EN | ADC_CFGR1_DISCEN |
ADC_CFGR1_OVRMOD | ADC_CFGR1_EXTEN | ADC_CFGR1_ALIGN | ADC_CFGR1_RES | ADC_CFGR1_SCANDIR | ADC_CFGR1_DMACFG,
ADC_CFGR1_AUTOFF | ADC_CFGR1_WAIT |ADC_CFGR1_CONT | ADC_CFGR1_DMAEN);
// DMA
// wait DMA1 Channel1 Transfer Complete flag
if(READ_BIT(DMA1_Channel1->CCR, DMA_CCR_EN) != RESET) {
// wait for Transfer Complete or Transfer Error flag
while(READ_BIT(DMA1->ISR, DMA_ISR_TCIF1 | DMA_ISR_TEIF1) == RESET);
// Disable DMA1 Channel1
CLEAR_BIT(DMA1_Channel1->CCR, DMA_CCR_EN);
}
// ADC DMA map to DMA1 Chanel1
CLEAR_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_ADC_DMA_RMP);
// Configure the peripheral address register
WRITE_REG(DMA1_Channel1->CPAR, (uint32_t)&(ADC1->DR));
// Configure the memory address
WRITE_REG(DMA1_Channel1->CMAR, (uint32_t)pData);
// Configure the number of DMA tranfer to be performs on channel
MODIFY_REG(DMA1_Channel1->CNDTR, 0xffffu, num);
// Channel priority level 01 Medium, Peripheral & Memory size 01 16-bits,
// Memory increment mode 1 enabled, Data transfer direction 0 Read from peripheral
// Circular mode disabled, Transfer complete interrupt enabled
MODIFY_REG(DMA1_Channel1->CCR, DMA_CCR_MEM2MEM | DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE |
DMA_CCR_PINC | DMA_CCR_CIRC | DMA_CCR_DIR | DMA_CCR_TEIE | DMA_CCR_HTIE | DMA_CCR_EN,
DMA_CCR_PL_0 | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_MINC | DMA_CCR_TCIE);
// ADC group regular conversion start
SET_BIT(ADC1->CR, ADC_CR_ADSTART);
// Enable DMA1 Channel1
SET_BIT(DMA1_Channel1->CCR, DMA_CCR_EN);
// Conversion complete flag
bConversionComplete = RESET;
// DMA1 Channel1 (ADC) interrupt enable
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
NVIC_SetPriority(DMA1_Channel1_IRQn, 3);
}
uint16_t scmADC1(uint32_t ch, uint8_t stime)
{
// ADC stop
stopADC1();
// Sampling time selection, Fadc = 14 MHz
// SMP Sampling tCONV,
// time,cycles usec
// 000 1,5 1,00
// 001 7,5 1,43
// 010 13,5 1,86
// 011 28,5 2,93
// 100 41,5 3,86
// 101 55,5 4,86
// 110 71,5 6,00
// 111 239,5 18,00
MODIFY_REG(ADC1->SMPR, ADC_SMPR_SMP, stime);
// Analog watchdog disabled, ADC group regular sequencer discontinuous mode disabled,
// Wait conversion mode off, Continuous conversion mode disabled,
// DR register is preserved with the old data when an overrun is detected,
// Hardware trigger detection disabled, Right alignment, Data resolution 12 bits,
// Scan sequence direction Upward, DMA one shot mode selected, DMA disabled
// ADC low power auto power enabled
MODIFY_REG(ADC1->CFGR1, ADC_CFGR1_AWD1EN | ADC_CFGR1_DISCEN | ADC_CFGR1_WAIT |
ADC_CFGR1_CONT | ADC_CFGR1_OVRMOD | ADC_CFGR1_EXTEN | ADC_CFGR1_ALIGN | ADC_CFGR1_RES |
ADC_CFGR1_SCANDIR | ADC_CFGR1_DMACFG | ADC_CFGR1_DMAEN,
ADC_CFGR1_AUTOFF);
// ADC channel selection
MODIFY_REG(ADC1->CHSELR, ADC_CHSELR_CHSEL, ch);
// ADC group regular conversion start
SET_BIT(ADC1->CR, ADC_CR_ADSTART);
// ADC group regular end of unitary conversion flag
while(READ_BIT(ADC1->ISR, ADC_ISR_EOC) == RESET);
// ADC data register
return READ_BIT(ADC1->DR, 0xffffu);
}
// ADC stop
void stopADC1(void)
{
// ADC group regular conversion stop
if(READ_BIT(ADC1->CR, ADC_CR_ADSTART) != RESET) {
SET_BIT(ADC1->CR, ADC_CR_ADSTP);
// wait for ADC group regular conversion stop
while(READ_BIT(ADC1->CR, ADC_CR_ADSTP) != RESET);
}
}
// ADC calibration
void calADC1(void)
{
// ADC disable
if(READ_BIT(ADC1->CR, ADC_CR_ADEN) != RESET) {
// ADC stop
stopADC1();
// ADC disable
SET_BIT(ADC1->CR, ADC_CR_ADDIS);
// wait for ADC1 disable
while(READ_BIT(ADC1->CR, ADC_CR_ADEN) != RESET);
}
// ADC DMA transfer disable
CLEAR_BIT(ADC1->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG);
// ADC calibration
SET_BIT(ADC1->CR, ADC_CR_ADCAL);
// Wait until ADCAL=0
while(READ_BIT(ADC1->CR, ADC_CR_ADCAL) != RESET);
// ADC Enable
// Clear the ADRDY bit
if(READ_BIT(ADC1->ISR, ADC_ISR_ADRDY) != RESET)
SET_BIT(ADC1->ISR, ADC_ISR_ADRDY);
// ADC enable
SET_BIT(ADC1->CR, ADC_CR_ADEN);
// wait for ADC ready flag
while(READ_BIT(ADC1->ISR, ADC_ISR_ADRDY) == RESET);
}
// ADC initialization
void initADC1(void)
{
// HSI14 clock request from ADC disable
SET_BIT(RCC->CR2, RCC_CR2_HSI14DIS);
// Internal High Speed 14MHz clock enable
SET_BIT(RCC->CR2, RCC_CR2_HSI14ON);
// wait for Internal High Speed 14MHz clock ready
while(READ_BIT(RCC->CR2, RCC_CR2_HSI14RDY) == RESET);
// Internal High Speed 14MHz clock enable
CLEAR_BIT(RCC->CR2, RCC_CR2_HSI14DIS);
// ADCCLK (Asynchronous clock mode), generated at product level (refer to RCC section)
CLEAR_BIT(ADC1->CFGR2, RCC_CFGR2_PREDIV);
// ADC1 clock enable
SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADCEN);
// ADC calibration
calADC1();
// Conversion complete flag
bConversionComplete = RESET;
}
Вт июн 14, 2022 00:53:10
MF52 Time Constant of ≤7 seconds in still air
Available tolerances: ±1%, ±2%, ±3% and ±5%
Вт июн 14, 2022 00:55:36
Вт июн 14, 2022 00:57:49
Вт июн 14, 2022 00:58:50
Вт июн 14, 2022 01:00:10
Вт июн 14, 2022 01:20:51
Вт июн 14, 2022 01:33:02
Вт июн 14, 2022 16:42:07
int16_t curr_temp;extern uint8_t ow_Answ[9];
snprintf(txt, sizeof(txt), "%d.%d°", curr_temp/10, curr_temp % 10); // Форматируем строку из примера выше. Число 77 станет "7.7°"
get_text_bounds((G_FONT_t *)&Tahoma16, txt, &x, &y, &l1, &h); // Вычисляем габариты строки (сколько она займёт места на экране). Значения размеров будут помещены в переменные l1 и h
write_string((G_FONT_t *)&Tahoma16, txt, &l1, &cy, framebuffer); // Вызываем функцию отрисовки полученой выше строки в экранный буфер framebuffer.
// И где-то сильно позже будет вызвана функция отправки данных на дисплей.
// Процесс вывода из буфера на экран.
epd_init();
// ESP_LOGI("Renderer", "EPD Power ON");
epd_poweron();
// ESP_LOGI("Renderer", "EPD CLS");
epd_clear();
// ESP_LOGI("Renderer", "EPD Draw");
epd_draw_grayscale_image(epd_full_screen(), framebuffer);
// ESP_LOGI("Renderer", "EPD Power OFF");
epd_poweroff_all();
const uint8_t Digits[13] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40,0x00,0x08};
// ^- Вот это - сами цифры.
// v- Вот это - как расположены сегменты геометрически.
// g-f-e-d-c-b-a [5]
// h [2] -g-f-e-d-c-b-a [5]
// g-f-e-d-c-b-a [5]
// deg [4]
// v- Вот это их представление в виде битов.
// 0 -> 0 1 1 1 1 1 1
// 1 -> 0 0 0 0 1 1 0
// 2 -> 1 0 1 1 0 1 1
// 3 -> 1 0 0 1 1 1 1
// 4 -> 1 1 0 0 1 1 0
// 5 -> 1 1 0 1 1 0 1
// 6 -> 1 1 1 1 1 0 1
// 7 -> 0 0 0 0 1 1 1
// 8 -> 1 1 1 1 1 1 1
// 9 -> 1 1 0 1 1 1 1
// - -> 1 0 0 0 0 0 0
// -> 0 0 0 0 0 0 0
// _ -> 0 0 0 1 0 0 0
void LED_Push(int16_t value) {
uint8_t v;
// -550 .. +1250 (degrees * 10 with fixed decimal point)
if (value < 0) {
// Blue if neg
CurrentColor[0] = 0;
CurrentColor[1] = 0;
CurrentColor[2] = 0xFF;
is_minus = 1;
if (value > -100) {
// -x.x
is_dot = 1;
value = -value;
v = value / 10;
Led_DigitAt(v, 1);
Led_DigitAt((value % 10), 2);
} else {
is_dot = 0;
value = -value;
value = value / 10;
v = value / 10;
Led_DigitAt(v, 1);
Led_DigitAt((value % 10), 2);
// -xx
};
} else {
is_minus = 0;
// no minus
// 0..40 -> Yellow
if ((value >= 0) && (value < 400)) {
CurrentColor[0] = 0xFF;
CurrentColor[1] = 0xFF;
CurrentColor[2] = 0;
} else if ((value >= 400) && (value < 900)) {
// 40..90 -> Green
CurrentColor[0] = 0;
CurrentColor[1] = 0xFF;
CurrentColor[2] = 0;
} else {
// > 90 -> Red
CurrentColor[0] = 0xFF;
CurrentColor[1] = 0;
CurrentColor[2] = 0;
};
if (value < 100) {
is_dot = 1;
// _x.x
Led_DigitAt(11, 0);
v = value % 10;
value = value / 10;
Led_DigitAt(v, 2);
v = value % 10;
value = value / 10;
Led_DigitAt(v, 1);
} else if (value < 1000) {
is_dot = 1;
v = value % 10;
value = value / 10;
Led_DigitAt(v, 2);
v = value % 10;
value = value / 10;
Led_DigitAt(v, 1);
Led_DigitAt(value, 0);
// xx.x
} else {
is_dot = 0;
value = value / 10;
v = value % 10;
value = value / 10;
Led_DigitAt(v, 2);
v = value % 10;
value = value / 10;
Led_DigitAt(v, 1);
Led_DigitAt(value, 0);
// xxx
};
};
if (is_dot) {
pixels[75*3 + 0] = CurrentColor[0] & Current_BL;
pixels[75*3 + 1] = CurrentColor[1] & Current_BL;
pixels[75*3 + 2] = CurrentColor[2] & Current_BL;
pixels[74*3 + 0] = CurrentColor[0] & Current_BL;
pixels[74*3 + 1] = CurrentColor[1] & Current_BL;
pixels[74*3 + 2] = CurrentColor[2] & Current_BL;
} else {
pixels[75*3 + 0] = 0x00;
pixels[75*3 + 1] = 0x00;
pixels[75*3 + 2] = 0x00;
pixels[74*3 + 0] = 0x00;
pixels[74*3 + 1] = 0x00;
pixels[74*3 + 2] = 0x00;
};
if (is_minus) {
Led_DigitAt(11, 0);
};
// degree sign
pixels[0] = CurrentColor[0] & Current_BL;
pixels[1] = CurrentColor[1] & Current_BL;
pixels[2] = CurrentColor[2] & Current_BL;
pixels[3] = CurrentColor[0] & Current_BL;
pixels[4] = CurrentColor[1] & Current_BL;
pixels[5] = CurrentColor[2] & Current_BL;
pixels[6] = CurrentColor[0] & Current_BL;
pixels[7] = CurrentColor[1] & Current_BL;
pixels[8] = CurrentColor[2] & Current_BL;
pixels[9] = (CurrentColor[0] & Current_BL) / 2;
pixels[10] = (CurrentColor[1] & Current_BL) / 2;
pixels[11] = (CurrentColor[2] & Current_BL) / 2;
}
void Led_DigitAt(uint8_t Digit, uint8_t Pos) {
uint16_t shift = 0;
int i;
uint8_t v;
switch (Pos) {
case 0: {
shift = 76;
break;
};
case 1: {
shift = 39;
break;
};
case 2: {
shift = 4;
break;
};
};
for (i=0; i<7; i++) {
if (Digits[Digit] & (0x01 << i)) {
for (v=0; v<5; v++) {
pixels[shift*3 + i*15 + v*3 + 0] = Current_BL & CurrentColor[0];
pixels[shift*3 + i*15 + v*3 + 1] = Current_BL & CurrentColor[1];
pixels[shift*3 + i*15 + v*3 + 2] = Current_BL & CurrentColor[2];
};
} else {
for (v=0; v<5; v++) {
pixels[shift*3 + i*15 + v*3 + 0] = 0x00;
pixels[shift*3 + i*15 + v*3 + 1] = 0x00;
pixels[shift*3 + i*15 + v*3 + 2] = 0x00;
};
};
};
}
void Led_Push_Px(int Number) {
uint8_t i;
uint8_t clr = 0, j;
// F_CPU = 8MHz = 62.5nS/tick
uint8_t H = PORTB | 1;
uint8_t L = PORTB & ~(1);
for (j=0;j<3;j++){
if (j==1) {clr = pixels[Number*3];};
if (j==0) {clr = pixels[Number*3+1];};
if (j==2) {clr = pixels[Number*3+2];};
i = 0x80;
while(i) {
if (clr & i) {
PORTB = H; // 62uS
asm volatile("nop"); // ~125nS
asm volatile("nop"); // ~295nS
asm volatile("nop"); // ~355nS
asm volatile("nop"); // ~420nS
asm volatile("nop"); // 485nS
asm volatile("nop"); // 550nS
asm volatile("nop"); // 615nS
asm volatile("nop"); // 670nS
PORTB = L;
} else {
PORTB = H; // 0nS
asm("nop"); // 62nS
asm("nop"); // 125nS
asm("nop"); // 185nS
PORTB = L; // +250nS -> 400uS
asm("nop"); // 465nS
asm("nop"); // 520nS
asm("nop"); // 580nS
asm volatile("nop"); // 650nS
};
i = i >> 1;
};
};
}
Чт июн 16, 2022 19:50:12
/*
* 1-wire(mega32a).c
*
* Created: 13.03.2018 5:40:10
* Author : User
*/
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include "DS18B20.h"
//#include "adc.h"
#include "lcd.h"
unsigned int temper;
unsigned int temper_tt;
unsigned char S;
char bufer0[60];
void inits_ports(void)
{
DDRB=0xFF;
PORTB=0x00;
DDRC|=(1<<2);
PORTC|=(0<<2);
DDRA=0x00;
PORTA=0x00;
DDRD=0xFF;
PORTD=0x00;
}
int main(void)
{
//unsigned int tt=0;
inits_ports();
//init_ADC();
lcd_init(LCD_DISP_ON);
lcd_clrscr();
while (1)
{
temper_tt=dt_check();
if (ds18b20_GetSign(temper_tt))
{
temper_tt=~temper_tt+1;
S='-';
}
else
{
S=' ';
}
temper=converttemp(temper_tt);
lcd_gotoxy(0,1);
sprintf(bufer0,"t=%c%2d *C\n\r",S,temper);
lcd_puts(bufer0);
}
}
#include "DS18B20.h"
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#define NOID 0xCC //Пропустить идентификацию
#define T_CONVERT 0x44 //Код измерения температуры
#define READ_DATA 0xBE //Передача байтов ведущему
#define PORTTEMP PORTD
#define DDRTEMP DDRD
#define PINTEMP PIND
#define BITTEMP 1
//функция определения датчика на шине
char dt_testdevice(void) //dt - digital termomether | определим, есть ли устройство на шине
{
//char stektemp=SREG;// сохраним значение стека
cli(); //запрещаем прерывание
char dt;
DDRTEMP |= 1<<BITTEMP; //притягиваем шину
_delay_us(485); //задержка как минимум на 480 микросекунд
DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
_delay_us(65); //задержка как максимум на 60 микросекунд
if ((PINTEMP & (1<<BITTEMP))==0)//проверяем, ответит ли устройство
{
dt=1;//устройство есть
}
else dt=0;//устройства нет
//SREG = stektemp;// вернем значение стека
_delay_us(420); //задержка как минимум на 480 микросекунд, но хватит и 420, тк это с учетом времени прошедших команд
return dt; //вернем результат
}
//функция записи бита на устройство
void dt_sendbit(char bt)
{
//char stektemp=SREG;// сохраним значение стека
cli(); //запрещаем прерывание
DDRTEMP |= 1<<BITTEMP; //притягиваем шину
_delay_us(2); //задержка как минимум на 2 микросекунды
if(bt)
DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
_delay_us(65); //задержка как минимум на 60 микросекунд
DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
//SREG = stektemp;// вернем значение стека
}
//функция записи байта на устройство
void dt_sendbyte(unsigned char bt)
{
char i;
for(i=0;i<8;i++)//посылаем отдельно каждый бит на устройство
{
if((bt & (1<<i)) == 1<<i)//посылаем 1
dt_sendbit(1);
else //посылаем 0
dt_sendbit(0);
}
}
//функция чтения бита с устройства
char dt_readbit(void)
{
//char stektemp=SREG;// сохраним значение стека
cli(); //запрещаем прерывание
char bt; //переменная хранения бита
DDRTEMP |= 1<<BITTEMP; //притягиваем шину
_delay_us(2); //задержка как минимум на 2 микросекунды
DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
_delay_us(13);
bt = (PINTEMP & (1<<BITTEMP))>>BITTEMP; //читаем бит
_delay_us(45);
// SREG = stektemp;// вернем значение стека
return bt; //вернем результат
}
//функция чтения байта с устройства
unsigned char dt_readbyte(void)
{
char c=0;
char i;
for(i=0;i<8;i++)
c|=dt_readbit()<<i; //читаем бит
return c;
}
//функция преобразования показаний датчика в температуру
int dt_check(void)
{
unsigned char bt;//переменная для считывания байта
unsigned int tt=0;
if(dt_testdevice()==1) //если устройство нашлось
{
dt_sendbyte(NOID); //пропустить идентификацию, тк у нас только одно устройство на шине
dt_sendbyte(T_CONVERT); //измеряем температуру
_delay_ms(750); //в 12битном режиме преобразования - 750 милисекунд
dt_testdevice(); //снова используем те же манипуляции с шиной что и при проверке ее присутствия
dt_sendbyte(NOID); //пропустить идентификацию, тк у нас только одно устройство на шине
dt_sendbyte(READ_DATA); //даем команду на чтение данных с устройства
bt = dt_readbyte(); //читаем младший бит
tt = dt_readbyte(); //читаем старший бит MS
tt = (tt<<8)|bt;//сдвигаем старший влево, младший пишем на его место, тем самым получаем общий результат
}
return tt;
}
char ds18b20_GetSign(unsigned int dt)
{
//Проверим 11-й бит
if (dt&(1<<11)) return 1;
else return 0;
}
//преобразование температуры в единицы
char converttemp (unsigned int tt)
{
char t = tt>>4;//сдвиг и отсечение части старшего байта
return t;
}
Пт июн 17, 2022 07:09:15
unsigned int temper_tt;
temper_tt=dt_check();
char ds18b20_GetSign(unsigned int dt)
{
//Проверим 11-й бит
if (dt&(1<<11)) return 1;
else return 0;
}
char ds18b20_GetSign(int dt)
{
if (dt < 0) return 1;
else return 0;
}
//преобразование температуры в единицы
char converttemp (unsigned int tt)
{
char t = tt>>4;//сдвиг и отсечение части старшего байта
return t;
}
char converttemp (int tt)
{
char t = tt / 16;
return t;
}
char text_array[5];
// Работает со значениями -55~127 градусов
// [-55n ] n = NULL-терминатор строки
// [-18n ]
// [ 0n ]
// [ 22n ]
// [ 127n]
void temp_to_text(int temp, chat *text) {
int temp_value = temp;
if (temp_value < 0) {
text[0] = '-';
temp_value = -temp_value;
} else {
text[0] = ' ';
}
// Здесь temp_value всегда имеет положительное значение.
if (temp_value < 10) {
// Значения 0..9
text[1] = '0' + temp_value;
text[2] = 0;
} else if (temp_value < 100) {
// Значения 10..99
text[1] = '0' + (temp_value / 10);
text[2] = '0' + (temp_value % 10);
text[3] = 0;
} else {
// Значения 100..127
text[1] = '1'; // Потому что не больше 127
temp_value = temp_value % 100;
text[2] = '0' + (temp_value / 10);
text[3] = '0' + (temp_value % 10);
text[4] = 0;
};
}
Пт июн 17, 2022 07:21:06
Пт июн 17, 2022 07:48:37