Merge branch 'master' into radio
This commit is contained in:
commit
446f85b05a
9
include/common.h
Normal file
9
include/common.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#define SET(X, Y) X |= (1 << Y)
|
||||
#define CLR(X, Y) X &= ~(1 << Y)
|
||||
#define CHK(X, Y) X & (1 << Y)
|
||||
#define TOG(X, Y) X ^= (1 << Y)
|
||||
|
||||
#endif /* COMMON_H */
|
15
include/io.h
15
include/io.h
@ -1,15 +0,0 @@
|
||||
#ifndef PORTS_H
|
||||
#define PORTS_H
|
||||
|
||||
/* DS18B20+ is configured in DS18B20 library */
|
||||
|
||||
/* Signal LED */
|
||||
#define LED_1 PD3
|
||||
|
||||
/* Servo motors */
|
||||
#define SERVO_L_PIN PB1
|
||||
#define SERVO_L OCR1A
|
||||
#define SERVO_R_PIN PB2
|
||||
#define SERVO_R OCR1B
|
||||
|
||||
#endif
|
10
include/led.h
Normal file
10
include/led.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef LED_H
|
||||
#define LED_H
|
||||
|
||||
#define LED_DDR DDRD
|
||||
#define LED_1_BIT PD3
|
||||
#define LED_2_BIT PD4
|
||||
|
||||
void init_leds(void);
|
||||
|
||||
#endif /* LED_H */
|
@ -3,15 +3,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define SET(PORT, PIN) (PORT |= (1 << PIN))
|
||||
#define CLR(PORT, PIN) (PORT &= (~(1 << PIN)))
|
||||
#define CHK(PORT, PIN) (PORT & (1 << PIN))
|
||||
#define TOG(PORT, PIN) (PORT ^= (1 << PIN))
|
||||
|
||||
void init_led(void);
|
||||
void init_pwm(void);
|
||||
void read_temp(void);
|
||||
void run_servos(void);
|
||||
uint16_t read_adc(uint8_t channel);
|
||||
|
||||
#endif
|
||||
|
21
include/servos.h
Normal file
21
include/servos.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef SERVOS_H
|
||||
#define SERVOS_H
|
||||
|
||||
#define SERVO_DDR DDRD
|
||||
#define SERVO_L_REG OCR0B
|
||||
#define SERVO_R_REG OCR0A
|
||||
#define SERVO_L_BIT PD5
|
||||
#define SERVO_R_BIT PD6
|
||||
|
||||
#define SERVO_MIN 930 // (us). Go backwards
|
||||
#define SERVO_MAX 1930 // (us). Go forwards
|
||||
#define SERVO_MID (SERVO_MIN + SERVO_MAX) / 2 // Stop
|
||||
#define PWM_PERIOD 16384 // (1000000 / F_CPU) * PRESCALER * 256) / F_CPU (us)
|
||||
|
||||
#define US2TIMER0(us) (255 * (uint32_t)us) / PWM_PERIOD
|
||||
|
||||
|
||||
void init_servos(void);
|
||||
void run_servos(void);
|
||||
|
||||
#endif /* SERVOS_H */
|
45
include/sonar.h
Normal file
45
include/sonar.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef SONAR_H
|
||||
#define SONAR_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
// Trigger
|
||||
#define TRIG_DDR DDRC
|
||||
#define TRIG_PORT PORTC
|
||||
#define TRIG_PIN PINC
|
||||
#define TRIG_BIT PC4
|
||||
|
||||
// Echo
|
||||
#define ECHO_DDR DDRC
|
||||
#define ECHO_PORT PORTC
|
||||
#define ECHO_PIN PINC
|
||||
#define ECHO_BIT PC5
|
||||
|
||||
#define SPEED_OF_SOUND 343 // (m/s)
|
||||
#define US_PER_CM 58 // Time for sound to travel distance of 1cm
|
||||
#define MAX_SONAR_RANGE 8 // Trigger + echo (m)
|
||||
#define DELAY_BETWEEN_TESTS 500 // Timeout for return signal
|
||||
#define TIMER_MAX 65535 // Depends on the timer used
|
||||
|
||||
#define CYCLES_PER_US F_CPU / 1000000
|
||||
#define SONAR_TIMEOUT (F_CPU * MAX_SONAR_RANGE) / SPEED_OF_SOUND
|
||||
|
||||
#define TRIG_ERROR -1
|
||||
#define ECHO_ERROR -2
|
||||
|
||||
#define TRIG_INPUT_MODE() CLR(TRIG_DDR, TRIG_BIT)
|
||||
#define TRIG_OUTPUT_MODE() SET(TRIG_DDR, TRIG_BIT)
|
||||
#define TRIG_LOW() CLR(TRIG_PORT, TRIG_BIT)
|
||||
#define TRIG_HIGH() SET(TRIG_PORT, TRIG_BIT)
|
||||
|
||||
#define ECHO_INPUT_MODE() CLR(ECHO_DDR, ECHO_BIT)
|
||||
#define ECHO_OUTPUT_MODE() SET(ECHO_DDR, ECHO_BIT)
|
||||
#define ECHO_LOW() CLR(ECHO_PORT, ECHO_BIT)
|
||||
#define ECHO_HIGH() SET(ECHO_PORT, ECHO_BIT)
|
||||
|
||||
|
||||
void init_sonar(void);
|
||||
void trigger_sonar(void);
|
||||
unsigned int read_sonar(void);
|
||||
|
||||
#endif /* SONAR_H */
|
@ -18,14 +18,11 @@ References:
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
//setup connection
|
||||
#define DS18B20_PORT PORTC
|
||||
#define DS18B20_DDR DDRC
|
||||
#define DS18B20_PIN PINC
|
||||
#define DS18B20_BIT PC0
|
||||
|
||||
#define DS18B20_PORT PORTD
|
||||
#define DS18B20_DDR DDRD
|
||||
#define DS18B20_PIN PIND
|
||||
#define DS18B20_DQ PD7
|
||||
|
||||
//commands
|
||||
#define DS18B20_CMD_CONVERTTEMP 0x44
|
||||
#define DS18B20_CMD_RSCRATCHPAD 0xbe
|
||||
#define DS18B20_CMD_WSCRATCHPAD 0x4e
|
||||
@ -41,7 +38,7 @@ References:
|
||||
//stop any interrupt on read
|
||||
#define DS18B20_STOPINTERRUPTONREAD 1
|
||||
|
||||
//functions
|
||||
|
||||
uint8_t ds18b20_reset(void);
|
||||
void ds18b20_writebit(uint8_t bit);
|
||||
uint8_t ds18b20_readbit(void);
|
144
src/ds18b20.c
144
src/ds18b20.c
@ -1,144 +0,0 @@
|
||||
/*
|
||||
ds18b20 lib 0x02
|
||||
|
||||
copyright (c) Davide Gironi, 2012
|
||||
|
||||
Released under GPLv3.
|
||||
Please refer to LICENSE file for licensing information.
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "ds18b20.h"
|
||||
|
||||
/*
|
||||
* ds18b20 init
|
||||
*/
|
||||
uint8_t ds18b20_reset()
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
//low for 480us
|
||||
DS18B20_PORT &= ~(1 << DS18B20_DQ); //low
|
||||
DS18B20_DDR |= (1 << DS18B20_DQ); //output
|
||||
_delay_us(480);
|
||||
|
||||
//release line and wait for 60uS
|
||||
DS18B20_DDR &= ~(1 << DS18B20_DQ); //input
|
||||
_delay_us(60);
|
||||
|
||||
//get value and wait 420us
|
||||
i = (DS18B20_PIN & (1 << DS18B20_DQ));
|
||||
_delay_us(420);
|
||||
|
||||
//return the read value, 0=ok, 1=error
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* write one bit
|
||||
*/
|
||||
void ds18b20_writebit(uint8_t bit)
|
||||
{
|
||||
//low for 1uS
|
||||
DS18B20_PORT &= ~(1 << DS18B20_DQ); //low
|
||||
DS18B20_DDR |= (1 << DS18B20_DQ); //output
|
||||
_delay_us(1);
|
||||
|
||||
//if we want to write 1, release the line (if not will keep low)
|
||||
if (bit)
|
||||
DS18B20_DDR &= ~(1 << DS18B20_DQ); //input
|
||||
|
||||
//wait 60uS and release the line
|
||||
_delay_us(60);
|
||||
DS18B20_DDR &= ~(1 << DS18B20_DQ); //input
|
||||
}
|
||||
|
||||
/*
|
||||
* read one bit
|
||||
*/
|
||||
uint8_t ds18b20_readbit(void)
|
||||
{
|
||||
uint8_t bit = 0;
|
||||
|
||||
//low for 1uS
|
||||
DS18B20_PORT &= ~(1 << DS18B20_DQ); //low
|
||||
DS18B20_DDR |= (1 << DS18B20_DQ); //output
|
||||
_delay_us(1);
|
||||
|
||||
//release line and wait for 14uS
|
||||
DS18B20_DDR &= ~(1 << DS18B20_DQ); //input
|
||||
_delay_us(14);
|
||||
|
||||
//read the value
|
||||
if (DS18B20_PIN & (1 << DS18B20_DQ))
|
||||
bit = 1;
|
||||
|
||||
//wait 45uS and return read value
|
||||
_delay_us(45);
|
||||
return bit;
|
||||
}
|
||||
|
||||
/*
|
||||
* write one byte
|
||||
*/
|
||||
void ds18b20_writebyte(uint8_t byte)
|
||||
{
|
||||
uint8_t i = 8;
|
||||
while (i--) {
|
||||
ds18b20_writebit(byte & 1);
|
||||
byte >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* read one byte
|
||||
*/
|
||||
uint8_t ds18b20_readbyte(void)
|
||||
{
|
||||
uint8_t i = 8, n = 0;
|
||||
while (i--) {
|
||||
n >>= 1;
|
||||
n |= (ds18b20_readbit() << 7);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* get temperature
|
||||
*/
|
||||
double ds18b20_gettemp()
|
||||
{
|
||||
uint8_t temperature_l;
|
||||
uint8_t temperature_h;
|
||||
double retd = 0;
|
||||
|
||||
#if DS18B20_STOPINTERRUPTONREAD == 1
|
||||
cli();
|
||||
#endif
|
||||
|
||||
ds18b20_reset(); //reset
|
||||
ds18b20_writebyte(DS18B20_CMD_SKIPROM); //skip ROM
|
||||
ds18b20_writebyte(DS18B20_CMD_CONVERTTEMP); //start temperature conversion
|
||||
|
||||
while (!ds18b20_readbit()); //wait until conversion is complete
|
||||
|
||||
ds18b20_reset(); //reset
|
||||
ds18b20_writebyte(DS18B20_CMD_SKIPROM); //skip ROM
|
||||
ds18b20_writebyte(DS18B20_CMD_RSCRATCHPAD); //read scratchpad
|
||||
|
||||
//read 2 byte from scratchpad
|
||||
temperature_l = ds18b20_readbyte();
|
||||
temperature_h = ds18b20_readbyte();
|
||||
|
||||
#if DS18B20_STOPINTERRUPTONREAD == 1
|
||||
sei();
|
||||
#endif
|
||||
|
||||
//convert the 12 bit value obtained
|
||||
retd = ((temperature_h << 8) + temperature_l) * 0.0625;
|
||||
|
||||
return retd;
|
||||
}
|
9
src/led.c
Normal file
9
src/led.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include <avr/io.h>
|
||||
#include "common.h"
|
||||
#include "led.h"
|
||||
|
||||
void init_leds(void)
|
||||
{
|
||||
SET(LED_DDR, LED_1_BIT);
|
||||
SET(LED_DDR, LED_2_BIT);
|
||||
}
|
82
src/main.c
82
src/main.c
@ -1,36 +1,21 @@
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include "ds18b20.h"
|
||||
#include "temperature.h"
|
||||
#include "led.h"
|
||||
#include "servos.h"
|
||||
#include "sonar.h"
|
||||
#include "nrf24.h"
|
||||
#include "io.h"
|
||||
#include "main.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "debug.h"
|
||||
#endif /* DEBUG */
|
||||
|
||||
void init_pwm(void)
|
||||
{
|
||||
DDRB |= 1 << SERVO_L_PIN | 1 << SERVO_R_PIN;
|
||||
/* Phase Correct PWM; Set/clear on Compare Match when down/up-counting */
|
||||
TCCR1A |= 1 << WGM11 | 1 << COM1A1 | 1 << COM1B1;
|
||||
/* "Clear Timer on Compare match" mode; Prescaler = 1 */
|
||||
TCCR1B |= 1 << WGM12 | 1 << WGM13 | 1 << CS10;
|
||||
ICR1 = F_CPU / 50 - 1; // 50Hz required by servos
|
||||
}
|
||||
#ifndef F_CPU
|
||||
#define F_CPU 1000000UL
|
||||
#endif
|
||||
|
||||
void init_led(void)
|
||||
{
|
||||
DDRD |= 1 << LED_1;
|
||||
}
|
||||
|
||||
void init_adc(void)
|
||||
{
|
||||
ADCSRA |= 1 << ADPS0 | 1 << ADPS1; // Prescaler = 8 => ADC clock = 125Hz
|
||||
ADMUX |= 1 << REFS0; // AVcc with external cap as reference voltage
|
||||
ADCSRA |= 1 << ADEN | 1 << ADSC;
|
||||
}
|
||||
|
||||
void read_temp(void)
|
||||
{
|
||||
@ -39,61 +24,22 @@ void read_temp(void)
|
||||
sei();
|
||||
for (;;) {
|
||||
d = ds18b20_gettemp();
|
||||
if (d >= 21)
|
||||
SET(PORTD, LED_1);
|
||||
if (d >= 23)
|
||||
;
|
||||
else
|
||||
CLR(PORTD, LED_1);
|
||||
;
|
||||
|
||||
_delay_ms(500);
|
||||
}
|
||||
}
|
||||
|
||||
void run_servos(void)
|
||||
{
|
||||
/* Stop */
|
||||
SERVO_L = 1500;
|
||||
SERVO_R = 1500;
|
||||
_delay_ms(1500);
|
||||
|
||||
/* Reverse */
|
||||
SERVO_L = 2000;
|
||||
SERVO_R = 2000;
|
||||
_delay_ms(1500);
|
||||
|
||||
/* Forwards */
|
||||
SERVO_L = 1000;
|
||||
SERVO_R = 1000;
|
||||
_delay_ms(1500);
|
||||
}
|
||||
|
||||
uint16_t read_adc(uint8_t channel)
|
||||
{
|
||||
ADMUX &= 0xF0;
|
||||
ADMUX |= channel;
|
||||
SET(ADCSRA, ADSC); // Start conversion
|
||||
while (CHK(ADCSRA, ADSC)); // Wait for conversion to finish
|
||||
|
||||
return ADCW;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint16_t adc_val;
|
||||
init_leds();
|
||||
init_servos();
|
||||
|
||||
init_led();
|
||||
init_pwm();
|
||||
init_adc();
|
||||
|
||||
while (1) {
|
||||
adc_val = read_adc(0);
|
||||
if (adc_val <= 512) {
|
||||
SERVO_R = 2000;
|
||||
SERVO_L = 2000;
|
||||
} else {
|
||||
SERVO_R = 1000;
|
||||
SERVO_L = 1000;
|
||||
}
|
||||
}
|
||||
run_servos();
|
||||
read_temp();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -10,59 +10,56 @@
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#define set_bit(reg,bit) reg |= (1<<bit)
|
||||
#define clr_bit(reg,bit) reg &= ~(1<<bit)
|
||||
#define check_bit(reg,bit) (reg&(1<<bit))
|
||||
#include "common.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void nrf24_setupPins()
|
||||
{
|
||||
set_bit(DDRC, 0); // CE output
|
||||
set_bit(DDRC, 1); // CSN output
|
||||
set_bit(DDRC, 2); // SCK output
|
||||
set_bit(DDRC, 3); // MOSI output
|
||||
clr_bit(DDRC, 4); // MISO input
|
||||
SET(DDRC, 0); // CE output
|
||||
SET(DDRC, 1); // CSN output
|
||||
SET(DDRC, 2); // SCK output
|
||||
SET(DDRC, 3); // MOSI output
|
||||
CLR(DDRC, 4); // MISO input
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void nrf24_ce_digitalWrite(uint8_t state)
|
||||
{
|
||||
if (state) {
|
||||
set_bit(PORTC, 0);
|
||||
SET(PORTC, 0);
|
||||
} else {
|
||||
clr_bit(PORTC, 0);
|
||||
CLR(PORTC, 0);
|
||||
}
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void nrf24_csn_digitalWrite(uint8_t state)
|
||||
{
|
||||
if (state) {
|
||||
set_bit(PORTC, 1);
|
||||
SET(PORTC, 1);
|
||||
} else {
|
||||
clr_bit(PORTC, 1);
|
||||
CLR(PORTC, 1);
|
||||
}
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void nrf24_sck_digitalWrite(uint8_t state)
|
||||
{
|
||||
if (state) {
|
||||
set_bit(PORTC, 2);
|
||||
SET(PORTC, 2);
|
||||
} else {
|
||||
clr_bit(PORTC, 2);
|
||||
CLR(PORTC, 2);
|
||||
}
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
void nrf24_mosi_digitalWrite(uint8_t state)
|
||||
{
|
||||
if (state) {
|
||||
set_bit(PORTC, 3);
|
||||
SET(PORTC, 3);
|
||||
} else {
|
||||
clr_bit(PORTC, 3);
|
||||
CLR(PORTC, 3);
|
||||
}
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
uint8_t nrf24_miso_digitalRead()
|
||||
{
|
||||
return check_bit(PINC, 4);
|
||||
return CHK(PINC, 4);
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
28
src/servos.c
Normal file
28
src/servos.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include "common.h"
|
||||
#include "servos.h"
|
||||
|
||||
void init_servos(void)
|
||||
{
|
||||
SET(SERVO_DDR, SERVO_L_BIT);
|
||||
SET(SERVO_DDR, SERVO_R_BIT);
|
||||
|
||||
SET(TCCR0A, COM0A1); // Clear OC0A on Compare Match, set OC0A at BOTTOM
|
||||
SET(TCCR0A, COM0B1); // Clear OC0B on Compare Match, set OC0B at BOTTOM
|
||||
|
||||
// Fast PWM, 0xFF TOP
|
||||
SET(TCCR0A, WGM00);
|
||||
SET(TCCR0A, WGM01);
|
||||
|
||||
// Prescaler. clkPWM = clkIO / 64
|
||||
SET(TCCR0B, CS00);
|
||||
SET(TCCR0B, CS01);
|
||||
}
|
||||
|
||||
void run_servos(void)
|
||||
{
|
||||
SERVO_L_REG = US2TIMER0(SERVO_MAX);
|
||||
SERVO_R_REG = US2TIMER0(SERVO_MID);
|
||||
_delay_ms(10000); // 10s
|
||||
}
|
61
src/sonar.c
Normal file
61
src/sonar.c
Normal file
@ -0,0 +1,61 @@
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include "sonar.h"
|
||||
|
||||
volatile uint32_t overflow_counter = 0;
|
||||
volatile uint32_t trig_counter = 0;
|
||||
volatile uint32_t no_of_cycles = 0;
|
||||
|
||||
void init_sonar()
|
||||
{
|
||||
TRIG_OUTPUT_MODE();
|
||||
ECHO_INPUT_MODE();
|
||||
}
|
||||
|
||||
void trigger_sonar()
|
||||
{
|
||||
TRIG_LOW();
|
||||
_delay_us(1);
|
||||
TRIG_HIGH();
|
||||
_delay_us(12);
|
||||
TRIG_LOW();
|
||||
_delay_us(1);
|
||||
}
|
||||
|
||||
ISR(TIMER1_OVF_vect)
|
||||
{
|
||||
++overflow_counter;
|
||||
TCNT1 = 0;
|
||||
}
|
||||
|
||||
unsigned int read_sonar()
|
||||
{
|
||||
int dist_in_cm = 0;
|
||||
init_sonar();
|
||||
trigger_sonar();
|
||||
|
||||
// While echo pin is low
|
||||
while (!(CHK(ECHO_PIN, ECHO_BIT))) {
|
||||
if (++trig_counter > SONAR_TIMEOUT)
|
||||
return TRIG_ERROR; // Received no response from echo
|
||||
}
|
||||
|
||||
TCNT1 = 0;
|
||||
TCCR1B |= (1 << CS10);
|
||||
TIMSK1 |= (1 << TOIE1);
|
||||
overflow_counter = 0;
|
||||
sei();
|
||||
|
||||
// While echo pin is high
|
||||
while (CHK(ECHO_PIN, ECHO_BIT)) {
|
||||
if (((overflow_counter * TIMER_MAX) + TCNT1) > SONAR_TIMEOUT)
|
||||
return ECHO_ERROR; // No echo within sonar range
|
||||
}
|
||||
|
||||
TCCR1B = 0x00;
|
||||
cli();
|
||||
no_of_cycles = ((overflow_counter * TIMER_MAX) + TCNT1);
|
||||
dist_in_cm = (no_of_cycles / (US_PER_CM * CYCLES_PER_US));
|
||||
|
||||
return dist_in_cm;
|
||||
}
|
144
src/temperature.c
Normal file
144
src/temperature.c
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
ds18b20 lib 0x02
|
||||
|
||||
copyright (c) Davide Gironi, 2012
|
||||
|
||||
Released under GPLv3.
|
||||
Please refer to LICENSE file for licensing information.
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include "common.h"
|
||||
#include "temperature.h"
|
||||
|
||||
/*
|
||||
* ds18b20 init
|
||||
*/
|
||||
uint8_t ds18b20_reset()
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
// low for 480us
|
||||
CLR(DS18B20_PORT, DS18B20_BIT);
|
||||
SET(DS18B20_DDR, DS18B20_BIT);
|
||||
_delay_us(480);
|
||||
|
||||
// release line and wait for 60uS
|
||||
CLR(DS18B20_DDR, DS18B20_BIT);
|
||||
_delay_us(60);
|
||||
|
||||
// get value and wait 420us
|
||||
i = CHK(DS18B20_PIN, DS18B20_BIT);
|
||||
_delay_us(420);
|
||||
|
||||
// return the read value, 0=ok, 1=error
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* write one bit
|
||||
*/
|
||||
void ds18b20_writebit(uint8_t bit)
|
||||
{
|
||||
// low for 1uS
|
||||
CLR(DS18B20_PORT, DS18B20_BIT);
|
||||
SET(DS18B20_DDR, DS18B20_BIT);
|
||||
_delay_us(1);
|
||||
|
||||
// if we want to write 1, release the line (if not will keep low)
|
||||
if (bit)
|
||||
CLR(DS18B20_DDR, DS18B20_BIT);
|
||||
|
||||
// wait 60uS and release the line
|
||||
_delay_us(60);
|
||||
DS18B20_DDR &= ~(1 << DS18B20_BIT);
|
||||
}
|
||||
|
||||
/*
|
||||
* read one bit
|
||||
*/
|
||||
uint8_t ds18b20_readbit(void)
|
||||
{
|
||||
uint8_t bit = 0;
|
||||
|
||||
// low for 1uS
|
||||
CLR(DS18B20_PORT, DS18B20_BIT);
|
||||
SET(DS18B20_DDR, DS18B20_BIT);
|
||||
_delay_us(1);
|
||||
|
||||
// release line and wait for 14uS
|
||||
CLR(DS18B20_DDR, DS18B20_BIT);
|
||||
_delay_us(14);
|
||||
|
||||
// read the value
|
||||
if (CHK(DS18B20_PIN, DS18B20_BIT))
|
||||
bit = 1;
|
||||
|
||||
// wait 45uS and return read value
|
||||
_delay_us(45);
|
||||
return bit;
|
||||
}
|
||||
|
||||
/*
|
||||
* write one byte
|
||||
*/
|
||||
void ds18b20_writebyte(uint8_t byte)
|
||||
{
|
||||
uint8_t i = 8;
|
||||
while (i--) {
|
||||
ds18b20_writebit(byte & 1);
|
||||
byte >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* read one byte
|
||||
*/
|
||||
uint8_t ds18b20_readbyte(void)
|
||||
{
|
||||
uint8_t i = 8, n = 0;
|
||||
while (i--) {
|
||||
n >>= 1;
|
||||
n |= (ds18b20_readbit() << 7);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* get temperature
|
||||
*/
|
||||
double ds18b20_gettemp()
|
||||
{
|
||||
uint8_t temperature_l;
|
||||
uint8_t temperature_h;
|
||||
double retd = 0;
|
||||
|
||||
#if DS18B20_STOPINTERRUPTONREAD == 1
|
||||
cli();
|
||||
#endif
|
||||
|
||||
ds18b20_reset(); // reset
|
||||
ds18b20_writebyte(DS18B20_CMD_SKIPROM); // skip ROM
|
||||
ds18b20_writebyte(DS18B20_CMD_CONVERTTEMP); // start temperature conversion
|
||||
|
||||
while (!ds18b20_readbit()); // wait until conversion is complete
|
||||
|
||||
ds18b20_reset(); // reset
|
||||
ds18b20_writebyte(DS18B20_CMD_SKIPROM); // skip ROM
|
||||
ds18b20_writebyte(DS18B20_CMD_RSCRATCHPAD); // read scratchpad
|
||||
|
||||
// read 2 byte from scratchpad
|
||||
temperature_l = ds18b20_readbyte();
|
||||
temperature_h = ds18b20_readbyte();
|
||||
|
||||
#if DS18B20_STOPINTERRUPTONREAD == 1
|
||||
sei();
|
||||
#endif
|
||||
|
||||
// convert the 12 bit value obtained
|
||||
retd = ((temperature_h << 8) + temperature_l) * 0.0625;
|
||||
|
||||
return retd;
|
||||
}
|
Loading…
Reference in New Issue
Block a user