How to create PWM feature using normal pin

Discussion in 'Embedded Systems and Microcontrollers' started by dave3344, Nov 19, 2014.

  1. dave3344

    Thread Starter New Member

    Nov 19, 2014
    4
    0
    I wanted to control the speed of my fan without using PWM configuration
    My lecturer say it can be done by set the time of turning on and off the fan using L293D
    so I do this program code but it doesn't seem worked, so anyone can provide some help??
    By the way I am new in programing microcontroller
    Sorry for my broken English

    Code (Text):
    1. list p=16f877a
    2. include "p16f877a.inc"
    3. __CONFIG _LVP_OFF & _WDT_OFF & _HS_OSC & _PWRTE_ON & _BODEN_OFF
    4.  
    5. count1         equ          20h
    6. count2         equ         21h
    7. count3         equ         22h
    8. count0         equ         23h
    9. temp            equ         24h
    10.  
    11.             org               0x0000
    12.             banksel        TRISB
    13.             clrf               TRISB
    14.             banksel        TRISC
    15.             clrf               TRISC
    16.             banksel        TRISD
    17.             clrf               TRISD
    18.             banksel        TRISA
    19.             bsf                TRISA,0
    20.        
    21.             banksel        PORTB
    22.             clrf              PORTB
    23.             banksel        ADCON1
    24.             movlw        b'01001110'
    25.             movwf        ADCON1
    26.             banksel        ADCON0
    27.             movlw        b'10000001'
    28.             movwf        ADCON0
    29.  
    30. acqtime:    call         delay50u
    31.                    bsf            ADCON0,GO_DONE
    32.  
    33. main:        btfsc        ADCON0,GO_DONE
    34.             goto        $-1
    35.             movf        ADRESH,W
    36.             movwf        temp
    37.             call        delayqsec
    38.             call         check
    39.             goto        acqtime
    40.  
    41. check:        movlw        d'20'
    42.             subwf        temp,0
    43.             btfss        STATUS,0
    44.             goto        temp0
    45.  
    46.             movlw        d'25'
    47.             subwf        temp,0
    48.             btfss        STATUS,0
    49.             goto        temp40
    50.  
    51.             movlw        d'30'
    52.             subwf        temp,0
    53.             btfss        STATUS,0
    54.             goto        temp50
    55.             goto        temp60
    56.             return
    57.        
    58. temp0:    
    59.             banksel        PORTB
    60.             clrf        PORTB
    61.             banksel        PORTC
    62.             bcf            PORTC,2
    63.             banksel        PORTD
    64.             bcf            PORTD,0
    65.             bcf            PORTD,1
    66.             return
    67.  
    68. temp40:        movlw        b'00000010'
    69.             banksel        PORTB
    70.             movwf        PORTB
    71.             banksel        PORTD
    72.             bsf            PORTD,0
    73.             bcf            PORTD,1
    74.             banksel        PORTC
    75.             bsf            PORTC,2
    76.             call         delay60u
    77.             bcf            PORTC,2
    78.             call        delay140u
    79.             return
    80.  
    81. temp50:        movlw        b'00000100'
    82.             banksel        PORTB
    83.             movwf        PORTB
    84.             banksel        PORTD
    85.             bsf            PORTD,0
    86.             bcf            PORTD,1
    87.             banksel        PORTC
    88.             bsf            PORTC,2
    89.             call        delay120u
    90.             bcf            PORTC,2
    91.             call        delay80u
    92.             return
    93.  
    94. temp60:        movlw        b'00010000'
    95.             banksel        PORTB
    96.             movwf        PORTB
    97.             banksel        PORTD
    98.             bsf            PORTD,0
    99.             bcf            PORTD,1
    100.             banksel        PORTC
    101.             bsf            PORTC,2
    102.             return
    103.  
    104. delay60u:    movlw        d'3'
    105.             movwf        count2
    106.             movlw        d'35'
    107.             movwf        count3
    108.             decfsz        count3,f
    109.             goto        $-1
    110.             decfsz        count2,f
    111.             goto        $-5
    112.             return
    113.  
    114. delay140u:    movlw        d'3'
    115.             movwf        count2
    116.             movlw        d'78'
    117.             movwf        count3
    118.             decfsz        count3,f
    119.             goto        $-1
    120.             decfsz        count2,f
    121.             goto        $-5
    122.             return
    123.  
    124. delay120u:  movlw        d'3'
    125.             movwf        count2
    126.             movlw        d'67'
    127.             movwf        count3
    128.             decfsz        count3,f
    129.             goto        $-1
    130.             decfsz        count2,f
    131.             goto        $-5
    132.             return
    133.  
    134. delay80u:   movlw        d'3'
    135.             movwf        count2
    136.             movlw        d'45'
    137.             movwf        count3
    138.             decfsz        count3,f
    139.             goto        $-1
    140.             decfsz        count2,f
    141.             goto        $-5
    142.             return
    143.  
    144. delayqsec:  movlw        d'7'
    145.             movwf        count1
    146.             movlw        d'255'
    147.             movwf        count2
    148.             movlw        d'255'
    149.             movwf        count3
    150.             decfsz        count3,f
    151.             goto        $-1
    152.             decfsz        count2,f
    153.             goto        $-5
    154.             decfsz        count1,f
    155.             goto        $-9
    156.             return
    157.  
    158. delay50u:    movlw        d'83'
    159.             movwf        count0
    160.             decfsz        count0,f
    161.             goto        $-1
    162.             return
    163.    
    164.             end
    165.  
    166.  
    167.  
    If u guys cannot understand any parts of my program, feel free to ask me :D
     
    Last edited: Nov 19, 2014
  2. dave3344

    Thread Starter New Member

    Nov 19, 2014
    4
    0
    this is my circuit diagram
    [​IMG]
     
  3. MrChips

    Moderator

    Oct 2, 2009
    12,446
    3,362
    That is PWM.
     
  4. dave3344

    Thread Starter New Member

    Nov 19, 2014
    4
    0
    he say can be done by using normal pins not ccp1 or ccp2....
     
  5. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    Yes, and the PWM he described does not need a hardware-implemented PWM signal. Simply time the toggling of a digital I/O pin according to the desired waveform and duty cycle.
     
  6. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    A couple of things I spotted:
    You have "goto temp0" but at the end of temp0 is "return", this will lead to stack underflow and unexpected results.
    Delayqsec looks like it will take a lot longer than delay50u, etc so the PWM duty cycle would be very small, it might not turn the fan
    Double check the banks, I like to step through the code in the simulator and check the right registers are changing.
     
  7. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,015
    PWM is nothing more than keeping a pin on for a period of time and off for a period of time.

    A lot easier to do in C IMHO but to each his own but the technique is the same C or assembler.

    Start small. Write a program that does nothing but turn a pin on.

    Write one that does nothing but turn a pin off.

    Next write a program that does a loop and turns the pin off and on. That alone will give you a 50% duty cycle.

    You should be able to step through the code and watch the pin go off and on or if you have a scope you can see it there too.

    Finally add in your delays. One before turning the pin on and one before turning it off.
     
  8. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,393
    497
    Choose a pin, turn it On, turn it Off. Now you have PWM.
    Keep it On long time, you have long duty cycle.
    Keep it On short time, you have short duty cycle.
    Any pin that can be configured for output will work.

    So yes, you don't need a specific PWM feature. Any output pin will do the job.
     
  9. dave3344

    Thread Starter New Member

    Nov 19, 2014
    4
    0
    thanks guys!! i fixed my errors and my circuit work perfectly now :D
     
Loading...