Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Много проблеми с часовник и 16F873A
http://mcu-bg.com/mcu_site/viewtopic.php?f=7&t=5772
Страница 1 от 2

Автор:  wolfshark [ Чет Май 08, 2008 9:30 pm ]
Заглавие:  Много проблеми с часовник и 16F873A

Не знам вече от къде да започна :cry: Начинаещ съм. Искам да си направя LED часовник. Направих си платка, налепих 130 светодиода като ги подредих като обикновен 7-сегментен индикатор. Паднаха се по 3 светодиода на сегмент. Направих го със 6 индикатора - по два за час, минута, секунда. Свързах ги динамично и направих платката с NPN транзистори. Започват проблемите:
1. Светят слабо, предполагам това се дължи на факта че съответният сегмент е повече време изключен от колкото включен. Как мога да оправя това?
2. Когато са светнали по-малко сегменти (напр. числото 1) те светят по-силно от напр. числото 8
3. Микроконтролера просто забива и всичко седи 00:00:00 като го препрограмирам като че ли тръгва

Прикачвам сорса който сътворих. Това ми е първата програма, бъдете снисходителни. Базиран е на таймера от PIC Микроконтролери част I
Не разчитайте на коментарите, след няколко промени в програмата не им обърнах внимание и ги омазах.
Код:
   list   p=16F873A
   #include <p16F873A.inc>
   __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC & _LVP_OFF
;---Дефиниране---
w      EQU   0
f      EQU   1
Begin_value    EQU   D'176'

      CBLOCK    H'020'   ; Адрес на първия регистър от GPR
      Counter_s1
      Counter_s2
      Counter_m1
      Counter_m2
      Counter_h1
      Counter_h2
      Cycle_counter
      Cycle_counter2
      Temp_PORTC
      ENDC

;---Дефиниране битовете на регистъра Flag_register---
#define      Dig_s1      PORTC,0
#define      Dig_s2      PORTC,1
#define      Dig_m1      PORTC,2
#define      Dig_m2      PORTC,3
#define      Dig_h1      PORTC,4
#define      Dig_h2      PORTC,5
;-----------------------------------------------------
      ORG   H'0000'      ;Начално зареждане
      goto   start

      ORG   H'0004'      ;Прекъсване
      goto    Int_service
;----Инициализация----
start      bcf   STATUS,RP0   ;Избор на банка 0
      clrf   PORTC      ;Нулиране PORTC
      clrf   PORTB      ;Нулиране PORTB
      bsf   STATUS,RP0   ;Избор на банка 1
      movlw   B'11000000'   ;Дефиниране на входове-изходи
      movwf   TRISC
      clrf   TRISB
      bcf   STATUS,RP0
      goto   main   
;----Обслужване на прекъсванията----
Int_service   btfss   INTCON,T0IF   ; Прекъсване от TMR0?
      goto   end_int      ; Не, връщане от ISR
TMR0_int   movlw   Begin_value   ; Begin value > W
      movwf   TMR0      ; W > TMR0
      call   Inc_timer   ; Актуализиране на таймера
      call   Update_disp   ; Обновяване на индикаторите
end_int      bcf   INTCON,T0IF   ;Нулиране на T0IF и връщане към главната програма
      retfie
;----Актуализиране на дисплея----
Inc_timer   incf   Cycle_counter,w   ; W=(Cycle_counter)+1
      xorlw   D'200'      ; W XOR 200 -> W
      btfsc   STATUS,Z   ; W=200? (изтекла е 1сек)
      goto   Inc_timer2   ;
      incf   Cycle_counter,f   ; Не, Cycle_counter=(Cycle_counter)+1
      return         ; Връщане към ISR
Inc_timer2   incf   Cycle_counter2,w   ; W=(Cycle_counter)+1
      xorlw   D'2'      ; W XOR 2 -> W
      btfsc   STATUS,Z   ; W=2
      goto   inc_counters   ; Да, уваличи брояча на таймера
      incf   Cycle_counter2,f; Не, Cycle_counter=(Cycle_counter)+1
      clrf   Cycle_counter
      return         ; Връщане към ISR
inc_counters   clrf   Cycle_counter   ; 00 Cycle_counter
      clrf   Cycle_counter2
      incf   Counter_s1,f   ; Counter_s1=(Counter_s1)+1
      movlw   D'10'
      xorwf   Counter_s1,w   ; (Counter_s1) XOR W -> W
      btfss   STATUS,Z   ; (Counter_s1) = 10
      return         ; Не, връщане към ISR
      clrf   Counter_s1   ; Да, нулиране на Counter_s1
inc_s2      incf   Counter_s2,f
      movlw   D'6'
      xorwf   Counter_s2,w
      btfss   STATUS,Z
      return
      clrf   Counter_s2
inc_m1      incf   Counter_m1,f
      movlw   D'10'
      xorwf   Counter_m1,w
      btfss   STATUS,Z
      return
      clrf   Counter_m1
inc_m2      incf   Counter_m2,f
      movlw   D'6'
      xorwf   Counter_m2,w
      btfss   STATUS,Z
      return
      clrf   Counter_m2
inc_h1      incf   Counter_h1,f   ; Counter_h1 + 1
      movlw   D'2'      ; Проверка за
      xorwf   Counter_h2,w   ; (Counter_h2)=2 ?
      goto   h1_cont      ; Не
      movlw   D'4'      ; Да
      xorwf   Counter_h1,w
      btfss   STATUS,Z
      return
      clrf   Counter_h1
      goto   inc_h2
h1_cont      movlw   D'10'
      xorwf   Counter_h1,w
      btfss   STATUS,Z
      return
      clrf   Counter_h1
inc_h2      incf   Counter_h2,f
      movlw   D'3'
      xorwf   Counter_h2,w
      btfss   STATUS,Z
      return
      clrf   Counter_h2
      return
;----Обновяване на дисплея----
Update_disp   movf   Temp_PORTC,w   ; Temp_PORTC -> W
      movwf   PORTC      ; W -> PortC
      btfsc   Dig_s1      ; Обновяване индикатор s1?
      goto   update_s1   ; Да
      btfsc   Dig_s2      ; Не. Обновяване индикатор s2?
      goto   update_s2   ; Да
      btfsc   Dig_m1      ; Не. Обновяване индикатор m1?
      goto   update_m1   ; Да
      btfsc   Dig_m2      ; Не. Обновяване индикатор m2?
      goto   update_m2   ; Да
      btfsc   Dig_h1      ; Не. Обновяване индикатор h1?
      goto   update_h1   ; Да
      goto   update_h2   ; Не
update_s1   movf   Counter_s1,w
      call    Table
      movwf   PORTB
      goto    end_update
update_s2   movf   Counter_s2,w
      call    Table
      movwf   PORTB
      goto    end_update
update_m1   movf   Counter_m1,w
      call    Table
      movwf   PORTB
      goto    end_update
update_m2   movf   Counter_m2,w
      call    Table
      movwf   PORTB
      goto    end_update
update_h1   movf   Counter_h1,w
      call    Table
      movwf   PORTB
      goto    end_update
update_h2   movf   Counter_h2,w
      call    Table
      movwf   PORTB
end_update   bcf   STATUS,C
      rlf   Temp_PORTC,f   ; Обновяване на следващ индикатор
      btfss   Temp_PORTC,6   ; Обновен ли е h2?
      return         ; Не, връщане към ISR
      movlw    B'00000001'
      movwf   Temp_PORTC
      return
;---- Таблица ----
Table      addwf   PCL,f      ; W + PCL = PCL
      retlw   b'10111111'
      retlw   b'10000110'
      retlw   b'11011011'
      retlw   b'11001111'
      retlw   b'11100110'
      retlw   b'11101101'
      retlw   b'11111101'
      retlw   b'10000111'
      retlw   b'11111111'
      retlw   b'11101111'
;----Конфигуриране и инициализация на таймера----
Timer_config      bsf   STATUS,RP0
      movlw   B'10000100'
      movwf   OPTION_REG
      bcf   STATUS,RP0
      clrf   Counter_s1
      clrf   Counter_s2
      clrf   Counter_m1
      clrf   Counter_m2
      clrf   Counter_h1
      clrf   Counter_h2
      clrf   Cycle_counter
      movlw   B'00000001'
      movwf   Temp_PORTC
      movlw   Begin_value
      movwf   TMR0
      return
;----Главна програма----
main      call   Timer_config
      movlw   B'10100000'
      movwf   INTCON
loop      nop
      goto   loop
      END


Прикачвам примерна схема. Не съм сложил бутони за настройване на часа но ще сложа, само да тръгне. С PORTB контролирам сегментите а с PORTC отделните индикатори
Изображение

Моля ви помагайте. Много труд хвърлих в това нещо и просто искам да го направя.

Прикачени файлове:
Clock.asm [5.46 KiB]
255 пъти

Автор:  ji4ka [ Чет Май 08, 2008 10:39 pm ]
Заглавие: 

1. Увеличи токовете като намалиш резисторите. Тия NPN от към VDD - куца работа - сложи PNP-та и инвертирай изходите в програмата.
2. Вместо общ резистор R9-R16 сложи отделен за всеки сегмент ЛЕД-ове - качеството си има цена. Провери и дали ти е стабилно захранването.
3. За програмата явно нещо си объркал ,ама нещо ме мързи да я изследвам. Действай със симулатора стъпка по стъпка :wink:

Автор:  wolfshark [ Чет Май 08, 2008 10:46 pm ]
Заглавие: 

Сложих PNP намалих резисторите - по-добре е но си е слабичко.
Сега контролера съвсем се сбъгяса - показва само 88:88:88 но динамичната индикация работи (това стана след като смених транзисторите на сегментите с PNP и модифижирах таблицата в програмата)
Захранването е стабилно. Всичко работи по принцип и ако сега го препрограмирам вероятно ще заработи, но до кога... не знам след което може пак да се сбъгяса.
Имам 2 контролера положението е идентично, сега ще препрограмирам другия и ще го сложа. (само да спомена че са free samples)

Автор:  fan [ Чет Май 08, 2008 11:16 pm ]
Заглавие: 

Като начало, отдели захранването на индикаторите от това на процесора :wink: , и виж в pdf -а на пика как и какви резистори ,диод и кондензатор се свързват към MCLR pina.

Автор:  fan [ Пет Май 09, 2008 2:52 am ]
Заглавие: 

Ето ти развита темата! Прегледай внимателно! Чети повечко за контролерите!Успех!
(Несъм инвертирал изходите, ако се налага (а то е така), ги коригирай)

Прикачени файлове:
clock.rar [1.82 KiB]
249 пъти

Автор:  Cekins [ Пет Май 09, 2008 9:36 am ]
Заглавие: 

1. Светодиодите на общ катод + ULN200х и нямаш нужда от инвертиране плюс това спестяваш запояването на 8 транзистора и 8 резистора.
2. Ползвай нещо от сорта на BC3xx PNP (ако можеш да правиш смд ползвай BC807)
3. Светодиодите щом са по 3 в никакъв случай не ги връзвай паралелно. Винаги единия е с малко по-малък пад от другите и все едно имаш един светодиод + два дето ич не щът да светят ама не знеш защо така. Сметни си резистора за последователно свързани светодиоди.
4. Чети документациите на светодиодите - има 1000ххх вида светодиоди от от 50 Iv (ucd) до десетки хиляди. Тия дето се продават по магазините за жълти стинки са по 50 - 100 - сам се сещай че в динамичен режим ше светят ама някой друг път. За добро светене ти трябват над 2-3 хиляди а в най-добрия случай 20 - 30 хиляди. най добре като искаш големи цифри в комет има до към 3 инчови 7сег.лед. (малко скъпички) с маркировка xxxxx SRWA (super bright red) - вадят очи при 40-50 mA и са перфектни за динамична.
5. Направи си опресняването на таймер (аз го правя на таймер 2 обикновенно) за да ти е фиксирано точно времето. А и тогава по лесно ще видиш кое точно ти се бъгва.

Автор:  wolfshark [ Пет Май 09, 2008 12:20 pm ]
Заглавие: 

fan написа:
Ето ти развита темата! Прегледай внимателно! Чети повечко за контролерите!Успех!
(Несъм инвертирал изходите, ако се налага (а то е така), ги коригирай)

Благодаря ти много! Прегледах кода, после ще го прегледам по-обстойно и ще видя дали работи. За контролерите определено имам да чета още доста. Не трябваше да се мятам директно на този 16F873 докато в момента чета за 16F84 - нещата са по-различни. Светодиодите си светят еднакво - не единия да свети по-силно а другите по-слабо

Автор:  ji4ka [ Пет Май 09, 2008 12:38 pm ]
Заглавие: 

Кажи как си вързал диодите в тройки? Ако са последователно може да се наложи да вдигнеш захранването до 5.5В. Червените ЛЕД-ове имат пад 1.6-1.7В + загубите по трасето, 5В може да не стигнат. Иначе така е най ефективно. Нагласи тока през тях да е поне 100ма импулс.
PNP-тата да не си им объркал изводите? Трябва да се обърне колектора към диодите, емитера към Вдд.

Автор:  Koleto [ Пет Май 09, 2008 4:43 pm ]
Заглавие: 

И като направиш тока 100мА гледай да си се погрижил добре да не ти забие контролера.... защото... сещаш се какво ще се случи с пуснатите светодиоди в момента в който се отпушат съответните транзистори и контролера земе та умре... За съжаление така се прави на всякъде по динамичните индикаций за да светят силно... работи се почти с максималния допустим импулсен ток на диодите и се мисли много ама много как да се защити системата от забиване на процесора и ако това все пак се случи... трябва да имаш предпазен механизъм с който да угасиш индикацията (куче в контролера или извън него да резетва при забиване и т.н.)...

Автор:  Cekins [ Пет Май 09, 2008 5:09 pm ]
Заглавие: 

Koleto, аз затова му предложих на човека от тия индикатори - честно казано до сега съм ползвал само до 1 инч обаче дори и те в границите на допустимия ток по документация (че и малко отгоре) пак светят достатъчно силно, и като остане да свети само 1 индикатор при забиване не изгаря, просто свети доста ярко (вади очи дето му викам аз :) ). За още по-големи индикатори може да питате @VANK :)

Автор:  Zeus [ Пет Май 09, 2008 7:43 pm ]
Заглавие: 

Аз ползвам индикатори за динамична индикация на KingBright. Поръчвам си ги от Комет. При 5В слагам 120ом резистори SMD 0805. Светят доста силно. И забиването не е проблем. Случвало се е да забие и да свети един индикатор около 1 час без да изгори. Май проблема му е повече, че не му работи програмата, отколкото силата на светене. Ако имам време, ще я прегледам. Не, че и аз съм много навътре в контролерите, но може и да открия някой бъг.

Автор:  wolfshark [ Пет Май 09, 2008 8:21 pm ]
Заглавие: 

Преди 2 седмици направих друг часовник - с нормални индикатори и PIC 16F628 като схемата и програмата взех от интернет. Странно но там нямаше никакви резистори - PORTB директно отиваше на сегментите, така и го направих. Всичко работи нормално но има отново проблема, че 1 свети по-силно от 8 например

Автор:  fan [ Пет Май 09, 2008 8:26 pm ]
Заглавие: 

Това добре, а ти до къде стигна със задачката?

Автор:  Zeus [ Пет Май 09, 2008 8:28 pm ]
Заглавие: 

И аз така правя. Сегментите ги свързвам през резистори директно към порта, а анодите/катодите ги управлявам през транзистори. wolfshark - компилирах програмата ти от поста и я пуснах през Протеус. Брояча започна да нараства, динамичната индикация си работи. Виж все пак връзките по платката. Закачих схемата от протеуса с която пробвах.

Прикачени файлове:
1.JPG
1.JPG [ 70.11 KiB | Прегледано 2270 пъти ]

Автор:  Ки4о [ Пет Май 09, 2008 8:35 pm ]
Заглавие: 

Zeus - схемата то е грешна :) виж къде си вързал земята :wink:

Страница 1 от 2 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/