Czy zawił bit C ?

To forum jest dla wszystkich pasjonatów wiecznie młodych mikrokontrolerów '51. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
Badman
-
Posty: 36
Rejestracja: 12 sty 2010, 13:07
Lokalizacja: Góra

Czy zawił bit C ?

Post autor: Badman » 25 sty 2011, 14:30

Do pomiaru temperatury używam termometr cyfrowy DS1820, który jest podłączony do Pin 3.5 uC AT89C2051. Natomiast wyświetlanie odbywa się na podwójnym wyświetlaczu o wspólnych anodach, które sterowane są poprzez 2 trazystory NPN. Bazy tych trazystorów poprzez rezystory podpięte do P3.0 i P3.1. Katodami wyświetlaczy steruje 74LS47, a on jest wysterowany przez:

P1.7 -> A0
P1.6 -> A1
P1.5 -> A2
P1.4 -> A3

Główny kod wygląda tak:

Kod: Zaznacz cały

wire equ P3.5
Led1 equ P3.0
Led2 equ P3.1

brak_urzadzen_1_wire equ 20h
tmp equ 21h

DL1 equ 50h
DL2 equ 51h

starszy_bajt equ 52h
mlodszy_bajt equ 53h
ulamkowa equ 54h
calkowita equ 55h

sek equ 56h
   
   org 0h
   ljmp start
   
   org 0Bh
przerwanieT0:
   mov TH0, #0ECh ; zaladowanie licznika
   mov TL0, #78h
   
   push Acc
   inc R3
   cjne R3, #200, skok
   mov R3, #0
   inc sek
   setb tmp
skok:
    
   cjne R1, #52h, spr
   mov R1, #50h ; jezeli R1 = 52h -> R1=50h
spr:
   mov Acc, R1
   mov R7, #1h ; P3.0=1, P3.1=0 
   jnb Acc.0, pokaz
   mov R7, #2h ; P3.0=0, P3.1=1
pokaz:
     mov A, P3
     orl A, #3h ; ustawienie 2 mlodszych _bitow P1 potzrebnych do wylaczenia DL1 i DL2
     mov P3, A
     mov P1, @R1
     mov A, P3
     xrl A, R7 ; ustawienie 2 mlodszych _bitow P1 potrzebnych do odpowiedniego wysterowania DL1 i DL2
     mov P3, A
     pop Acc
     inc R1
   reti
   
start:
    mov R1, #50h ; ustawienie komorki pamieci 50h, czyli na DL1
    clr TR0 ; zatrzymanie licznika T0
    mov TMOD,#01h ; T0 jako 16-bitowy

    mov TH0, #0ECh ; zaladowanie licznika
    mov TL0, #78h
    setb ET0 ; odblokowanie przerwania od T0
    setb PT0 ; priorytet na toprzerwanie
    setb EA ; wlaczenie przerwan 
    mov DL2, #0
    mov DL1, #0
    setb TR0 ; wlaczenie licznika T0
    setb tmp;
  
loop: ; glowne petla programu
    jbc tmp, dalej
   ;sjmp loop
dalej:
    lcall Init_1_Wire
    mov A,#0CCh
  lcall Zapisz_Bajt_1_Wire
  mov A,#044h
  lcall Zapisz_Bajt_1_Wire
  mov B,#0
  lcall opoznienie
  mov B,#0
  lcall opoznienie
  lcall init_1_wire
  
  mov A,#0CCh
  lcall Zapisz_Bajt_1_Wire
  mov A,#0BEh
  lcall Zapisz_Bajt_1_Wire
  
  
  lcall Czytaj_Bajt_1_Wire ; wczytanie LSB
  mov mlodszy_bajt,A
  
  lcall Czytaj_Bajt_1_Wire ; wczytanie MSB
  lcall Init_1_Wire
  mov starszy_bajt,A
  
  mov A, starszy_bajt
  mov R0, #mlodszy_bajt 
  xchd A,@R0
  mov ulamkowa, A
  
  mov A, @R0
  swap A
  mov calkowita, A
  
    acall Hex2Dec
  
    mov R2,#0
    mov R4, #1
  ;  sjmp loop
petla:    
    mov B, #0
    acall Opoznienie
    djnz R2, petla
    djnz R4, petla
   
stop: sjmp loop

Opoznienie: 
  djnz B, Opoznienie ; 2us * B
  ret
  
Hex2Dec: ; w A dziesiatki, w B jednosci. Niszczy A i B
  push B
  mov B, #10
  div AB
  swap A
  mov DL1, A
  mov A, B
  pop B
  swap A
  mov DL2, A
  ret
  

$INCLUDE  (X:\kod\lib\1wire.a51)  
  END

  
Kod do obsługi 1wire:

Kod: Zaznacz cały

Init_1_Wire:
  clr wire
  mov B,#0
  lcall Opoznienie
  setb wire
  mov B,#30
  lcall Opoznienie
  mov C,wire
  mov brak_urzadzen_1_wire,C
  lcall Opoznienie
  ret
  
RD_Wire_Bit:
  clr wire
  setb wire
  mov B,#5
  nop
  lcall Opoznienie
  mov C,wire
  mov B,#60
  lcall Opoznienie
  ret

Czytaj_Bajt_1_Wire:
  mov R6,#8
czytaj_kolejny_bit:
  lcall RD_Wire_Bit
  rrc A
  djnz R6,czytaj_kolejny_bit
  ret
  
  
WR_Wire_Bit:
  mov B, #1
  cpl C  
  
  ;mov B.5, C
  
  orl B, #100000b
  jc wr_nie_zero
  anl B, #11011111b
   
Wr_Nie_Zero:
  clr wire
  lcall Opoznienie
  setb wire
  jnc Wire_1
  ret
  
Wire_1:
  mov B, #30
  lcall Opoznienie
  ret
  
Zapisz_Bajt_1_Wire:
  mov R6, #8  
zapisz_kolejny_bit:
  rrc A
  lcall WR_Wire_Bit
  djnz R6, zapisz_kolejny_bit
  ret
Kiedy robię odczyt co sekunde wydaje się być ok, na wyświetlaczy nie pojawiają się stany pośrednie. Kiedy opóźnienie wykonywane jest poprzez skoki do "petla" mam na wyświetlacz chwilę dziwne liczby.
Domyślam się procedury do 1wire używają C, a w procedurze przerwania jest polecenie cjne, które ustawia C.
Zgadłem ? :)

PS. Układ zrobiony na uniwersalnej płytce stykowej - pająk. Dodatkowo jak włącze zasilanie przy zczytywaniu 1 sekundowym mam wyświetloną wartość 85 i po chwili (pewnie po 1 sek) jest już ok.

keruseykaryu

Post autor: keruseykaryu » 25 sty 2011, 18:35

Dodaj do przerwania PUSH PSW i na koniec POP PSW. To znaczniki się zachowają.

Kod: Zaznacz cały

   org 0Bh 
przerwanieT0: 
   push Psw
   mov TH0, #0ECh ; zaladowanie licznika 
   mov TL0, #78h 
    
   <cięcie>

     mov P3, A 
     pop Acc 
     inc R1 

     pop Psw
   reti

ODPOWIEDZ