pic16f874步进电机程序

发布者:科技创造者最新更新时间:2017-12-04 来源: eefocus关键字:pic16f874  步进电机程序 手机看文章 扫描二维码
随时随地手机看文章

pIC16f874步进电机程序

    list    p=16f874 
    include  


; --==*[ CONSTANTS ]*==--

#define        COMMAND_2    ’B’ 
#define        COMMAND_3    ’C’ 
#define        COMMAND_4    ’D’ 


; --==*[ VARIABLES ]*==-- 
cmdNum        equ    0x20            ; command number. 0xFF for invalid command 
recByte        equ    0x21            ; received byte 

motorL        equ    0x22            ; motor data - low byte 
motorH        equ    0x23            ; motor data - high byte 

byteCnt        equ    0x24            ; internal counter for byte counting during reception 

tickL        equ    0x25            ; ticks: low byte 
tickH        equ    0x26            ; ticks: high byte 
result1L    equ    0x27            ; result: this one is needed for storage of ticks 
result1H    equ    0x28 

winkelL        equ    0x29            ; winkel: tick counter without overflow check etc. 
winkelH        equ    0x30 

quad        equ    0x31            ; quadrature signal, for direction storage 
oldb        equ    0x32            ; old value of PORTB 
newb        equ    0x33            ; new value of PORTB 

tmr0o0        equ    0x34            ; tmr0 overflow counter 0 
tmr0o1        equ    0x35            ; tmr0 overflow counter 1 

wtemp1        equ    0x60            ; storage for the W register (rbif) 
wtemp2        equ    0x61            ; storage for the W register (CCp2if) 
wteMP3        equ    0x62            ; storage for the W register (rcif) 
wtemp4        equ    0x63            ; storage for the W register (usart error routines) 


    org    0x00                ; --==*[ RESET VECTOR ]*==-- 
    b    main 

    org    0x04                ; --==*[ INT VECTOR ]*==-- 
    b    int_handler 

    org    0x05                ; --==*[ MAIN PROGRAM ]*==-- 
main: 
    ; --==*[ VARIABLES - initialize ]*==-- 
    MOVlw    0xFF 
    MOVwf    cmdNum 
    clrf    motorL 
    clrf    motorH 
    clrf    tickL 
    clrf    tickH 
    clrf    result1L 
    clrf    result1H 
    clrf    winkelL 
    clrf    winkelH 
    clrf    quad 
    clrf    oldb 
    clrf    newb 
    clrf    tmr0o0 
    clrf    tmr0o1 

    ; --==*[ PORTS - setup port B ]*==-- 
    clrf    PORTB 
    bsf    STATUS, RP0            ; PIN 4 and 5 as input (photo-interrupter signals) 
    MOVlw    b’00110000’            ; pin 1 has to be an output (direction signal) 
    MOVwf    TRISB                ; all other pins are outputs, too (default) 
    bcf    STATUS, RP0 

    ; --==*[ PORTS - setup port C ]*==-- 
    clrf    PORTC 
    bsf    STATUS, RP0 
    MOVlw    b’11111011’            ; pin 2 as output (PWM signal) 
    MOVwf    TRISC                ; pins 6 and 7 have to be inputs (default) 
    bcf    STATUS, RP0            ; all other pins are inputs, too  (default) 

    ; --==*[ CCP1 - setup PWM Module ]*==-- 
    bsf    STATUS, RP0 
    MOVlw    d’249’                ; pwm period (calculated with formula) 
    MOVwf    PR2 
    bcf    STATUS, RP0            ; duty cycle = 0 
    clrf    CCPR1L                ; CCPR1L is upper 8 (bit: 9...2) bits of duty cycle 
    MOVlw    b’00000101’            ; enable timer2 (bit: 2) and set prescale of 1:4 (bit: 0-1) 
    MOVwf    T2CON                ; timer2 is important for pwm operation! 
    MOVlw    b’00001111’            ; select pwm mode for ccp1 module (bit: 0-3) 
    MOVwf    CCP1CON                ; and reset lower two bits of duty cycle (bit: 4-5) 

    ; --==*[ USART - setup ]*==-- 
    bsf    STATUS, RP0 
    MOVlw    0x40                ; configure baud generator register (calculated with formula) 
    MOVwf    SPBRG                ; with: 9600 baud, no parity, 8 data bits, no handshake 
    MOVlw    b’00100100’            ; enable trasmit (bit: 5) and high speed baud rate (bit: 2) 
    MOVwf    TXSTA 
    bcf    STATUS, RP0 
    MOVlw    b’10010000’            ; enable serial port (bit: 7) and continuous reception (bit: 4) 
    MOVwf    RCSTA 
    clrw                    ; w = 0 
    MOVwf    RCREG                ; reset UART receiver and fifo 
    MOVwf    RCREG                ; so we CAN avoid receive/framing/overrun errors at the beginning 
    MOVwf    RCREG 
    MOVwf    TXREG                ; just in case:     the txif flag is now valid (=1; avoids infinite loops in sendByte) 

    ; --==*[ TIMER 0 - setup ]*==-- 
    bsf    STATUS, RP0            ; this is tricky; prescaler has to be assigned to the WDT, 
                        ; in case you want to achieve 1:1 prescale 
    bcf    OPTION_REG, PS0            ; first, set prescaler to 1:2 
    bcf    OPTION_REG, PS1 
    bcf    OPTION_REG, PS2 
    bsf    OPTION_REG, PSA            ; then, assign prescaler to wdt; now we have a 1:1 prescale for timer0 :-) 
    bcf    OPTION_REG, T0SE 
    bcf    OPTION_REG, T0CS 
    bcf    STATUS, RP0 

    ; --==*[ INTERRUPTS - setup ]*==-- 
    bsf    STATUS, RP0 
    clrf    PIE1 
    bsf    PIE1, RCIE            ; enable "receive byte" interrupt 
    bcf    STATUS, RP0 
    clrf    INTCON                ; reset all interrupt flags 
    bsf    INTCON, RBIE            ; enable "interrupt on change" interrupt 
    bsf    INTCON, T0IE            ; enable "timer0 overflow" interrupt 
    bsf    INTCON, PEIE            ; enable peripheral interrupts 
    bsf    INTCON, GIE            ; enable global interrupts 

    ; --==*[ MAIN LOOP ]*==-- 
loop: 
    b        loop 


; --==*[ sendByte - ROUTINE ]*==-- 
sendByte:                    ; send byte (which is stored in W) 
sendByte_l0:                    ; wait until new data arrived in txreg 
    btfss    PIR1, TXIF            ; (inDICated via transmit interrupt flag bit: txif) 
    b        sendByte_l0 
sendByte_l1: 
    MOVwf    TXREG                ; send new data 
    return 


; --==*[ INTERRUPT HANDLING ROUTINE ]*==-- 
int_handler: 
    btfsc    RCSTA, OERR            ; overflow error occured, handle it 
    b    err_Overflow 
    btfsc    RCSTA, FERR            ; framing error occured, handle it 
    b    err_Frame 
    btfsc    PIR1, RCIF            ; receive interrupt: rcif 
    b    int_USART_receive 
    btfsc    INTCON, RBIF            ; pin interrupt: rbif 
    b    int_RB_change 
    btfsc    INTCON, T0IF            ; tmr0 interrupt: t0if 
    b    int_timer0_reset 
    retfie 

int_RB_change: 
    incf    tickL, 1            ; increment ticks (low byte) 
    btfsc    STATUS, Z 
    incf    tickH, 1            ; increment ticks on overflow (high byte) 
    incf    winkelL, 1            ; same as tick, but will not be reset (eichungswert) 
    btfsc    STATUS, Z 
    incf    winkelH, 1 
    MOVwf    wtemp1                ; save W 
    MOVfw    PORTB 
    MOVwf    newb                ; newb = PORTB 
    MOVlw    b’00110000’            ; and mask 
    andwf    oldb, 1                ; reset all bits except 4 and 5 
    andwf    newb, 1                ; reset all bits except 4 and 5 
    clrf    quad                ; reset quad value 
    clrw                    ; oldb == 00 ? 
    subwf    oldb, W 
    bz    o00 
    MOVlw    b’00010000’            ; oldb == 01 ? 
    subwf    oldb, W 
    bz    o01 
    MOVlw    b’00100000’            ; oldb == 10 ? 
    subwf    oldb, W 
    bz    o10 
    b    o11                ; else, oldb == 11 
o00: 
    MOVlw    b’00010000’            ; newb == 01 ? 
    subwf    newb, W 
    bnz    quit 
    bsf    quad, 7                ; left 
    b    quit 
o01: 
    MOVlw    b’00110000’            ; newb == 11 ? 
    subwf    newb, W 
    bnz    quit 
    bsf    quad, 7                ; left 
    b    quit 
o10: 
    clrw                    ; newb == 00 ? 
    subwf    newb, W 
    bnz    quit 
    bsf    quad, 7                ; left 
    b    quit 
o11: 
    MOVlw    b’00100000’            ; newb == 10 ? 
    subwf    newb, W 
    bnz    quit 
    bsf    quad, 7                ; left 
quit: 
    MOVfw    PORTB 
    MOVwf    oldb                ; oldb = PORTB 
    MOVfw    wtemp1                ; restore W 
    bcf    INTCON, RBIF            ; reset interrupt (important) 
    retfie 


int_timer0_reset: 
    btfsc    tmr0o0, 7            ; wait 128 overflows 
    goto    a1 
    incf    tmr0o0, 1 
    goto    a0 
a1: 
    btfsc    tmr0o1, 6            ; wait 64 overflows 
    goto    a4 
    incf    tmr0o1, 1 
    goto    a0 
a4: 
    btfsc    PORTB, 7            ; a short hack, so we can measure the impulses 
    goto    next1                ; of timer0 with an oscillograph 
    bsf    PORTB, 7            ; signal is on bit 7 of portb 
    goto    mainl 
next1: 
    bcf    PORTB, 7 
mainl: 
    MOVwf    wtemp2                ; save W 
    MOVfw    tickL                ; store ticks in result1 
    MOVwf    result1L 
    MOVfw    tickH 
    MOVwf    result1H 

    MOVfw    quad                ; and blend the direction bit on MSB of result1 
    iorwf    result1H, 1 

    clrf    tickH                ; clear tick counter 
    clrf    tickL 
    clrf    tmr0o0                ; clear timer0 overflow counters 
    clrf    tmr0o1 
    MOVfw    wtemp2                ; restore W 
a0: 
    bcf    INTCON, T0IF            ; reset interrupt (important) 
    retfie 


int_USART_receive: 
    MOVwf    wtemp3                ; save W 
    MOVlw    COMMAND_3            ; command3 active ? 
    subwf    cmdNum, W 
    bz    getData_command3        ; yes, handle it 
    MOVfw    RCREG                ; store received byte 
    clrf    RCREG                ; it’s a good idea to flush the buffer 
    clrf    RCREG                ; after receiving a byte, so it’s 
    clrf    RCREG                ; forced that we have a new byte in the buffer in the next step 
    MOVwf    recByte 
    MOVlw    COMMAND_2            ; -execute command2 ? 
    subwf    recByte, W 
    bz    command2            ;  yes, do it 
    MOVlw    COMMAND_3            ; -execute command3 ? 
    subwf    recByte, W 
    bz    command3            ;  yes, do it 
    MOVlw    COMMAND_4            ; -execute command4 ? 
    subwf    recByte, W 
    bz    command4            ;  yes, do it 

commandUnknown:                    ; else, received byte is unknown 
    bsf    PORTB, 0            ; show error on LED
    MOVfw    wtemp3                ; restore W 
    retfie 

; --==*[ COMMAND EXEC - transmit motor data in debug mode ]*==-- 
command2: 
    MOVfw    result1H 
    call    sendByte 
    MOVfw    result1L 
    call    sendByte 
    MOVfw    winkelH 
    call    sendByte 
    MOVfw    winkelL 
    call    sendByte 
    MOVfw    wtemp3                ; restore W 
    retfie 

; --==*[ COMMAND INIT - setup for receive motor data (part 1/2) ]*==-- 
command3:                    ; command3 
    MOVlw    COMMAND_3 
    MOVwf    cmdNum                ; cmdNum contains now the current command value 
    MOVlw    .2 
    MOVwf    byteCnt                ; we want exactly 2 bytes from the pc 
    MOVfw    wtemp3                ; restore W 
    retfie 

; --==*[ COMMAND EXEC - receive motor data (part 2/2) ]*==-- 
getData_command3: 
    decf    byteCnt, 1            ; handle byte counter 
    bz    c3_b2                ; if byte counter is 0 then it is the 2nd byte 
    MOVfw    RCREG                ; else, 1st byte receive 
    MOVwf    motorL                ; store in motorL 
    b    outhere                ; and exit 
c3_b2: 
    MOVfw    RCREG                ; 2nd byte receive 
    MOVwf    motorH                ; store in motorH 
    MOVlw    0xFF                ; reset cmdNum to undefined value (0xFF) 
    MOVwf    cmdNum 
                        ; reconfigure PWM 
    MOVfw    motorH 
    MOVwf    CCPR1L                ; store high byte (8; bits 9 - 2) 
    bcf    CCP1CON, CCP1Y 
    btfsc    motorL, 0            ; store low byte (2; bits 0) 
    bsf    CCP1CON, CCP1Y 
    bcf    CCP1CON, CCP1X 
    btfsc    motorL, 1            ; store low byte (2; bits 1) 
    bsf    CCP1CON, CCP1X 
    btfss    motorL, 2            ; motorL<2> bit is significant for motor direction 
    b    turn_left 
    bsf    PORTB, 1            ; turn motor right 
    b    outhere 
turn_left: 
    bcf    PORTB, 1            ; turn motor left 
outhere: 
    MOVfw    wtemp3                ; restore W 
    retfie 


; --==*[ COMMAND EXEC - transmit motor data ]*==-- 
command4: 
    MOVfw    result1H            ; transmit high byte 
    call    sendByte 
    MOVfw    result1L            ; transmit low byte 
    call    sendByte 
    MOVfw    wtemp3                ; restore W 
    retfie 


; --==*[ ERROR HANDLING - for the serial communication ]*==-- 
err_Overflow:                    ; handle overflow error 
    MOVwf    wtemp4                ; save W 
    bsf    PORTB, 7            ; show error on leds (10) 
    bcf    PORTB, 6 
    bcf    RCSTA, CREN            ; dISAble continuous reception 
    MOVf    RCREG, W            ; flush receive fifo buffer (3 bytes deep) 
    MOVf    RCREG, W 
    MOVf    RCREG, W 
    bsf    RCSTA, CREN            ; reenable continuous reception 
    MOVfw    wtemp4                ; restore W 
    retfie 
err_Frame:                    ; handle frame error 
    MOVwf    wtemp4                ; save W 
    bcf    PORTB, 7            ; show error on leds (01) 
    bsf    PORTB, 6 
    MOVf    RCREG, W            ; flush receive fifo buffer (3 bytes deep) 
    MOVf    RCREG, W 
    MOVf    RCREG, W 
    MOVfw    wtemp4                ; restore W 
    retfie 


    end 


关键字:pic16f874  步进电机程序 引用地址:pic16f874步进电机程序

上一篇:pic12C508 DTMF拔号程序
下一篇:pic16f508步进电机程序

推荐阅读最新更新时间:2024-03-16 15:48

步进电机定位控制系统VHDL程序与仿真
步进电机定位控制系统VHDL程序与仿真 library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; entity step_motor is port (reset:in STD_LOGIC; --系统复位信号 dir: in STD_LOGIC; --方向控制信号 clk: in STD_LOGIC; --系统时钟信号 ini: in STD_LOGIC; --初始化使能信号 manner: in STD_LOGIC_VECTOR (1 dow
[嵌入式]
用AT89C51单片机控制步进电机的汇编源程序
  下面程序完成的主要功能:实现步进电机的正反转,加速、减速;显示电机转速(转速级别)和工作状态(正转、反转、不转)。   源程序   SPEED EQU 10H ;SPEED为转速等级标志,共7级,即1~7   FX EQU 11H ;FX 为方向标志   COUNT EQU 12H ;COUNT中断次数标志   ORG 0000H   AJMP MAIN   ORG 0003H ;外部中断0入口地址,加速子程序   AJMP UP   ORG 0013H ;外部中断1入口地址,减速子程序   AJMP DOWN   ORG 000BH ;定时器0中断入口地址,控制中断次数来达到控制转速 AJMP ZDT0
[单片机]
基于Linux的C02激光雕刻系统步进电机驱动程序
随着嵌入式技术的不断成熟,基于嵌入式系统编写特制电路下的设备驱动程序也越来越受到人们的青睐。在各种嵌入式操作系统中,嵌入式Linux是免费的源代码开放软件,可根据需要任意进行剪裁。在嵌入式Linux开发过程中需要为指定设备编写和编译驱动程序,这与以往在PC机上的Linux驱动开发明显不同,本文设计了基于S3C2440嵌入式Linux下激光雕刻系统的步进电机驱动程序。 1 硬件系统的设计 步进电机开环控制系统主要由中央控制器、步进电机驱动器、传感器以及步进电机四大部分组成。本系统采用基于ARM920t内核的S3C244 0A微处理器作为控制系统的中央控制器,该芯片主频400MHz,最高可达到533MHz,内含多种设备接口
[工业控制]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved