天堂草原最受欢迎的角色,天堂动漫,天堂在线,色天堂下载,天堂中文在线资源,亚洲男人天堂

技術(shù)熱線: 4007-888-234

專注差異化嵌入式產(chǎn)品解決方案 給智能產(chǎn)品定制注入靈魂給予生命

提供開發(fā)工具、應(yīng)用測試 完善的開發(fā)代碼案例庫分享

從全面的產(chǎn)品導(dǎo)入到強大技術(shù)支援服務(wù) 全程貼心伴隨服務(wù),創(chuàng)造無限潛能!

技術(shù)支持

PIC單片機實現(xiàn)帶反饋控制的PWM信號發(fā)生器源碼

更新時間: 2019-03-23

十年專注單片機方案開發(fā)的方案公司英銳恩,分享PIC單片機實現(xiàn)帶反饋控制的PWM信號發(fā)生器源碼。英銳恩現(xiàn)提供服務(wù)產(chǎn)品涉及主控芯片:8位單片機、16位單片機、32位單片機及各類運算放大器等。

這個實現(xiàn)了一個帶反饋控制的PWM發(fā)生器。PWM信號的占空比由電位器決定,電位器上的電壓被采樣后,與PWM信號經(jīng)過低通濾波的電壓比較,根據(jù)比較的結(jié)果調(diào)整占空比,從而實現(xiàn)用電位器控制占空比。

    LIST p=PIC16F877A,r=hex    ;microcontroller & base
    INCLUDE    "P16F877A.inc"    ;register memory mapping file

;************************
; global variables
;************************
i        equ        0x21        ;general purpose counter 1
j        equ        0x22            ;general purpose counter 2
pot_ana_value    equ        0x23        ;Analog value of the potentiometer
pwm_ana_value    equ        0x24        ;Analog value of the PWM output after low filtering
#define        timer_trigger    0x25,    0    ;This bit indicating the timer has been triggered
w_temp        equ        0x26        ; temp variable for W register
status_temp    equ        0x27        ; status variable for STATUS register
temp        equ        0x28        ; general temp 


variable;************************
; port definitions
;************************
#define        led_data    PORTD        ;portD outputs 7-segment data
#define        led_pot_high    PORTB,    0    ;portB.0 selects high 4-bit value of pot
#define        led_pot_low    PORTB,    1    ;portB.1 selects low 4-bit value of pot
#define        led_pwm_high    PORTB,    2    ;portB.2 selects high 4-bit value of pwm
#define        led_pwm_low    PORTB,    3    ;portB.3 selects low 4-bit value of pwm
#define        led_inc        PORTB,    4    ;portB.4 drive the LED indicating PWM
                        ;duty cycle increasing.
#define        led_dec        PORTB,    5    ;portB.5 drive the LED indicating PWM
                        ;duty cycle decreasing.

;************************
; reload value of TMR0
; Timer 0 Interval = 5000 us
; 64 * ( 256 - TMR0 ) = 5000, TMR0 = 178 (0xB2);************************
tmr0_reload    equ    0xB2

;************************
; 7-segment LED definitions
;               a
;         +----------+
;         |          |
;        f|          |b
;         |     g    |
;         +----------+
;         |          |
;        e|          |c
;         |          |
;         +----------+ o dp
;              d 
;************************
LED_SEGa    equ    0x40    ;7-segment display segment A

LED_SEGb    equ    0x20    ;7-segment display segment B
LED_SEGc    equ    0x10    ;7-segment display segment C
LED_SEGd    equ    0x08    ;7-segment display segment D
LED_SEGe    equ    0x04    ;7-segment display segment ELED_SEGf    equ    0x02    ;7-segment display segment F
LED_SEGg    equ    0x01    ;7-segment display segment G
LED_SEGdp    equ    0x80    ;not used
LED_BLANK    equ    0x00


;****************************************************************
;reset vector
;****************************************************************
ResetVec:   
    org    0x0000            ;reset vector address   
    goto    Start            ;start program execution

    org    0x0004
Tmr0IntServ:                ; Timer 0 interrupt service routing

 movwf    w_temp            ; save W register
    swapf    STATUS, W    clrf    STATUS
    movwf    status_temp        ; save STATUS register
   
    bcf    INTCON, T0IF        ; clear Timer 0 interrupt flag
    bsf    timer_trigger
    movlw    tmr0_reload        ; reload timer 0
    movwf    TMR0           
   
    swapf    status_temp, W
    movwf    STATUS            ; restore STATUS register
    swapf    w_temp, F
    swapf    w_temp, W        ; restore W register
    retfie

Start:    org     0x0100            ;start of program
    goto    SysInit


;****************************************************************

; LED DISPLAY DECODER FROM BINARY TO 7-SEGMENT
; the hex value to be displayed is stored in W before calling this
; function. The function will return the output value of LED in W
;****************************************************************
LEDDecoder:
    addwf    PCL,f                                ;W   DISPLAY
    retlw    LED_SEGa|LED_SEGb|LED_SEGc|LED_SEGd|LED_SEGe|LED_SEGf        ;0 - "0"
    retlw    LED_SEGb|LED_SEGc                        ;1 - "1"
    retlw    LED_SEGa|LED_SEGb|LED_SEGd|LED_SEGe|LED_SEGg            ;2 - "2"
    retlw    LED_SEGa|LED_SEGb|LED_SEGc|LED_SEGd|LED_SEGg            ;3 - "3"
    retlw    LED_SEGb|LED_SEGc|LED_SEGf|LED_SEGg                ;4 - "4"

 retlw    LED_SEGa|LED_SEGc|LED_SEGd|LED_SEGf|LED_SEGg            ;5 - "5"
    retlw    LED_SEGa|LED_SEGc|LED_SEGd|LED_SEGe|LED_SEGf|LED_SEGg        ;6 - "6"
    retlw    LED_SEGa|LED_SEGb|LED_SEGc                    ;7 - "7"
    retlw    LED_SEGa|LED_SEGb|LED_SEGc|LED_SEGd|LED_SEGe|LED_SEGf|LED_SEGg    ;8 - "8"
    retlw    LED_SEGa|LED_SEGb|LED_SEGc|LED_SEGd|LED_SEGf|LED_SEGg        ;9 - "9"
    retlw    LED_SEGa|LED_SEGb|LED_SEGc|LED_SEGe|LED_SEGf|LED_SEGg        ;0xA - "A"
    retlw    LED_SEGc|LED_SEGd|LED_SEGe|LED_SEGf                ;0xB - "b"
    retlw    LED_SEGa|LED_SEGd|LED_SEGe|LED_SEGf                ;0xC - "C"

 retlw    LED_SEGb|LED_SEGc|LED_SEGd|LED_SEGe|LED_SEGg            ;0xD - "d"
    retlw    LED_SEGa|LED_SEGd|LED_SEGe|LED_SEGf|LED_SEGg            ;0xE - "E"
    retlw    LED_SEGa|LED_SEGe|LED_SEGf|LED_SEGg                ;0xF - "F"
    retlw    LED_BLANK                            ;0x10- " "
;****************************************************************
; System initialization

;****************************************************************
SysInit:
    bcf    STATUS, RP1
    bsf    STATUS,    RP0
    clrf    TRISB            ;portB output
    clrf    TRISC            ;portC output
    clrf    TRISD            ;portD output
    movlw    0xff
    movwf    TRISA            ;portA input

    bcf    STATUS, RP0        ;set initial value of the I/O ports
    clrf    PORTB
    clrf    PORTD
    clrf    PORTC    bcf    timer_trigger       

; Timer 0 config
    movlw    tmr0_reload        ; timer 0 initial value
    movwf    TMR0           
    bsf    STATUS, RP0
    movlw    0x05            ; timer 0 freq div = 64, use internal clock
    movwf    OPTION_REG    

; PWM config
    movlw    0xff            ; PWM cycle = 256us   
    movwf    PR2
    bcf    STATUS, RP0
    movlw    0x80            ; CCP1RL initial value, 50% duty cycle
    movwf    CCPR1L
    movlw    0x0C            ; PWM mode for CCP1
    movwf    CCP1CON
    movlw    0x04            ; T2 control: 1:1 freq div, enable T2
    movwf    T2CON
; ADC config
    bsf    STATUS,    RP0
    clrf    ADCON1            ; left alignment, 8 analog channel
    bcf    STATUS, RP0
    movlw    0x81            ; Focs/32 A/D clock freq, 

enable ADC
    movwf    ADCON0       

; Interrupt config
    movlw    0xA0
    movwf    INTCON            ; enable Timer 0 interrupt


;****************************************************************
; The main loop of the program
;****************************************************************
Mainloop:    btfsc    timer_trigger
    call    AdjustPWM
    call    ScanLED

    goto    Mainloop        ;endless loop


;****************************************************************
; Adjust PWM duty cycle
;****************************************************************
AdjustPWM:

 bcf    timer_trigger
    call    UpdateAnalogValue
    movf    pot_ana_value,    W
    subwf    pwm_ana_value,    W
    btfss    STATUS,    Z
    goto    need_adjustment
no_adjustment:
    bcf    led_inc            ; equal, no adjustment needed
    bcf    led_dec            ; turn-off the LEDs
    returnneed_adjustment:
    btfss    STATUS,    C
    goto    need_decreament
    movlw    0xff            ; need increament
    subwf    CCPR1L,    W
    btfsc    STATUS, Z       
    goto    no_adjustment        ; if CCPR1L = 0xff, can't increase any more
    bsf    led_inc

 bcf    led_dec
    incf    CCPR1L,    F
    return
need_decreament
    movlw    0x00
    subwf    CCPR1L,    W
    btfsc    STATUS, Z
    goto    no_adjustment        ; if CCPR1L = 0x00, can't decrease any more
    bsf    led_dec
    bcf    led_inc
    decf    CCPR1L,    F
    return;****************************************************************
; SCAN the 7-Segment LEDs
;****************************************************************
ScanLED:

  movf    pot_ana_value,    W
    andlw    0x0f            ; low 4-bit
    call    LEDDecoder
    movwf    led_data        ; output value
    bsf    led_pot_low
    movlw    0x32
    call    Delayx10us        ; delay 500us
    bcf    led_pot_low

    swapf    pot_ana_value,    W    ; high 4-bit pot analog value
    andlw    0x0f           
    call    LEDDecoder    movwf    led_data
    bsf    led_pot_high
    movlw    0x32
    call    Delayx10us
    bcf    led_pot_high

 movf    pwm_ana_value,    W    ; low 4-bit pwm analog value
    andlw    0x0f
    call    LEDDecoder
    movwf    led_data
    bsf    led_pwm_low
    movlw    0x32

call    Delayx10us
    bcf    led_pwm_low

    swapf    pwm_ana_value,    W    ; high 4-bit pwm analog value
    andlw    0x0f
    call    LEDDecoder
    movwf    led_data
    bsf    led_pwm_high
    movlw    0x32
    call    Delayx10us
    bcf    led_pwm_high
    return

;****************************************************************
UpdateAnalogValue:

 bcf    ADCON0,    CHS0    ; select RA0 for analog input, POT value
    movlw    0x03
    call    Delayx10us    ; delay for 30us
    bsf    ADCON0, GO_DONE
UAV_loop1:
    btfsc    ADCON0, GO_DONE    ; wait for A/D conversion
    goto    UAV_loop1     movf    ADRESH, W
    movwf    pot_ana_value    ; update value

    movlw    0x03        ; delay 30us for next conversion
    call    Delayx10us

    bsf    ADCON0, CHS0    ; select RA1 for analog input, PWM value
    movlw    0x03
    call    Delayx10us    ; delay for 30us
    bsf    ADCON0, GO_DONE
UAV_loop2:
    btfsc    ADCON0, GO_DONE    ; wait for A/D conversion
    goto    UAV_loop2
    movf    ADRESH,    W
    movwf    pwm_ana_value    ; update value

    return        

    END

(文源網(wǎng)絡(luò),侵刪)


404
返回首頁 |  返回上一頁
联系我们: 格尔木市| 伊金霍洛旗| 桂平市| 新昌县| 准格尔旗| 施秉县| 綦江县| 越西县| 塔城市| 合川市| 台江县| 大石桥市| 桦川县| 金坛市| 博爱县| 宣武区| 五家渠市| 宜良县| 年辖:市辖区| 宁陕县| 田林县| 徐闻县| 泰兴市| 肃北| 遂昌县| 平和县| 江口县| 吴川市| 南郑县| 齐河县| 宜兰市| 衡水市| 房产| 关岭| 胶南市| 乡城县| 济源市| 改则县| 石门县| 磴口县| 温州市|