Отговори на тема  [ 4 мнения ] 
Проблем със софтуерен ШИМ (PWM) [PIC16F84A] 
Автор Съобщение
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Май 24, 2012 2:12 pm
Мнения: 3
Мнение Проблем със софтуерен ШИМ (PWM) [PIC16F84A]
Здравейте всички :) Нов съм в света на микроконтролерите и в езикът асемблер и това е първата ми тема във форумът Ви. Надявам че с помощта Ви ще напредна :)
Целта на изпитанието на което се подложих е да постигна нещо като това :
http://www.instructables.com/id/Super-Easy-Reversible-Motor-Control-for-Arduino-/
или накратко да управлявам посоката и скоростта на електромоторче чрез микроконтролер (използвам PIC16F84A който няма вграден ШИМ и се налага това да бъде постигнато програмно).
Схемата се състои от реле свързано със микроконтролера към порт Б и по-точно към пинове 1 и 2 (има и един светодиод свързан към пин 0 който използвам само за индикация на случващото се). При подаване на логическа "1" към пин 1 се включва моторчето , а при подаване на логическа "1" към пин 2 се променя посоката му на въртене .... осъществих схемата и всичко съм тествал и работи ,но имам голям проблем с част от програмата ... целта на програмата е следната :
1.моторчето се върти по часовниковата стрелка за определено време със скорост 100%
2.пауза
3.моторчето се върти по часовниковата стрелка за определено време със скорост 50%
4.пауза
5.моторчето се върти обратно на часовниковата стрелка за определено време със скорост 100%
6.пауза
7.моторчето се върти обратно на часовниковата стрелка за определено време със скорост 50%
8.пауза
9. всичко от начало се повтаря до безкрай

а ето и какво се получава при мен:

1.моторчето се върти по часовниковата стрелка за определено време със скорост 100%
2.пауза
3.моторчето се върти по часовниковата стрелка за определено време със скорост 50% и програмата не продължава напред ...

По пътят на логиката проблема на програмата ми е в броячът ("cou") който трябва да отчете кога подпрограмата за ШИМ ("pwmf50") да прехвърли управлението на главната програма - main.
Ще може ли някой да помогне ?
Ето и кодът (на пръв поглед изглежда сложен заради размерът му но всъщност има две подпрограми които се дублират/с разлика в стойностите/ и една главна програма - main):

Цитат:
list p=16F84A
#include <p16F84A.inc>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

w EQU 0
f EQU 1
Counter EQU H'0C'
c equ 0
portb equ 0x06 ; port b equate
duty equ 0x0c ; length of duty cycle
temp equ 0x0d ; length of duty cycle
cou set d'100'


ORG H'0000'
goto start

start bsf STATUS,RP0
movlw B'11010111'
movwf OPTION_REG
bcf STATUS,RP0
clrf PORTB
bsf STATUS,RP0
movlw B'11111000'
movwf TRISB
bcf STATUS,RP0
goto main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;deley for the pause between subroutines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WaitP movlw D'30'
movwf Counter
clrf TMR0
againP bcf INTCON,T0IF
loopP btfss INTCON,T0IF
goto loopP
decfsz Counter,f
goto againP
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;delay for the time of Action on pwm100b and pwm100f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WaitA movlw D'70'
movwf Counter
clrf TMR0
againA bcf INTCON,T0IF
loopA btfss INTCON,T0IF
goto loopA
decfsz Counter,f
goto againA
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;pwm 50% forward
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pwm50f movlw d'0'
movwf portb
movlw d'90' ; Duty cycle length
movwf duty
movf duty,w
movwf temp
bsf portb,0
bsf portb,1
pwma50f nop
nop
nop
decfsz temp
goto pwma50f
movlw d'255'
movwf temp
movf duty,w
subwf temp,f
bcf portb,0
bcf portb,1

pwmb50f nop
nop
nop
decfsz temp
goto pwmb50f
bcf INTCON,T0IF
btfss INTCON,T0IF
goto pwm50f
decfsz cou
clrf TMR0
return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;pwm 50% backward
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pwm50b movlw d'0'
movwf portb
movlw d'90' ; Duty cycle length
movwf duty
movf duty,w
movwf temp
bsf portb,0
bsf portb,1
bsf portb,2
pwma50b nop
nop
nop
decfsz temp
goto pwma50b
movlw d'255'
movwf temp
movf duty,w
subwf temp,f
bcf portb,0
bcf portb,1
bcf portb,2

pwmb50b nop
nop
nop
decfsz temp
goto pwmb50b
bcf INTCON,T0IF
btfss INTCON,T0IF
goto pwm50b
decfsz cou
clrf TMR0
return





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;pwm 100% forward
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pwm100f bsf portb,0
bsf portb,1
call WaitA
bcf portb,0
bcf portb,1
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;pwm 100% backward
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pwm100b bsf portb,0
bsf portb,1
bsf portb,2
call WaitA
bcf portb,0
bcf portb,1
bcf portb,2
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
main call pwm100f
call WaitP
call pwm50f
call WaitP
call pwm100b
call WaitP
call pwm50b
call WaitP
goto main

END


ПП: Незнам как да постна кода така че директивите да са разделени на колонки :?


Чет Май 24, 2012 2:25 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Май 01, 2009 4:01 pm
Мнения: 1438
Мнение Re: Проблем със софтуерен ШИМ (PWM) [PIC16F84A]
Ами няма да прескочи никога! Ти първо нулираш INTCON,T0IF и след това проверяваш дали е сетнат. Първо го провери и ако е сетнат тогава го нулирай и т.н. А и с cou имаш недомислица. Намаляваш го с 1 и направо излизаш от подпрограмата а би трябвало да излезеш като стане 0. А и така както си го декларирал няма адрес и е просто стойност, която никога няма да се намали.


Чет Май 24, 2012 3:26 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Май 24, 2012 2:12 pm
Мнения: 3
Мнение Re: Проблем със софтуерен ШИМ (PWM) [PIC16F84A]
Успях да изляза от ШИМ генератора и да се върна към основната програма и сега се изпълнява всичко от главната програма main (която се наложи да попроменя), но времето за което моторчето се върти със скорост 50% е много малко и не успявам да го променя ... ето каква е логиката ми :

Цитат:
pwm50 ;начало на подпрограмата която осъществява ШИМ
....
....
....
....
pwmb50 nop
nop
nop
decfsz temp ;temp = temp-1 . temp=0 ?
goto pwmb50 ;НЕ - изпъни отново
;ДА - прескочи "goto pwmb50f"

btfss INTCON,T0IF ;бит T0IF=1???
goto pwm50 ;НЕ - върни се в началото на подпрограмата
decfsz cou ;ДА - намали cou с 1. cou=0 ?
goto pwm50 ;НЕ - върни се в началото на подпрограмата
return ;ДА - върни се към главната програма



т.е. следя за препълване на TMR0 , като проверявам бит T0IF дали е 1 или 0.Препълването би трябвало да отнеме около 43ms (поне толкова го сметнах но точното време не е от значение) т.е. T0IF става 1 и тогава намалям брояча (cou) с 1 , като същевременно проверявам дали брояча не е стигнал до 0 и когато това стане се връщам към главната програма. Следователно ако cou e 100 трябва да се върна към главната програма след 100 x 43ms = 4,3 секунди , а при мен се получава време от около 1 секунда (дори когато направя cou = 255).Или май трябва да зануля T0IF отново след като намаля cou с 1 ?

Ето и main където нулирам TMR0 и бит T0IF преди да извикам подпрограма pwm50:
Цитат:
main call pwm100f
call WaitP

clrf TMR0
bcf INTCON,T0IF
call pwm50
call WaitP

call pwm100b
call WaitP

clrf TMR0
bcf INTCON,T0IF
bsf portb,2
call pwm50
bcf portb,2
call WaitP

goto main


относно декларацията на брояча "cou" - така ли трябва да е ?:
Цитат:
......
.....
cou equ 0x0f


ORG H'0000'
goto start

start movlw d'255'
movwf cou
....
...
...

Къде ми е грешката ?


Чет Май 24, 2012 5:03 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Май 24, 2012 2:12 pm
Мнения: 3
Мнение Re: Проблем със софтуерен ШИМ (PWM) [PIC16F84A]
Готово :P Направих го :D Благодаря за помощта :lol:
Ето и кодът ако някой се интересува :wink:
Цитат:
list p=16F84A
#include <p16F84A.inc>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

w EQU 0
f EQU 1
portb equ 0x06 ; port b equate
Counter EQU 0x0c
duty equ 0x0d ; length of duty cycle
temp equ 0x0e ; length of duty cycle
cou equ 0x0f


ORG H'0000'
goto start

start movlw d'100'
movwf cou
bsf STATUS,RP0
movlw B'11010111'
movwf OPTION_REG
bcf STATUS,RP0
clrf PORTB
bsf STATUS,RP0
movlw B'11111000'
movwf TRISB
bcf STATUS,RP0
goto main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;deley for the pause between subroutines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WaitP movlw D'50'
movwf Counter
clrf TMR0
againP bcf INTCON,T0IF
loopP btfss INTCON,T0IF
goto loopP
decfsz Counter,f
goto againP
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;delay for the time of Action on pwm100b and pwm100f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WaitA movlw D'70'
movwf Counter
clrf TMR0
againA bcf INTCON,T0IF
loopA btfss INTCON,T0IF
goto loopA
decfsz Counter,f
goto againA
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;pwm 50% speed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pwm50 movlw d'0'
movwf portb
movlw d'90'
movwf duty
movf duty,w
movwf temp
bsf portb,0
bsf portb,1
pwma50 nop
nop
nop
decfsz temp
goto pwma50
movlw d'255'
movwf temp
movf duty,w
subwf temp,f
bcf portb,0
bcf portb,1

pwmb50 nop
nop
nop
decfsz temp ;temp = temp-1 . temp=0 ?
goto pwmb50 ;НЕ - изпъни отново
;ДА - прескочи "goto pwmb50f"

btfss INTCON,T0IF ;бит T0IF=1???
goto pwm50 ;НЕ - върни се в началото на подпрограмата
decfsz cou ;ДА - намали cou с 1. cou=0 ?
goto t0clr ;НЕ - върни се в началото на подпрограмата
return ;ДА - върни се към главната програма

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;t0clr - нулиране на бит T0IF на TMR0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
t0clr bcf INTCON,T0IF
goto pwm50

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;pwm 100% forward
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pwm100f bsf portb,0
bsf portb,1
call WaitA
bcf portb,0
bcf portb,1
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;pwm 100% backward
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pwm100b bsf portb,0
bsf portb,1
bsf portb,2
call WaitA
bcf portb,0
bcf portb,1
bcf portb,2
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
main call pwm100f
call WaitP

movlw d'100'
movwf cou
clrf TMR0
bcf INTCON,T0IF
call pwm50
call WaitP

call pwm100b
call WaitP

movlw d'100'
movwf cou
clrf TMR0
bcf INTCON,T0IF
bsf portb,2
call pwm50
bcf portb,2
call WaitP

goto main

END


Чет Май 24, 2012 5:33 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 4 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 6 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни