Вс сен 22, 2019 15:15:45
Пн сен 23, 2019 06:41:11
Пн сен 23, 2019 13:10:19
/*
* File: ds18b20-tmp03f-conv.c
* Author: nstorm
* DS18B20 code author: http://blablacode.ru/mikrokontrollery/442
*/
#define F_CPU 8000000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/cpufunc.h>
#include <util/delay.h>
#include <math.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include "ds18b20-tmp03f-conv.h"
// Global temp
temp_t temp;
volatile uint16_t pwm_reg;
// сброс датчика
uint8_t therm_reset() {
uint8_t i;
// опускаем ногу вниз на 480uS
THERM_LOW();
THERM_OUTPUT_MODE();
_delay_us(480); // замените функцию задержки на свою
// подымаем линию на 60uS
THERM_INPUT_MODE();
_delay_us(60);
// получаем значение на линии в период 480uS
i = (THERM_PIN & (1 << THERM_DQ));
_delay_us(420);
// возвращаем значение (0=OK, 1=датчик не найден)
return i;
}
// функция отправки бита
void therm_write_bit(uint8_t bit) {
// опускаем на 1uS
THERM_LOW();
THERM_OUTPUT_MODE();
_delay_us(1);
// если хотим отправить 1, поднимаем линию (если нет, оставляем как есть)
if (bit) THERM_INPUT_MODE();
// ждем 60uS и поднимаем линию
_delay_us(60);
THERM_INPUT_MODE();
}
// чтение бита
uint8_t therm_read_bit(void) {
uint8_t bit = 0;
// опускаем на 1uS
THERM_LOW();
THERM_OUTPUT_MODE();
_delay_us(1);
// поднимаем на 14uS
THERM_INPUT_MODE();
_delay_us(14);
// читаем состояние
if (THERM_PIN & (1 << THERM_DQ)) bit = 1;
// ждем 45 мкс и возвращаем значение
_delay_us(45);
return bit;
}
// читаем байт
uint8_t therm_read_byte(void) {
uint8_t i = 8, n = 0;
while (i--) {
// сдвигаем в право на 1 и сохраняем следующее значение
n >>= 1;
n |= (therm_read_bit() << 7);
}
return n;
}
// отправляем байт
void therm_write_byte(uint8_t byte) {
uint8_t i = 8;
while (i--) {
// отправляем бит и сдвигаем вправо на 1
therm_write_bit(byte & 1);
byte >>= 1;
}
}
void therm_convert() {
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
therm_write_byte(THERM_CMD_CONVERTTEMP);
}
// читаем температуру с датчика
bool therm_read_temperature() {
uint8_t temperature[2];
if (!therm_read_bit())
return false;
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
therm_write_byte(THERM_CMD_RSCRATCHPAD);
temperature[0] = therm_read_byte();
temperature[1] = therm_read_byte();
therm_reset();
temp.digit = temperature[0] >> 4;
temp.digit |= (temperature[1] & 0x7) << 4;
temp.decimal = temperature[0] & 0xF;
temp.decimal *= THERM_DECIMAL_STEPS_12BIT;
return true;
}
void update_pwm_reg() {
cli();
pwm_reg = ((uint32_t)(TMP_LOW_CNT * 400) / (235 - temp.digit));
sei();
}
void read_and_update() {
therm_convert();
while (!therm_read_temperature());
update_pwm_reg();
}
ISR(TIM0_COMPB_vect) {
OCR0A = pwm_reg;
}
void init() {
cli(); // Disable interrupts
CCP = 0xD8; // Magic number to enable configuration access
CLKMSR = 0b00; // Internal osc
_NOP();
_NOP();
_NOP();
CCP = 0xD8;
CLKPSR = 0; // Prescaler 1:1 = 8 MHz system clock
ACSR |= (1 << 7); // ACD (ACD: Analog Comparator Disable = 1)
PRR = 0b11; // Power Reduction Register
sei(); // Enable interrupts
THERM_DDR = 0xFF; //
/* Timer init
* PWM, Phase & Freq. Correct, TOP = OCR0A, 1:8 prescaler
* Counting up: Set OC0A/OC0B on compare match
* Counting down: Clear OC0A/OC0B on compare match
*/
TCCR0A = (1 << WGM00) | (1 << COM0B0) | (1 << COM0B1);
TCCR0B = (1 << WGM03) | (1 << CS01);
TCCR0C = 0;
TIMSK0 = (1 << OCIE0B); // Enable OC0B interrupt (at BOTTOM)
}
int main(void) {
init();
// Initial temp reading
read_and_update();
OCR0A = pwm_reg;
OCR0B = TMP_LOW_CNT;
PRR = (1 << PRTIM0); // Enable Timer0
while (1) {
read_and_update();
}
}
/*
* File: ds18b20-tmp03f-conv.h
* Author: nstorm
*/
#include <stdint.h>
#ifndef DS18B20_TMP03F_CONV_H
#define DS18B20_TMP03F_CONV_H
/* Определяем куда подключен датчик */
#define THERM_PORT PORTB
#define THERM_DDR DDRB
#define THERM_PIN PINB
#define THERM_DQ PB2
/* Макросы для "дергания ноги" и изменения режима ввода/вывода */
#define THERM_INPUT_MODE() THERM_DDR &= ~(1 << THERM_DQ)
#define THERM_OUTPUT_MODE() THERM_DDR |= (1 << THERM_DQ)
#define THERM_LOW() THERM_PORT &= ~(1 << THERM_DQ)
#define THERM_HIGH() THERM_PORT |= (1 << THERM_DQ)
// команды управления датчиком
#define THERM_CMD_CONVERTTEMP 0x44
#define THERM_CMD_RSCRATCHPAD 0xBE
#define THERM_CMD_WSCRATCHPAD 0x4E
#define THERM_CMD_CPYSCRATCHPAD 0x48
#define THERM_CMD_RECEEPROM 0xB8
#define THERM_CMD_RPWRSUPPLY 0xB4
#define THERM_CMD_SEARCHROM 0xF0
#define THERM_CMD_READROM 0x33
#define THERM_CMD_MATCHROM 0x55
#define THERM_CMD_SKIPROM 0xCC
#define THERM_CMD_ALARMSEARCH 0xEC
#define THERM_DECIMAL_STEPS_12BIT 625 //.0625
#define TMP_LOW_US 12000
#define TMP_LOW_CNT (uint16_t)(TMP_LOW_US/2)
typedef struct {
int8_t digit;
uint16_t decimal;
} temp_t;
#endif /* DS18B20_TMP03F_CONV_H */
:100000000AC019C018C017C016C015C09FC013C0C1
:1000100012C011C010C011271FBFCFE5D0E0DEBF56
:10002000CDBF20E0A0E4B0E001C01D93A534B2072D
:10003000E1F79ED0F9C0E4CF49E0415071F0129849
:100040000A9A52E05A95F1F700C080FD0A9850EAEA
:100050005A95F1F70A988695F0CF089512980A9A62
:1000600042E04A95F1F700C00A9845E24A95F1F757
:10007000000080B148E74A95F1F782FB882780F9B4
:100080000895CF93DF93D9E0C0E0D15039F0E6DF97
:10009000879588278795C695C82BF7CF8C2FDF913A
:1000A000CF91089512980A9A4FEB53E04150504077
:1000B000E9F700C000000A9850EA5A95F1F780B1BC
:1000C00047E453E041505040E9F700C0000084701D
:1000D00008952F933F93CF93E5DF8CECADDF84E45D
:1000E000ABDFBCDF8823E9F3DDDF8CECA5DF8EEB33
:1000F000A3DFC7DFC82FC5DF382FD4DF37703295B5
:10010000307F4C2F42954F70342B30A98C2F8F703D
:1001100090E061E772E04FD092A981A9F89440A1E4
:100120002BEE30E0241B310B47FD3395032F000FDE
:10013000440B550B60E07FE980E090E04ED034A99D
:1001400023A97894CF913F912F9108951F930F93F6
:100150000FB70F9310E04F935F9343A154A157BD86
:1001600046BD5F914F910F910FBF0F911F91189551
:10017000F89448ED4CBF17BF0000000000004CBFD2
:1001800016BFFF9A43E045BF78944FEF41B941E372
:100190004EBD42E14DBD1CBD44E04BBD9ADF43A1C5
:1001A00054A157BD46BD40E757E155BD44BD41E0B0
:1001B00045BF8FDFFECF0027552704C0080F591F0A
:1001C000880F991F8050904029F076956795B0F37D
:1001D0007107B1F7802F952F0895A1E21A2FAA1B5E
:1001E000BB1BEA2FFB2F0DC0AA1FBB1FEE1FFF1F5B
:1001F000A217B307E407F50720F0A21BB30BE40B2B
:10020000F50B661F771F881F991F1A9569F7609570
:10021000709580959095262F372F482F592F6A2F4C
:0C0220007B2F8E2F9F2F0895F894FFCFA6
:00000001FF
Пт сен 27, 2019 08:58:35
Пт сен 27, 2019 11:09:15
Пт сен 27, 2019 11:39:44
Пт сен 27, 2019 13:55:30
Пт сен 27, 2019 14:25:22
Пт сен 27, 2019 15:02:07
temp.digit = temperature[0] >> 4;
temp.digit |= (temperature[1] & 0x7) << 4;
PRR = (1 << PRTIM0); // Enable Timer0
Пт сен 27, 2019 15:44:10
Пн сен 30, 2019 11:16:24
Ср окт 02, 2019 05:59:16