|
|
Elektronika.lt portalo forumas
Jūs esate neprisijungęs lankytojas. Norint dalyvauti diskusijose, būtina užsiregistruoti ir prisijungti prie forumo.
Prisijungę galėsite kurti naujas temas, atsakyti į kitų užduotus klausimus, balsuoti forumo apklausose.
Administracija pasilieka teisę pašalinti pasisakymus bei dalyvius,
kurie nesilaiko forumo taisyklių.
Pastebėjus nusižengimus, prašome pranešti.
Dabar yra 2024 12 28, 09:00. Visos datos yra GMT + 2 valandos.
|
|
|
|
Forumas » Mikrovaldikliai » Atmega8 + ds18b20
|
Jūs negalite rašyti naujų pranešimų į šį forumą Jūs negalite atsakinėti į pranešimus šiame forume Jūs negalite redaguoti savo pranešimų šiame forume Jūs negalite ištrinti savo pranešimų šiame forume Jūs negalite dalyvauti apklausose šiame forume
|
|
|
|
|
|
Atmega8 + ds18b20 |
Parašytas: 2013 12 28, 16:23 |
|
|
|
Sveiki, esu naujokas elektronikoje... Susidūriau su bėda jungdamas temperatūros sensorių prie mikrovaldiklio.
Simuliacijos programoje tikrinant schemą gaunu labai daug klaidų:
http://www.part.lt/img/d28f3e693ec8092ac0398ce60a65c6f4306.png
Galbūt kas padėtų?
main.c
Kodas: |
#include <avr/io.h>
#include <stdio.h>
#include "lcd.h"
#include "tsensorius.h"
char temp[4];
int main(void)
{
int i=0;
//DDRB |= 1;
InitLCD(LS_BLINK|LS_ULINE);
LCDClear();
LCDWriteStringXY(0,0,"Lauko");
LCDWriteStringXY(8,0,"Variklio");
//LCDWriteStringXY(1,1,"26 C");
//LCDWriteStringXY(11,1,"78 C");
while(1)
{
i = (i+1)%10;
char x[4]={0};
therm_read_temperature(x);
sprintf(temp,"%s",x);
LCDWriteStringXY(1,1,temp);
}
} |
tsensorius.h
Kodas: |
#include <avr/io.h>
#include <stdio.h>
#ifndef F_CPU
#define F_CPU 3000000UL //Your clock speed in Hz (3Mhz here)
#endif
#define LOOP_CYCLES 8 //Number of cycles that the loop takes
#define us(num) (num/(LOOP_CYCLES*(1/(F_CPU/1000000.0))))
#define THERM_PORT PORTB
#define THERM_DDR DDRB
#define THERM_PIN PINB
#define THERM_DQ PB5
/* Utils */
#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)
/* list of these commands translated into C defines:*/
#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
/* constants */
#define THERM_DECIMAL_STEPS_12BIT 625 //.0625
void therm_delay(uint16_t delay);
uint8_t therm_reset();
void therm_write_bit(uint8_t bit);
uint8_t therm_read_bit(void);
uint8_t therm_read_byte(void);
void therm_write_byte(uint8_t byte);
//
void therm_read_temperature(char *buffer);
void therm_read_temperature2(int8_t *digi, uint16_t *deci);
|
tsensorius.c
Kodas: |
#include "tsensorius.h"
void therm_delay(uint16_t delay)
{
while(delay--) asm volatile("nop");
}
uint8_t therm_reset()
{
uint8_t i;
//Pull line low and wait for 480uS
THERM_LOW();
THERM_OUTPUT_MODE();
therm_delay(us(480));
//Release line and wait for 60uS
THERM_INPUT_MODE();
therm_delay(us(60));
//Store line value and wait until the completion of 480uS period
i=(THERM_PIN & (1<<THERM_DQ));
therm_delay(us(420));
//Return the value read from the presence pulse (0=OK, 1=WRONG)
return i;
}
void therm_write_bit(uint8_t bit)
{
//Pull line low for 1uS
THERM_LOW();
THERM_OUTPUT_MODE();
therm_delay(us(1));
//If we want to write 1, release the line (if not will keep low)
if(bit) THERM_INPUT_MODE();
//Wait for 60uS and release the line
therm_delay(us(60));
THERM_INPUT_MODE();
}
uint8_t therm_read_bit(void)
{
uint8_t bit=0;
//Pull line low for 1uS
THERM_LOW();
THERM_OUTPUT_MODE();
therm_delay(us(1));
//Release line and wait for 14uS
THERM_INPUT_MODE();
therm_delay(us(14));
//Read line value
if(THERM_PIN&(1<<THERM_DQ)) bit=1;
//Wait for 45uS to end and return read value
therm_delay(us(45));
return bit;
}
uint8_t therm_read_byte(void)
{
uint8_t i=8, n=0;
while(i--)
{
//Shift one position right and store read value
n>>=1;
n|=(therm_read_bit()<<7);
}
return n;
}
void therm_write_byte(uint8_t byte)
{
uint8_t i=8;
while(i--)
{
//Write actual bit and shift one position right to make the next bit ready
therm_write_bit(byte&1);
byte>>=1;
}
}
void therm_read_temperature(char *buffer)
{
// Buffer length must be at least 12bytes long! ["+XXX.XXXX C"]
uint8_t temperature[2];
int8_t digit;
uint16_t decimal;
//Reset, skip ROM and start temperature conversion
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
therm_write_byte(THERM_CMD_CONVERTTEMP);
//Wait until conversion is complete
while(!therm_read_bit());
//Reset, skip ROM and send command to read Scratchpad
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
therm_write_byte(THERM_CMD_RSCRATCHPAD);
//Read Scratchpad (only 2 first bytes)
temperature[0]=therm_read_byte();
temperature[1]=therm_read_byte();
therm_reset();
//Store temperature integer digits and decimal digits
digit=temperature[0]>>4;
digit|=(temperature[1]&0x7)<<4;
//Store decimal digits
decimal=temperature[0]&0xf;
decimal*=THERM_DECIMAL_STEPS_12BIT;
//Format temperature into a string [+XXX.XXXX C]
sprintf(buffer, "%+d.%04u C", digit, decimal);
}
void therm_read_temperature2(int8_t *digi, uint16_t *deci)
{
// Buffer length must be at least 12bytes long! ["+XXX.XXXX C"]
uint8_t temperature[2];
int8_t digit;
uint16_t decimal;
//Reset, skip ROM and start temperature conversion
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
therm_write_byte(THERM_CMD_CONVERTTEMP);
//Wait until conversion is complete
while(!therm_read_bit());
//Reset, skip ROM and send command to read Scratchpad
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
therm_write_byte(THERM_CMD_RSCRATCHPAD);
//Read Scratchpad (only 2 first bytes)
temperature[0]=therm_read_byte();
temperature[1]=therm_read_byte();
therm_reset();
//Store temperature integer digits and decimal digits
digit=temperature[0]>>4;
digit|=(temperature[1]&0x7)<<4;
//Store decimal digits
decimal=temperature[0]&0xf;
decimal*=THERM_DECIMAL_STEPS_12BIT;
//results
*digi = digit;
*deci = decimal;
}
|
|
|
Paskutinį kartą redagavo maklas, 2013 12 28, 17:58. Redaguota 1 kartą |
|
|
|
|
|
Atmega8 + ds18b20 |
Parašytas: 2013 12 28, 17:44 |
|
|
|
tingiu visa ziureti koda, bet i main.c pradzioje irasyk tokias eilutes. Nes main.c faile nera nurodyta kokias bibliotekas naudosi
Kodas: |
#include <avr/io.h>
#include <stdio.h> |
|
|
_________________ Diplomas tik etikete ant konservų dėžutes. O kas slepiasi dėžutėje neaišku. |
|
|
|
|
Atmega8 + ds18b20 |
Parašytas: 2013 12 28, 17:59 |
|
|
|
pcwortex rašo: |
tingiu visa ziureti koda, bet i main.c pradzioje irasyk tokias eilutes. Nes main.c faile nera nurodyta kokias bibliotekas naudosi
Kodas: |
#include <avr/io.h>
#include <stdio.h> |
|
Pridėjau.
Gal kas galėtų peržiūrėti visą kodą? |
|
|
|
|
|
|
Atmega8 + ds18b20 |
Parašytas: 2013 12 28, 18:10 |
|
|
|
Nepaziurejau, tavo paveiksliuko. Tau kodas veikia. Maniau, kad neveikia. O kas ziures visa koda, tai man rodos cia nerasi tokiu zmoniu. turi aiskintis pats ir kas neaisku klausti. Bet kiek suprantu, tu susiradai koda, padarei copy paste ir viskas. Pirmiausia pradek nuo lempuciu junginejimu, o ne sok iskart ant protokolu.
maklas rašo: |
pcwortex rašo: |
tingiu visa ziureti koda, bet i main.c pradzioje irasyk tokias eilutes. Nes main.c faile nera nurodyta kokias bibliotekas naudosi
Kodas: |
#include <avr/io.h>
#include <stdio.h> |
|
Pridėjau.
Gal kas galėtų peržiūrėti visą kodą? |
|
|
_________________ Diplomas tik etikete ant konservų dėžutes. O kas slepiasi dėžutėje neaišku. |
|
|
|
|
|
Atmega8 + ds18b20 |
Parašytas: 2013 12 28, 20:47 |
|
|
|
pradekim nuo to, kad void therm_read_temperature(char *buffer); gali reiketi didesnio buferio nei 4 baitai, t.y. reikia iki 12 baitu // Buffer length must be at least 12bytes long! ["+XXX.XXXX C"]
gali pasinaudoti kita funkcija, kuri grazina sveikus skaicius void therm_read_temperature2(int8_t *digi, uint16_t *deci) sveikaja dali i uint8_t, bei po kablelio i uint16_t kintamuosius.
perduodant kintamuju adresus gali reiketi nurodyti &kintamasis, nes kintamieji proceduroje aprasyti adresu *kintamasis. |
|
|
|
|
|
|
Atmega8 + ds18b20 |
Parašytas: 2013 12 28, 21:52 |
|
|
|
Štai kodas:
Kodas: |
#include <avr/io.h>
#include <stdio.h>
#include "lcd.h"
#include "tsensorius.h"
int main(void)
{
InitLCD(LS_BLINK|LS_ULINE);
LCDClear();
LCDWriteStringXY(0,0,"Lauko");
while(1)
{
int8_t x;
uint16_t y;
char temp[10];
therm_read_temperature2(&x,&y);
sprintf(temp, "%i.%i", x, y);
LCDWriteStringXY(1,1,temp);
}
} |
Tačiau visada išvedama temperatūra: 127.9375
Kur padariau klaidą? |
|
|
|
|
|
Atmega8 + ds18b20 |
Parašytas: 2013 12 28, 22:50 |
|
|
|
tavo biblioteka nenaudoja INPUT_PULLUP mode, todel reikia DQ (PB5) per 4,7kom varza prijungti prie VCC
beje, jei laidas poilgis, tai PULLUP naudoti nepatartina. |
|
|
|
|
|
Atmega8 + ds18b20 |
Parašytas: 2013 12 28, 23:13 |
|
|
|
AlgisL rašo: |
tavo biblioteka nenaudoja INPUT_PULLUP mode, todel reikia DQ (PB5) per 4,7kom varza prijungti prie VCC
beje, jei laidas poilgis, tai PULLUP naudoti nepatartina. |
Ačiū tau, viskas sėkmingai veikia. |
|
|
|
|
|
|
|
Atmega8 + ds18b20 |
Parašytas: 2013 12 31, 10:06 |
|
|
|
Vienas daviklis veikia puikiai, tačiau kitas nuolat į LCD išveda -63C. Kur klaida?
Kodas: |
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include "lcd.h"
#include "1wire.h"
/*****************************************************************************\
|* Function prototypes
\*****************************************************************************/
int16_t ds18b20ReadTemperature(uint8_t bus, uint8_t * id);
/*****************************************************************************\
|* Defines for the temperature conversion
\*****************************************************************************/
#define DS18B20_FAMILY_ID 0x28
#define DS18B20_SKIP_ROM 0xcc
#define DS18B20_START_CONVERSION 0x44
#define DS18B20_READ_SCRATCHPAD 0xbe
#define DS18B20_WRITE_SCRATCHPAD 0x4e
#define DS18B20_COPY_SCRATCHPAD 0x48
#define DS18B20_ERROR -1000
/*****************************************************************************\
|* Make the 1-wire "bus" on pin-7 of port ONEWIRE_PORT (see 1wire.h)
\*****************************************************************************/
#define BUS ONEWIRE_PIN_0
#define BUS2 ONEWIRE_PIN_1
#define MAX_DEVICES 1
/*****************************************************************************\
|* Set up stdio
\*****************************************************************************/
uint8_t crap[7];
/*****************************************************************************\
|* Initialise the firmware - program entry point
\*****************************************************************************/
int main (void)
{
signed int temp = 0;
signed int temp2 = 0;
/*************************************************************************\
|* Set up the uart
\*************************************************************************/
InitLCD(LS_BLINK|LS_ULINE);
LCDClear();
LCDWriteStringXY(0,0,"Kraunama...");
/*************************************************************************\
|* Declare the devices and initialise
\*************************************************************************/
static oneWireDevice devices[MAX_DEVICES];
static oneWireDevice devices2[MAX_DEVICES];
oneWireDevice *ds18b20;
oneWireDevice *ds18b202;
oneWireInit(BUS);
oneWireInit(BUS2);
/*************************************************************************\
|* Search for and populate the devices until all CRC's are read correctly
\*************************************************************************/
LCDClear();
LCDWriteStringXY(0,0,"Ieskoma...");
while (oneWireSearchBuses(devices, MAX_DEVICES, BUS) != ONEWIRE_SEARCH_COMPLETE && oneWireSearchBuses(devices2, MAX_DEVICES, BUS2) != ONEWIRE_SEARCH_COMPLETE);
/*************************************************************************\
|* After device enumeration, find the temperature sensor
\*************************************************************************/
LCDClear();
LCDWriteStringXY(0,0,"Ieskomi davikliai...");
ds18b20 = oneWireFindFamily(DS18B20_FAMILY_ID, devices, MAX_DEVICES);
ds18b202 = oneWireFindFamily(DS18B20_FAMILY_ID, devices2, MAX_DEVICES);
/*************************************************************************\
|* Just print the temperature constantly
\*************************************************************************/
LCDClear();
LCDWriteStringXY(0,0,"Lauko");
LCDWriteStringXY(8,0,"Variklio");
while (1)
{
temp = ds18b20ReadTemperature(ds18b20->bus, ds18b20->id);
temp = (temp >> 4);
temp2 = ds18b20ReadTemperature(ds18b202->bus, ds18b202->id);
temp2 = (temp2 >> 4);
char a[6], b[6];
sprintf(a, "%i.0", temp);
LCDWriteStringXY(0,1,a);
sprintf(b, "%i.0", temp2);
LCDWriteStringXY(9,1,b);
}
}
/*****************************************************************************\
|* Read the temperature from an identified sensor
\*****************************************************************************/
int16_t ds18b20ReadTemperature(uint8_t bus, uint8_t * id)
{
int16_t temperature;
// Reset, presence.
if (!oneWireDetectPresence(bus))
return DS18B20_ERROR;
// Match the id found earlier.
oneWireMatchRom(id, bus);
//oneWireSendByte(DS18B20_SKIP_ROM, bus);
// Send start conversion command.
oneWireSendByte(DS18B20_START_CONVERSION, bus);
// Wait until conversion is finished.
// Bus line is held low until conversion is finished.
#ifdef ONEWIRE_USE_PARASITIC_POWER
ONEWIRE_RELEASE_BUS(bus);
_delay_ms(850);
#else
while (!oneWireReadBit(bus))
;
#endif
// Reset, presence.
if(!oneWireDetectPresence(bus))
return DS18B20_ERROR;
// Match id again.
oneWireMatchRom(id, bus);
//oneWireSendByte(DS18B20_SKIP_ROM, bus);
// Send READ SCRATCHPAD command.
oneWireSendByte(DS18B20_READ_SCRATCHPAD, bus);
// Read only two first bytes (temperature low, temperature high)
// and place them in the 16 bit temperature variable.
temperature = oneWireReceiveByte(bus);
temperature |= (oneWireReceiveByte(bus) << 8);
uint8_t i;
for(i=0; i<7; i++)
crap[i] = oneWireReceiveByte(bus);
return temperature;
}
|
|
|
|
|
|
|
|
Atmega8 + ds18b20 |
Parašytas: 2013 12 31, 15:36 |
|
|
|
Kodas: |
while (oneWireSearchBuses(devices, MAX_DEVICES, BUS) != ONEWIRE_SEARCH_COMPLETE && oneWireSearchBuses(devices2, MAX_DEVICES, BUS2) != ONEWIRE_SEARCH_COMPLETE); |
cia pasakai, kad kai nors viena davikli rado, kito ieskoti nebereikia
vietoje && naudok || arba davikliu ieskok paeiliui, paradzioje BUS, paskui BUS2
DS18x20x pasizymi tuom, kad juos keleta gali jungti lygiaigreciai prie to paties BUS'o
Kodas: |
#define MAX_DEVICES 2
while (oneWireSearchBuses(devices, MAX_DEVICES, BUS) != ONEWIRE_SEARCH_COMPLETE);
temp = ds18b20ReadTemperature(ds18b20[0]->bus, ds18b20[0]->id);
temp = (temp >> 4);
temp2 = ds18b20ReadTemperature(ds18b20[1]->bus, ds18b20[1]->id);
temp2 = (temp2 >> 4);
|
klaidu gali but del ivairiu dalyku, pvz: nepritempei prie +5V per varza, daviklis (ne)pajungtas ilgu neekranuotu laidu ir t.t. |
|
|
|
|
|
|
Google paieška forume |
|
|
Naujos temos forume |
|
|
FS25 Tractors
Farming Simulator 25 Mods,
FS25 Maps,
FS25 Trucks |
|
ETS2 Mods
ETS2 Trucks,
ETS2 Bus,
Euro Truck Simulator 2 Mods
|
|
FS22 Tractors
Farming Simulator 22 Mods,
FS22 Maps,
FS25 Mods |
|
VAT calculator
VAT number check,
What is VAT,
How much is VAT |
|
LEGO
Mänguköök,
mudelautod,
nukuvanker |
|
Thermal monocular
Thermal vision camera,
Night vision ar scope,
Night vision spotting scope |
|
FS25 Mods
FS25 Harvesters,
FS25 Tractors Mods,
FS25 Maps Mods |
|
Dantų protezavimas
All on 4 implantai,
Endodontija mikroskopu,
Dantų implantacija |
|
FS25 Mods
FS25 Maps,
FS25 Cheats,
FS25 Install Mods |
|
GTA 6 Weapons
GTA 6 Characters,
GTA 6 Map,
GTA 6 Vehicles |
|
FS25 Mods
Farming Simulator 25 Mods,
FS25 Maps |
|
ATS Trailers
American Truck Simulator Mods,
ATS Trucks,
ATS Maps |
|
|
|