Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Using PWM on a 18F13K22

Status
Not open for further replies.
Swordfish is not the problem it's a great compiler for the 18f chips.
What is the problem PWM Jon's chart shows how to set the color of the led which could use PWM or just a timer after all the pic is just sitting there blinking a led at a fast setting to make a port pin output a set amount of current. The same colors could be set with a resistor then just add the flicker.
 
While in the shower, I gave this a brief bit of thought. I wonder how it would look to connect 8 LEDs to a port, say 5 yellows and three reds, and just write random numbers to the port as rapidly as possible. Something like this:

While true
PortB = Rand() * 254 + 1
Wend

As I recall, Rand() returns a value between 0 – 1. Multiply this by 254 to get a value between 0 - 254, and add 1 to give you a value between 1 – 255 so that at least one LED is always on. Simple enough to try.
 
Swordfish is not the problem it's a great compiler for the 18f chips.
What is the problem PWM Jon's chart shows how to set the color of the led which could use PWM or just a timer after all the pic is just sitting there blinking a led at a fast setting to make a port pin output a set amount of current. The same colors could be set with a resistor then just add the flicker.
If i understand you correctly tho, wouldn't this just give one colour? Or are you suggesting a number of resistor's on different pins?
I didn't mean to suggest SF was the problem, i was asking to the likely hood of there forum offering help.
I don't ask anything on the microchip forum now, just about each and every question is met with....What you cant do XYZ!!! YOU TOOL!!! read the datasheet!!!
There seems to be a clique on there that run's the show, only the minority get useful information. The rest of us get what i assume is now a cut and paste reply.
 
$1.80!!!!! i will go find a cheaper option :D thank you for looking at it jonsea. I confess i didn't see the multi led thing, just 5 channel. So it's going to be a bust :( i will search again! God this google is good,it took just over 4 min's to find that page.

Well, if $1.80 each is simply beyond reach, you could go for the low power, non-premium version. This would cut out those expensive transistors and 5 resistors and save 15 cents each!. I would guess if you're trying to light up a room, the 15 extra cents would be well spent.
 
Sorry ghostman11 what I mean is you could set a color with a resistor with the pick and the timer and three transistors you could make any color you want and using the timer you could use more pins and if your really good you could invert the output to make it look like one led is doing a deferent thing c
 
I can see where Mr Deb has his confusion, but i can find no way to explain it in a way he can grasp.
Mr Deb is making a distinction between PWM peripheral, and timer interrupt PWM. In reality, if your code is doing little or nothing else, then there really is no difference to quality.
I cant remember now how many timer's he has on that chip, But enough to even have one timer for every 3 leds! The reason i think he is getting strobes, is because he is running the loop too fast. Really for the program loop method to work, you need a scope or program in ASM. That way you can see the timings, otherwise it's just guess work with simple program looping. OR do it with TIMERS and INTERRUPTS! that way simple calculation's give you the correct timings for smooth PWM, and yes Burt i am aware you know this already, but i prefer to tell you to the op.:D no offense OP.
As much as i hate to add a complication, i would also use the PLL for a really smooth transition, but again at that speed you need a scope. OR calculator,pen and paper. No idea what paper cost's over there
 
It's really quite expensive here! Way too much to spare a sheet on a flow chart or to sketch out a plan before copy&pasting(TM) code!
You may mock, but i have just seen an invoice for a box of 5 reams A4 :eek::eek::eek::eek: £31 for the paper and £22 delivery!!!:mad::banghead:. Next time i will get off my lazy a r s e, and go pick it up locally, rather than try and save £2 a box!
 
THANKS for all the great info. Am going to rethink my options seeing how cheap this particular candle is.
Only reason I was using Swordfish is that's the only programming language I am familiar with but am delving into ASM when I have time. Over at My Projects | {Brads Electronic Projects} he has an ASM tutorial I am following when I get the chance. Started with lesson one but need to get the pic chips he is using. All I have are 18F and 2 16F chips. Yes I could use the chips I have but life is to confusing already.Just too many items on my plate during the holidays.
As for this RGB candle Ghostman11 presented, it has all the software etc. Cost is very reasonable as well.
 
MrDEB, please take no offense but given the difficulties you have even constructing a conditional statement in Basic, assembler will be a huge uphill battle for you.
 
hang on i didn't suggest another chip! i took a quick peek at the code, and thought from what the site had said, that you can use the chip you have. Just get the configs etc changed to match your chip, dont buy anything else you should be able to use that code. JUST CHANGE the config and anything else that is needed to make it run on your chip!
PLEASE DO NOT go tweaking!!!! My idea is simply to get you a candle running, then whatever happens you have candles for your dinner.
because of problem's at home i am working from here this week (most of it), i will try and take a look, or ask LG to look at it for you when he has time.
 
first part
Code:
; This is a candle flicker simulator with 5 output channels and wind functions
; 28SEP13 V00.00 PJS New

#define    CODE_VER_STRING "Peter Shabino 28SEP13 code for LED candle  V00.00 www.wire2wire.org" ;Just in ROM !!! update vars below with true level!!

;****************************************************************************************
; port list
; Vss(8)
; Vdd(1)
; GP0(7)    LED / PGD
; GP1(6)    LED / PGC
; GP2(5)    LED
; GP3(4)    input output mode (low = active low, high = active high)
; GP4(3)    LED
; GP5(2)    LED
;****************************************************************************************


;-----------------------------------------------------------------------------------------------------------
; compiler configuration
;-----------------------------------------------------------------------------------------------------------
        ; set processor type and output file type (intel merged hex (.hex))
        list    f=INHX8M
        ; PIC12F508 Configuration Bit Settings
        #include "p12F508.inc"
        ; CONFIG = __config 0xFFEA
        __CONFIG _OSC_IntRC & _WDT_OFF & _CP_OFF & _MCLRE_OFF

;-----------------------------------------------------------------------------------------------------------
;constants
;-----------------------------------------------------------------------------------------------------------
    ; LED dimming level control
DIMSTEPS    equ        0x2F    ; number of total dimming steps (and mask) bigger = more steps
CALMLEDMAX    equ        0xFF    ; mask for the max led value during calm (and mask) bigger = brighter
CALMLEDMIN    equ        0x0F    ; mask for the min led value during calm (or mask) bigger = brighter
WINDLEDMAX    equ        0x0A    ; mask for the max led value during wind (and mask) bigger = brighter
WINDLEDMIN    equ        0x00    ; mask for the min led value during wind (or mask) bigger = brighter
    ; LED hold time control
CALMHOLDMAX    equ        0x7F    ; mask for the max length of time a calm led value will be held (and mask) bigger = longer
CALMHOLDMIN    equ        0x0F    ; mask for the min length of time a calm led value will be held (or mask) bigger = longer
WINDHOLDMAX    equ        0x1F    ; mask for the max length of time a wind led value will be held (and mask) bigger = longer
WINDHOLDMIN    equ        0x01    ; mask for the min length of time a wind led value will be held (or mask) bigger = longer
    ; wind gust generation
WINDMAXLEN    equ        0x0F    ; max length of wind time (and mask)
WINDMINLEN    equ        0x03    ; minimum length of wind time (or mask)
CALMMAXLEN    equ        0x1F    ; max length of wind calm (and mask)
CALMMINLEN    equ        0x07    ; minimum length of calm time (or mask)


;-----------------------------------------------------------------------------------------------------------
;variables (0x07 - 0x1F only)
;-----------------------------------------------------------------------------------------------------------
;        equ        0x07
;        equ        0x08
phase        equ        0x09
time0        equ        0x0B
time1        equ        0x0C
time2        equ        0x0D
time4        equ        0x0E
time5        equ        0x0F
led0l        equ        0x10
led0h        equ        0x11
led1l        equ        0x12
led1h        equ        0x13
led2l        equ        0x14
led2h        equ        0x15
led4l        equ        0x16
led4h        equ        0x17
led5l        equ        0x18
led5h        equ        0x19
temp0        equ        0x1A
temp1        equ        0x1B
wind        equ        0x1C
windcntl    equ        0x1D
windcnth    equ        0x1E
;        equ        0x1F
 
second part
Code:
;-----------------------------------------------------------------------------------------------------------
;put the following at address 0000h (starting vector)
;-----------------------------------------------------------------------------------------------------------
        org    0000h
;chip configuraton
        movwf    OSCCAL    ; move the osc cal value stored at the end of code to the osccal reg MUST be first instruction
        movlw    0xD6
        OPTION            ; TMR0 as a timer with 128 prescaler
        goto    INITREGS

;-----------------------------------------------------------------------------------------------------------
; This chunk of code is to fix a issue with the 12F parts not able to call subs in the lower half of the page...
;-----------------------------------------------------------------------------------------------------------
_RANDOM
        goto    _RANDOMLONG

;-----------------------------------------------------------------------------------------------------------
;init registers
INITREGS
;-----------------------------------------------------------------------------------------------------------
        movlw    0xff
        movwf    GPIO    ; set all bits high (leds off)
        movlw    0x08
        TRIS    GPIO    ; set LED pins as outputs
        movlw    0x30    ; set up inital seed (MUST NOT BE 0x0000!)
        movwf    led0h
        movlw    0x45
        movwf    led0l
        movlw    0x05    ; set up inital seed (MUST NOT BE 0x0000!)
        movwf    led1h
        movlw    0x30
        movwf    led1l
        movlw    0xA2    ; set up inital seed (MUST NOT BE 0x0000!)
        movwf    led2h
        movlw    0x11
        movwf    led2l
        movlw    0xC5    ; set up inital seed (MUST NOT BE 0x0000!)
        movwf    led4h
        movlw    0xEE
        movwf    led4l
        movlw    0xDE    ; set up inital seed (MUST NOT BE 0x0000!)
        movwf    led5h
        movlw    0xAD
        movwf    led5l
        movlw    0xFF    ; Init the wind control vars
        movwf    wind
        movwf    windcntl
        movlw    0x01
        movwf    windcnth

;-----------------------------------------------------------------------------------------------------------
;start of functional code
STARTOFCODE
;-----------------------------------------------------------------------------------------------------------
        movf    TMR0, W        ; grab the current timer value
        andlw    DIMSTEPS    ; mask off any upper bits not used for dimming the leds
        movwf    phase        ; this move does NOT affect the status reg so next check should be valid
        btfss    STATUS, Z    ; if the result is 0 turn on all the leds
        goto    CLEARDONE
        movlw    0xFF
        btfss    GPIO, 3        ; check mode pin if high use active high outputs
        clrf    GPIO        ; all outputs low for active low outputs
        btfsc    GPIO, 3        ; check mode pin if low use active low outputs
        movwf    GPIO        ; all outputs high for active high outputs

CLEARDONE
        incfsz    wind, W        ; check if wind is set add 1 if set goto windy code
        goto    WINDYLVS

        ; conditions are normal use full range
        movf    led0l, W    ; grab the random output
        andlw    DIMSTEPS    ; mask off unused bits
        andlw    CALMLEDMAX    ; apply limits
        iorlw    CALMLEDMIN    ; apply limits
        subwf    phase, W    ; suptract the result from the current phase value
        btfss    STATUS, C    ; if there is a carry (negitive) turn the leds off
        goto    LED0U
        btfss    GPIO, 3        ; check mode pin if high use active high outputs
        bsf        GPIO, 0        ; turn off the led set pin high for active low pins
        btfsc    GPIO, 3        ; check mode pin if low use active low outputs
        bcf        GPIO, 0        ; turn off the led set pin low for active high pins
LED0U
        movf    led1l, W    ; SEE led0l description above for comments
        andlw    DIMSTEPS
        andlw    CALMLEDMAX
        iorlw    CALMLEDMIN
        subwf    phase, W
        btfss    STATUS, C
        goto    LED1U
        btfss    GPIO, 3        ; check mode pin
        bsf        GPIO, 1
        btfsc    GPIO, 3        ; check mode pin
        bcf        GPIO, 1
LED1U
        movf    led2l, W    ; SEE led0l description above for comments
        andlw    DIMSTEPS
        andlw    CALMLEDMAX
        iorlw    CALMLEDMIN
        subwf    phase, W
        btfss    STATUS, C
        goto    LED2U
        btfss    GPIO, 3        ; check mode pin
        bsf        GPIO, 2
        btfsc    GPIO, 3        ; check mode pin
        bcf        GPIO, 2
LED2U
        movf    led4l, W    ; SEE led0l description above for comments
        andlw    DIMSTEPS
        andlw    CALMLEDMAX
        iorlw    CALMLEDMIN
        subwf    phase, W
        btfss    STATUS, C
        goto    LED4U
        btfss    GPIO, 3        ; check mode pin
        bsf        GPIO, 4
        btfsc    GPIO, 3        ; check mode pin
        bcf        GPIO, 4
LED4U
        movf    led5l, W    ; SEE led0l description above for comments
        andlw    DIMSTEPS
        andlw    CALMLEDMAX
        iorlw    CALMLEDMIN
        subwf    phase, W
        btfss    STATUS, C
        goto    LED5U
        btfss    GPIO, 3        ; check mode pin
        bsf        GPIO, 5
        btfsc    GPIO, 3        ; check mode pin
        bcf        GPIO, 5
LED5U
        goto    UPDATEDONE    ; finished processing leds in normal conditions

WINDYLVS
        ; conditions are windy
        movf    led0l, W    ; SEE led0l description above for comments
        andlw    DIMSTEPS
        andlw    WINDLEDMAX
        iorlw    WINDLEDMIN
        subwf    phase, W
        btfss    STATUS, C
        goto    LED0UW
        btfss    GPIO, 3        ; check mode pin
        bsf        GPIO, 0
        btfsc    GPIO, 3        ; check mode pin
        bcf        GPIO, 0
LED0UW
        movf    led1l, W    ; SEE led0l description above for comments
        andlw    DIMSTEPS
        andlw    WINDLEDMAX
        iorlw    WINDLEDMIN
        subwf    phase, W
        btfss    STATUS, C
        goto    LED1UW
        btfss    GPIO, 3        ; check mode pin
        bsf        GPIO, 1
        btfsc    GPIO, 3        ; check mode pin
        bcf        GPIO, 1
LED1UW
        movf    led2l, W    ; SEE led0l description above for comments
        andlw    DIMSTEPS
        andlw    WINDLEDMAX
        iorlw    WINDLEDMIN
        subwf    phase, W
        btfss    STATUS, C
        goto    LED2UW
        btfss    GPIO, 3        ; check mode pin
        bsf        GPIO, 2
        btfsc    GPIO, 3        ; check mode pin
        bcf        GPIO, 2
LED2UW
        movf    led4l, W    ; SEE led0l description above for comments
        andlw    DIMSTEPS
        andlw    WINDLEDMAX
        iorlw    WINDLEDMIN
        subwf    phase, W
        btfss    STATUS, C
        goto    LED4UW
        btfss    GPIO, 3        ; check mode pin
        bsf        GPIO, 4
        btfsc    GPIO, 3        ; check mode pin
        bcf        GPIO, 4
LED4UW
        movf    led5l, W    ; SEE led0l description above for comments
        andlw    DIMSTEPS
        andlw    WINDLEDMAX
        iorlw    WINDLEDMIN
        subwf    phase, W
        btfss    STATUS, C
        goto    UPDATEDONE
        btfss    GPIO, 3        ; check mode pin
        bsf        GPIO, 5
        btfsc    GPIO, 3        ; check mode pin
        bcf        GPIO, 5
 
third part
Code:
;-----------------------------------------------------------------------------------------------------------
; check if at the end of a dimming cycle if so go update the LED PRBS values as needed.
UPDATEDONE
;-----------------------------------------------------------------------------------------------------------       
        movf    phase, W
        btfss    STATUS, Z
        goto    STARTOFCODE

        ; check on conditons
        incfsz    wind, W        ; check if wind is set add 1 if set goto windy code
        goto    WINDLEDS

        ; conditions are normal use long flicker delays
        decfsz    time0, F    ; subtract 1 from dwell time if 0 update PRBS for this channel
        goto    LED1
        movlw    led0l        ; set up the indirect register with location of 16 bit LFSR var for this channel
        movwf    FSR
        call    _RANDOM        ; call the random function
        movf    led5h, W    ; move the high value of LED 5 to the W register (using a different channels values to increase randomness)
        iorlw    CALMHOLDMIN    ; apply limits
        andlw    CALMHOLDMAX    ; apply limits
        movwf    time0        ; store new dwell time
LED1
        decfsz    time1, F    ; see normal time0 comment above for this section
        goto    LED2
        movlw    led1l
        movwf    FSR
        call    _RANDOM
        movf    led0h, W
        iorlw    CALMHOLDMIN
        andlw    CALMHOLDMAX
        movwf    time1
LED2
        decfsz    time2, F    ; see normal time0 comment above for this section
        goto    LED4
        movlw    led2l
        movwf    FSR
        call    _RANDOM
        movf    led1h, W
        iorlw    CALMHOLDMIN
        andlw    CALMHOLDMAX
        movwf    time2
LED4
        decfsz    time4, F    ; see normal time0 comment above for this section
        goto    LED5
        movlw    led4l
        movwf    FSR
        call    _RANDOM
        movf    led2h, W
        iorlw    CALMHOLDMIN
        andlw    CALMHOLDMAX
        movwf    time4
LED5
        decfsz    time5, F    ; see normal time0 comment above for this section
        goto    WINDCHECK
        movlw    led5l
        movwf    FSR
        call    _RANDOM
        movf    led4h, W
        iorlw    CALMHOLDMIN
        andlw    CALMHOLDMAX
        movwf    time5
        goto    WINDCHECK    ; done processing LED PRBS and dwell values


WINDLEDS
        ; conditions are windy
        decfsz    time0, F    ; see normal time0 comment above for this section
        goto    LED1W
        movlw    led0l
        movwf    FSR
        call    _RANDOM
        movf    led5h, W
        iorlw    WINDHOLDMIN
        andlw    WINDHOLDMAX
        movwf    time0
LED1W
        decfsz    time1, F    ; see normal time0 comment above for this section
        goto    LED2W
        movlw    led1l
        movwf    FSR
        call    _RANDOM
        movf    led0h, W
        iorlw    WINDHOLDMIN
        andlw    WINDHOLDMAX
        movwf    time1
LED2W
        decfsz    time2, F    ; see normal time0 comment above for this section
        goto    LED4W
        movlw    led2l
        movwf    FSR
        call    _RANDOM
        movf    led1h, W
        iorlw    WINDHOLDMIN
        andlw    WINDHOLDMAX
        movwf    time2
LED4W
        decfsz    time4, F    ; see normal time0 comment above for this section
        goto    LED5W
        movlw    led4l
        movwf    FSR
        call    _RANDOM
        movf    led2h, W
        iorlw    WINDHOLDMIN
        andlw    WINDHOLDMAX
        movwf    time4
LED5W
        decfsz    time5, F    ; see normal time0 comment above for this section
        goto    WINDCHECK
        movlw    led5l
        movwf    FSR
        call    _RANDOM
        movf    led4h, W
        iorlw    WINDHOLDMIN
        andlw    WINDHOLDMAX
        movwf    time5
        goto    WINDCHECK

;-----------------------------------------------------------------------------------------------------------
;Determine if a wind gust is going by and calulate durations
WINDCHECK
;-----------------------------------------------------------------------------------------------------------
        incfsz    wind, W        ; check if wind is set add 1 if not 0 goto wind code
        goto    WIND
        ; no wind is present wait for timeout then enable wind
        decfsz    windcntl, F    ; check the no wind timer if time for next event
        goto    TIMERWAIT
        decfsz    windcnth, F    ; check the no wind timer if time for next event
        goto    TIMERWAIT
        movlw    0x42    ; time to go into wind mode (dim leds + fast flicker)
        movwf    wind
        ; set up the length of the wind gust
        movf    led0h, W    ; grab new wind starttime
        iorlw    WINDMINLEN    ; min length of wind
        andlw    WINDMAXLEN    ; max length of wind
        movwf    windcnth    ; store gust length
        goto    TIMERWAIT    ; done processing wind time

WIND
        ; in a wind gust wait for time out then calculate calm
        decfsz    windcntl, F    ;Determine if a wind gust is going by
        goto    TIMERWAIT
        decfsz    windcnth, F    ;Determine if a wind gust is going by
        goto    TIMERWAIT
        ; enable the calm
        movlw    0xFF        ; time to exit wind mode (bright leds + slow flicker)
        movwf    wind
        ; set up the lenght of the calm
        movf    led0h, W    ; grab new wind endtime
        iorlw    CALMMINLEN    ; min length of wind
        andlw    CALMMAXLEN    ; max length of wind
        movwf    windcnth    ; store clam lenght

;-----------------------------------------------------------------------------------------------------------
; if the value of the timer is still 0 wait for it to increment by 1 before continuing
TIMERWAIT
;-----------------------------------------------------------------------------------------------------------
        movf    TMR0, W        ; grab the current value of the timer
        andlw    DIMSTEPS    ; apply dimming step mask
        btfsc    STATUS, Z    ; wait for the timer to count off 0
        goto    TIMERWAIT    ; if 0 loop till not
        goto    STARTOFCODE    ; go to the start of the loop

;-----------------------------------------------------------------------------------------------------------
; catch all loop to prevent runaway code
;-----------------------------------------------------------------------------------------------------------
ENDLOOP
        goto    ENDLOOP

;####################################
; functions
;####################################

;*************************************************************
; 16 bit random number generator PRBS LSR modified from AN544
_RANDOMLONG
;*************************************************************
        movf    INDF, W        ; get the low byte
        movwf    temp0        ; save it to a temp var
        rrf        temp0, W    ; Wreg = Q12
        incf    FSR, F        ; high byte
        xorwf    INDF, W        ; Wreg = xor(Q12,Q3)
        movwf    temp1        ; temp(bit3) = xor(Q12,Q3)
        swapf    temp1, F    ; temp(bit7) = xor(Q12,Q3)
        rlf        temp0, F    ; Wreg = Q14
        xorwf    temp0, F    ; Wreg = xor(Q15,Q14)
        xorwf    temp1, F    ; temp(bit7) = xor(Q15,Q14,Q12,Q3)
        rlf        temp1, W    ; cflag = xor(Q15,Q14,Q12,Q3)
        rlf        INDF, F        ; move bit7 to new bit0 and then..
        rlf        temp0, F    ; ..rotate RNG value to the left
        decf    FSR, F        ; low byte
        movf    temp0, W    ; grab low byte
        movwf    INDF        ; save it back
        retlw    0x00        ; return from interrupt


        de  CODE_VER_STRING
        end
 
here is the datasheet for the part the code was written for, it may help when altering for your part
 

Attachments

  • 12f508.pdf
    1.5 MB · Views: 250
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top