hi Darrel,
i found a good code for controlling 8 servo motors and i tried it.
its very awsome and it contains a pc sofware too.
unfortunatily, it is written in mokrobasic and it contains some assembly codes.
since i m new to pic microcontrollers and i use only PBP, i didnt understand the code and its procedure.
i wish i can understand it so i can make my own code using PBP and microcode studio. and also to programm my own vb software.
could u explain this code and how it define 20ms periods.. etc.
u can find attached the full folder containing pc software and also pic firmware.
here is the code:
Code:program SERVO8_USB_18F2550 '****************************************************************************************** '* 18F2550 PIC USB_HID 50Hz PWM SERVO CONTROLLER * '* by W. Schroeder alias "xor" -- July 4, 2006 * '* * '* Compiles with mikroBASIC 4.03 and tested on the EasyPIC3 Development Board * '* Uses mikroBASIC USB_HID Library and must include "USBdsc.pbas" and "HIDconstant.pbas" * '* * '* Also required is the free Visual Basic Servo Controller Demo program included with * '* this file. This program has been tested on Windows XP with USB2.0. * '* * * '* Configuration settings for the 18F2550 are the same as the mikroBASIC 18F2550 HID * '* example found in the mikroBASIC Examples folder in the mikroBASIC directory. * '* These configurations are set up for an 8MHz crystal oscillator and through internal * '* PLL settings this is increased to 48MHz. This also produces a very fast 12 MIPS. * '* * '* The EasyPIC3 board provides an easy connection to the PIC via a USB port. Please * '* refer to the board schematic for ideas for your own circuit connections. * '* * '* For the purposes of this demo all output pins of PORTB are utilized. * '* Servo0 is PORTB.0, Servo1 is PORTB.1, ......, Servo7 is PORTB.7 * '* * '* The range of PWM on-time is 800us to 2200us analogous with a resolution of 0 to 255 * '* A value of 127/128 is considered 50% of servo rotation with an on-time of 1500us * '* Timer0 in 16-bit mode is used to establish an accurate 20ms (50Hz) PWM interval * '* * '****************************************************************************************** '****************************************************************************************** include "USBdsc" ' this module must be included in the same folder as the main program dim T0 as word absolute $FD6 dim old as byte dim servoport as ^byte dim _s0,_s1,_s2,_s3,_s4,_s5,_s6,_s7 as byte dim wrbuf as byte[2] servo as byte[9] wr_adr as word sub procedure delay_810us delay_us(810) end sub sub procedure interrupt If INTCON.TMR0IF = 1 Then ' if 20ms interval servoport^ = 255 ' turn on all servos _s0 = servo[0] + 1 ' set up temp variables _s1 = servo[1] + 1 _s2 = servo[2] + 1 _s3 = servo[3] + 1 _s4 = servo[4] + 1 _s5 = servo[5] + 1 _s6 = servo[6] + 1 _s7 = servo[7] + 1 old = 0 FSR0L = servoport FSR0H = hi(servoport) delay_810us ' this delay to hold position 0 TMR0L = 0 For old = 0 to 255 ' manage 8 outputs with 256 positions each ASM ' very efficient PWM masking routine movlw 0 decfsz main_global__s0, 1,0 iorlw 1 decfsz main_global__s1, 1,0 iorlw 2 decfsz main_global__s2, 1,0 iorlw 4 decfsz main_global__s3, 1,0 iorlw 8 decfsz main_global__s4, 1,0 iorlw 16 decfsz main_global__s5, 1,0 iorlw 32 decfsz main_global__s6, 1,0 iorlw 64 decfsz main_global__s7, 1,0 iorlw 128 andwf INDF0, 1,0 END ASM While TMR0L = old ' wait until TMR0 increments Wend Next old ' all outputs are off at this point T0= -3600 ' balance of time for 20ms cycle INTCON.TMR0IF = 0 ' be ready to interrupt again for next interval Else HID_InterruptProc End If end sub sub procedure Init_Main INTCON2 = 0xF5 INTCON3 = 0xC0 RCON.IPEN = 0 ' disable Priority Levels on interrupts PIE1 = 0 ' clear all interrupt enables PIE2 = 0 PIR1 = 0 PIR2 = 0 ADCON1 = 15 ' digital IO TRISA = 0 TRISB = 0 TRISC = 0 LATA = 0 LATB = 0 LATC = 0 end sub sub procedure SERVO8_INIT(dim byref servo_port as byte, dim port_config as byte) servoport = @servo_port + 18 ' PORT TRIS ADDRESS servoport^ = servoport^ And Not(port_config) ' SET TRIS servoport = servoport - 9 ' PORT OUTPUT LATCH ADDRESS T0CON = %00000101 ' prescaler = 64 or ~5us per increment T0 = -4000 ' preset for 20ms INTCON = %10100000 ' Timer0 Interrupt Enabled and Flag Cleared T0CON.7 = 1 ' Timer0 On end sub main: Init_Main SERVO8_INIT(PORTB, 255) HID_Enable(@servo, @wrbuf) ' @servo is equivalent to the Read_Buffer Delay_mS(1000) while true If HID_READ <> 0 Then ' if USB package has arrived...servo positions are in Read_Buffer wrbuf[0] = 255 ' 255 is verification value HID_WRITE(@wrbuf, 1) ' reply to host with verification End If wend HID_Disable '** This code is necessary in order to make linker load the variables and HID_InterruptProc routine. '** In real time it will never execute. if false then HID_InterruptProc wr_adr = @DeviceDescr wr_adr = @ConfigDescr wr_adr = @InterfaceDescr wr_adr = @HID_Descriptor wr_adr = @EP1_RXDescr wr_adr = @EP1_TXDescr wr_adr = @HID_ReportDesc wr_adr = @LangIDDescr wr_adr = @ManufacturerDescr wr_adr = @ProductDescr wr_adr = @StrUnknownDescr end if end.




Bookmarks