Ik probeer met een 16F628 (Xtal 20MHz) een 38kHz blokgolf op te wekken d.m.v. het schrijven van de daarvoor beschikbare registers. Door instellen van locatie PR2 (92h) zou het mogelijk moeten om de frequentie in te stellen. Echter de frequentie lijkt vastgebakken op de minimale waarde (PR2 = 0xFF) en blijkt alleen te veranderen door het wijzigen van de prescaler (bit 0 en 1 van t2con op locatie 12h. Hiermee krijg ik frequenties van resp. 1221, 4881 en 19531Hz (prescaler 16/4/1) ongeacht de waarde van PR2. De waarde van de duty cycle lijkt wel goed te werken CCPR1L op locatie 15h. Kan iemand me vertellen wat ik fout doe? Bijgevoegd programma in JAL. ALvast bedankt voor de moeite.

JAL programma:

include f628_20
include jlib
include interval
include jdelay
include 16f628_PWM

var volatile byte CMCON at 0x1F = 0x07 -- disable port a analog functions
-- var volatile byte f at 0x92 = 0x01
var byte DC

-- PWM init
f628_pr2 = 0x82 -- 38kHz
f628_t2con = 0b000_0100 -- prescaler TMR2: b1,b0 Prescaler 00 = 1; 01 = 4; 1x = 16
f628_ccp1con = 0x3c -- PWM mode
pin_b3_direction = output

f628_ccpr1l = 0x41 -- Duty Cycle 50%

forever loop

-- f628_ccpr1l = DC
-- DC = 0xff -- DC + 2
-- if DC == 250 then
-- DC = 0
-- f628_ccpr1l = DC
-- delay_1s(1)
-- end if
-- delay_100ms(1)

end loop

Op 7 juli 2005 15:42:43 schreef Nees:

f628_t2con = 0b000_0100 -- prescaler TMR2: b1,b0

plaats eens een nul meer:

f628_tcon = 0b0000_0100

als je prog al zo zou zijn moet je eens in de juiste volgorde zoals de datasheet opgeeft je instucties herschikken

bij mij werkt alles perfect

Bedankt voor je antwoord maar helaas wil het nog steeds niet lukken. De nul had ik al gevonden en de volgorde uit de datasheet geeft ook geen verbetering. Heb je misschien een voorbeeld-programmaatje? Alvast bedankt.


procedure init_PWM is
   f877_pr2 = 255 -- Tmr2 period reg: PWM period = (PR2+1).4.Tosc.(Tmr2_prescale)
   -- CCP1
   f877_ccpr1l = 0
   pin_c2_direction = output
   f877_t2con = 0b_0000_0100 -- Tmr2 on, prescaler = 1
   f877_ccp1con = 0b_0000_0000
   pin_c2 = low
   -- CCP2
   f877_ccpr2l = 0
   pin_c1_direction = output
   f877_t2con = 0b_0000_0100 -- Tmr2 on, prescaler = 1	
   f877_ccp2con = 0b_0000_0000
   pin_c1 = low
end procedure

-- Fan 1(left) on RC2 / CCP1

procedure start_fan_left ( byte in out dutycycle, bit out on_off, bit out start ) is
   if dutycycle < 200 then
      f877_ccpr1l = 200
      start = true
      if dutycycle < 155 then
         dutycycle = 155
      end if
   else
      f877_ccpr1l = dutycycle
   end if
   f877_ccp1con = 0b_0011_1100
   on_off = true
end procedure

procedure stop_fan_left ( byte out dutycycle, bit out on_off, bit out start ) is
   dutycycle = 0
   f877_ccpr1l = dutycycle
   f877_ccp1con = 0b_0000_0000
   pin_c2 = low
   on_off = false
   start = false
end procedure

procedure update_fan_left ( byte in dutycycle ) is
   f877_ccpr1l = dutycycle	 	
end procedure

in hoofdprogramma (forever loop...)


...
 if pushb_down then
        if fan_on_left then
           stop_fan_left ( fan_speed_left, fan_on_left, fan_starting_left )
        else
           start_fan_left ( fan_speed_left, fan_on_left, fan_starting_left )
           vtmr1_go = true
        end if
        if fan_on_right then
           stop_fan_right ( fan_speed_right, fan_on_right, fan_starting_right )
        else
           start_fan_right ( fan_speed_right, fan_on_right, fan_starting_right )
           vtmr2_go = true
        end if
     end if
     if pushb_set then
        fan_speed_left = fan_speed_left - 5
        update_fan_left ( fan_speed_left )
        fan_speed_right = fan_speed_right - 5
        update_fan_right ( fan_speed_right )
     end if
     if pushb_8 then
        fan_speed_left = fan_speed_left + 5
        update_fan_left ( fan_speed_left )
        fan_speed_right = fan_speed_right + 5
        update_fan_right ( fan_speed_right )
     end if
   end if
...

[Bericht gewijzigd door Jonathan op ]

Bedankt voor je reply. Programma aangepast voor 16F628a. Zelfde resultaat, hoogste freq. 19.53kHz (Fosc = 20MHz)ongeacht waarde in PR2. 16F877a uit de kast getrokken. Op breadboard gezet. Aangesloten. Programma geladen. Zelfde resultaat. Max freq. 19.53kHz. ???? Probeer zelf nu assembler te schrijven maar krijg dit (nog) niet werkend. Iemand nog een goed idee?

Ik weet niet wat je fout doet, want je kan veel hogere frequenties halen, maar dit werkt:


	LIST P=PIC16F628A, F=INHX8M
	__CONFIG _CP_OFF & _WDT_OFF & _HS_OSC & _LVP_OFF 

	include "p16f628A.inc"
	include "../inc/macros.inc"

;*****************************************************************************
; Equates, I/O, vars
;*****************************************************************************
RESET_V		EQU	0x0000		; Address of RESET Vector
ISR_V		EQU	0x0004		; Address of Interrupt Vector
OSC_FREQ	EQU	.20000000	; Oscillator Frequency is 20 MHz

;*****************************************************************************
; Program start
;*****************************************************************************
	ORG	RESET_V			; RESET vector location
RESET		goto	START

;*****************************************************************************
; This is the Periperal Interrupt routine. Should NOT get here
;*****************************************************************************
	ORG	ISR_V			; Interrupt vector location
INTERRUPT	GOTO    INTERRUPT	; Hang processor

;*****************************************************************************
; Initialize processor registers
;*****************************************************************************
START					; POWER_ON Reset (Beginning of program)
		CLRF	STATUS		; Do initialization, Select bank 0
		CLRF	INTCON		; Clear int-flags, Disable interrupts
		CLRF	PCLATH		; Keep in lower 2KByte

		CLRF	PORTA		; ALL PORT output should output Low.
		CLRF	PORTB

		BANK1
		MOVLW	0x07
		movwf	CMCON		; Port A is digital
		
		movlw	0xFF
		movwf	TRISA		; Port a All input
		MOVLW	b'11110111'	; RB3 (PWM) is output
		MOVWF	TRISB
		BSF	OPTION_REG, NOT_RBPU
					; Disable PORTB pull-ups
		BANK0

		CLRF	T2CON		; Stop Timer2, Prescaler = 1:1, Postscaler = 1:1
		CLRF	TMR2		; Clear Timer2 register
		BANK1
		movlw	.131		; Closest match to 26.3 usec
		movwf	PR2
		BANK0
		movlw	.61		; plm 50 % (132/61)
		movwf	CCPR1L
		movlw	b'00001100'	; Enable PWM mode, lsb's are 0
		movwf	CCP1CON
		bsf	T2CON,TMR2ON

		goto	$

		END

Ik zou zeggen: zoek de verschillen :-)

Oké, bedankt voor je antwoord. Nadat ik de BANK0 en BANK1 macro's (?) had herschreven in:


;BANK0
		BCF		STATUS,RP1
		BCF		STATUS,RP0

;BANK1
		BCF		STATUS,RP1
		BSF		STATUS,RP0

kon ik gaan tot 2,5MHz (!). De blokgolf ziet er dan niet meer uit maar ik hoef toch maar 38kHz. Dus dit volstaat! Maar blijkbaar gaat er in JAL iets fout met het schrijven van RP2 op locatie 92h in Bank 1. Als ik naar de assemblercode kijk die JAL maakt staat er:



;; 013 :    f628_pr2 = 100 -- Tmr2 period reg: PWM period = (PR2+1).4.Tosc.(Tmr2_prescale)
  movlw   H'64'
  movwf   H'92'

Geen vermelding dat dit naar Bank1 geschreven zou moeten. Misschien lees ik ergens overheen maar misschien is er iemand die verduidelijking kan geven. Ik programmeer namelijk liever in JAL dan assembler. Bedankt allemaal voor de support!

Op 12 juli 2005 10:20:45 schreef Nees:
Oké, bedankt voor je antwoord. Nadat ik de BANK0 en BANK1 macro's (?) had herschreven in:[...]

Yep, zijn Macros met bsf/bcf waarbij ik gelijk ook die irritante warnings mee uitzet die je altijd krijgt als je een register in bank1 adresseert.

Blijkbaar wordt er een bankselect vergeten in je JAL (ken die taal niet). Dat de blokgolf lelijk wordt bij 2.5 MHz ligt denk ik aan je meetapparatuur, want bij mij ziet ie er mooi uit maar hoe hoger de freq, hoe minder bits voor de PWM.

raar dat het van mij wel werkt

misschienn liggen die adressen in een PIC877 anders?

ik zou eens moeten kijken

[Bericht gewijzigd door Jonathan op ]

Ik heb inmiddels het ook werkend met JAL. Ik gebruik hierin voor het schrijven van PR2 de assembler code:


-- f628_pr2 = 100 -- Tmr2 period reg: PWM period = (PR2+1).4.Tosc.(Tmr2_prescale)
   -- assembler workaround to tackle bankselect problem JAL
   assembler
      BCF		0x03,6
	  BSF		0x03,5
	  movlw	0x81		; 1 / 26.0 usec =38,461kHz
	  movwf	0x92
	  BCF		0x03,6
	  BCF		0x03,5
   end assembler
   f628_ccpr1l = 65

Verschillen tussen 877 en 628 in Data/Register file mapping zit alleen hierin dat er voor de 877 meer registers gedefinieerd zijn. Volgens mij lijkt het op een verschil in compilers. Als ik mijn compiler start zonder opties krijg ik als eerste regel: jal 00.04-50 (djgpp). Ben benieuwd wat voor compiler jij gebruikt.

ik compile via JALEDIT met JAL vs 4.59

Ik ben inmiddels overgegaan op JAL versie 0.4.60 en hiermee blijkt het wel goed te gaan!! Geen assembler meer nodig om PR2 te kunnen schrijven. Allen bedankt.