[ yurke_pzs @ 19.07.2010. 20:55 ] @
Problem je u sledecem...radim neki projekat za fax...regulacija temperature...imam dva ds1820 senzora (one-wire komunikacija)...programiram u CodeVision-u. On ima gotove f-je za ovaj senzor. Meni su konkretno problem ova f-je:

sp_temp=ds1820_temperature_10(&ds1820_rom_codes[0][0]);
un_temp=ds1820_temperature_10(&ds1820_rom_codes[1][0]);

sve ok radi i meri dobro temperature na oba. medjutim uC-u treba dosta vremena da odradi ove dve f-je sto mi se odrazava na ostatak programa. imam recimo dva tastera koji treba da povecavaju ili smanjuju vrednost zeljene temp, medjutim njih moram da drzim oko 1sec da bi doslo do promene. Zna li neko kako da resim problem??? Koristim kristal od 8MHz. palo mi je na pamet da postavim tajmer koji ce recimo na svakih 30sec da poziva ove f-je ali mi je to malo budž metoda.


hvala svima koji su voljni da pomognu
[ branko_g @ 20.07.2010. 11:59 ] @
Pokaži kod, možda se može nešto optimizovati. Inače 1sekunda za funkciju je ipak mnogo, sa mnogo manjom računarskom snagom su ljudi otišli na mesec.
Inače pogledaj i ovo:
http://gandalf.arubi.uni-kl.de/avr_projects/tempsensor/index.html

P.S. CodeVision je dobra stvar ali samo na prvi pogled. Probaj ipak neki novi projekat sa WinAVR.
[ yurke_pzs @ 20.07.2010. 12:43 ] @
/*****************************************************
This program was produced by the
CodeWizardAVR V1.24.6 Standard
Automatic Program Generator
© Copyright 1998-2005 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
e-mail:[email protected]

Project : Primena senzora i aktuatora
Version :
Date : 19.7.2010
Author : Milos
Company : Jurosevic
Comments:


Chip type : ATmega16
Program type : Application
Clock frequency : 8,000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256
*****************************************************/

#include <mega16.h>
#include <stdio.h>

// 1 Wire Bus functions
#asm
.equ __w1_port=0x1B ;PORTA
.equ __w1_bit=0
#endasm
#include <1wire.h>

// DS1820 Temperature Sensor functions
#include <ds1820.h>

// maximum number of DS1820 devices
// connected to the 1 Wire bus
#define MAX_DS1820 8
// number of DS1820 devices
// connected to the 1 Wire bus
unsigned char ds1820_devices, i, j;
// DS1820 devices ROM code storage area,
// 9 bytes are used for each device
// (see the w1_search function description in the help)
unsigned char ds1820_rom_codes[MAX_DS1820][9];

// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>


// Declare your global variables here

#define set_dana PIND.0
#define temp_plus PIND.1
#define temp_minus PIND.2
#define grejac PORTC.0
#define provetravanje PORTC.1

int sp_temp; //spoljasnja temperatura
int un_temp; //unutrasnja temperatura

void main(void)
{
// Declare your local variables here

bit promenap, promenam, promenad, set_br_dana, grejanje;
int br_dana, donji_prag, gornji_prag, histerezis, podesena_temp;
char lcd_buffer[33];

// Determine the number of DS1820 devices
// connected to the 1 Wire bus
ds1820_devices=w1_search(0xf0,ds1820_rom_codes);

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0xFF;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;


// LCD module initialization
lcd_init(16);
lcd_clear();

promenap=0;
promenam=0;
promenad=0;
br_dana=20;
set_br_dana=0;
podesena_temp=300;
histerezis=10;

lcd_gotoxy(3,0);
lcd_putsf("Inkubacija");

while(!set_br_dana){
if (temp_plus && !promenap) {
if(br_dana<40)
{
br_dana=br_dana+1;
}
promenap = 1; // Update flag
}
if (!temp_plus)
{
promenap=0;
}

if (temp_minus && !promenam) {
if(br_dana>10){
br_dana=br_dana-1;
}
promenam = 1;
}

if (!temp_minus)
{
promenam=0;
}

if (set_dana && !promenad) {
set_br_dana=1;
promenad=1;
TCCR1B=4;
}

if (!set_dana)
{
promenad=0;
}

if (br_dana==21 || br_dana==31)
{
lcd_gotoxy(7,1);
lcd_putsf(" dan ");
}else{
lcd_gotoxy(7,1);
lcd_putsf(" dana");
}
lcd_gotoxy(5,1);
sprintf(lcd_buffer, "%i",br_dana);
lcd_puts(lcd_buffer);
}

lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Trenutna:");
lcd_gotoxy(15,0);
lcd_putsf("C");
lcd_gotoxy(0,1);
lcd_putsf("Zeljena:");
lcd_gotoxy(15,1);
lcd_putsf("C");

while (1)
{
// Place your code here

gornji_prag=podesena_temp+histerezis;
donji_prag=podesena_temp-histerezis;

if (temp_plus && !promenap) {
if(podesena_temp<800)
{
podesena_temp=podesena_temp+5;
}
promenap = 1; // Update flag
}
if (!temp_plus)
{
promenap=0;
}

if (temp_minus && !promenam) {
if(podesena_temp>150)
{
podesena_temp=podesena_temp-5;
}
promenam = 1;
}

if (!temp_minus)
{
promenam=0;
}

sprintf(lcd_buffer, "%i.%u\xb2",podesena_temp/10,podesena_temp%10);
lcd_gotoxy(10,1);
lcd_puts(lcd_buffer);

sp_temp=ds1820_temperature_10(&ds1820_rom_codes[0][0]);
un_temp=ds1820_temperature_10(&ds1820_rom_codes[1][0]);

sprintf(lcd_buffer,"%i.%u\xb2",un_temp/10, un_temp%10);
lcd_gotoxy(10,0);
lcd_puts(lcd_buffer);

if(un_temp<=donji_prag && !provetravanje)
{
grejac=1;
grejanje=1;
}else if((un_temp>donji_prag)&&(un_temp<=gornji_prag)){
if((un_temp<=gornji_prag)&&(grejanje))
{
grejac=1;
grejanje=1;
}else{
grejac=0;
grejanje=0;
}
}else{
grejac=0;
grejanje=0;
}

};
}
[ branko_g @ 20.07.2010. 14:24 ] @
Ako nisi menjao fusebits onda ti ATmega radi još uvek sa 1MHz internim oscilatorom(fabrički podešen).
Pogledaj Datasheet i to poglavlje o oscilatorima pa ćeš videti kako se menja oscilator.

A što se tiče programeskog stila, probaj da umesto ugnježdenih if-if-elseif koristiš "automat stanja" sa switch-case strukturom.
Preglednost programa će biti daleko bolja, a i samo dodavanje novih stanja i reagovanje na događaje će biti lakše shvatljivo.
Pogledaj uostalom primer pod "Forum-> Mikrokontroleri-> Atmel AVR za početnike" na www.automatika.rs
Možda će ti to pomoći.

[Ovu poruku je menjao branko_g dana 20.07.2010. u 16:19 GMT+1]
[ milanmeh @ 20.07.2010. 17:29 ] @
Ja sam se sreo sa ovim problemom i mogu ti odmah reci da se uzrok nalazi u ugradjenoj biblioteci za DS1820.

Kada mega16 izda zahtev za citanje temperature potrebno je oko 600 do 700 ms da DS1820 ocita temperaturu, uradi sve potrebne operacije i postavi rezultat na scratch pad. Ovo vreme cekanja se u ugradjenoj biblioteci realizuje preko funkcije praznog cekanja, delay_ms(), i to prakticno znaci da za tih 600ms (sto je OGROMNO vreme za mikrokontroler) mega16 nece raditi apsolutno nista. Sreca je sto je ugradjena biblioteka od DS1820 otvorena i mozes da je izmenis. Moj predlog je da rasparcas funkciju citanja sa senzora na takav nacin da izbegnes koriscenje delay_ms() funkcije, i umesto nje napravis svoje kasnjenje. Za to najbolje da koristis timer sa interruptom. To bi izgledalo ovako nekako:

pozivas prvi deo funkicje, da bude sve do poziva za delay_ms()

umesto delay_ms(), startujes timer0

timer0 postavis tako da ti broji do odredjene vrednosti koja odgovara tom kasnjenju od 600-700ms, po isteku tog vremena postavljas neki flag, recimo RESUME=1;

pozivas drugu polovinu funkcije citanja DS1820, posle delay_ms(), ali samo ako je RESUME=1;

kada ocitas temperaturu postavis RESUME=0 i ceo sistem ceka sledecu naredbu za pocetak citanje temperature

Code:

READ_TEMP1();
if(RESUME==1){
READ_TEMP2();
RESUME=0;
}