' ********************************************************************** ' * File: uk_BASAVR_046.BAS * ' * Version: 1.1 * ' * Date: 23.04.11 * ' * Development Tools: Bascom-AVR Demo Ver. 1.11.9.1 + * ' * + AVR bootloader grifo(r) Ver. 1.2 * ' * Cards: GMM AM08 + GMM TST3 * ' * Developed by: GRIFO(r) Italian Technology * ' * via Dell'Artigiano 8/6 * ' * 40016 S. Giorgio di Piano (BO) * ' * Tel. +39 051 892052 Fax. +39 051 893661 * ' * http://www.grifo.com http://www.grifo.it * ' * Author: Gianluca Angelini * ' ********************************************************************** ' Example program 46 of BASCOM AVR course. ' Continuos rotation Servomotor. ' The program allows to define direction and speed of a Servomotor with ' continuos rotations through proper values inserted by console. The signal ' selected to drive the Servomotor is the PB1 of Mini Module, reported on CN4.3 ' connector of GMM TST3. This signal is not generated by BASCOM's instructions ' dedicated to Servo, but by low level instructions. ' In order to obtain the maximum resolution on the motor position, it has been ' necessary to obtain the highest resolution on timings; this condition has ' been satisfied only with parts of programs coded in assembly. ' The program has been tested with the model Servo standard 900-00008 produced ' by Parallax. ' The program describes its functionalities and uses a serial console provided ' of monitor and keyboard with a fixed physical protocol at 19200 Baud, 8 Bit ' x chr, 1 Stop bit, No parity. ' This console can be another system capable to support a serial RS 232 ' communication. In order to simplify the use it can be used a PC provided of ' one COMx line, that execute a terminal emulation program as HYPERTERMINAL or ' the homonym modality provided by BASCOM AVR (see IDE Configuration). ' The program works only when the GMM AM08 is mounted on Z2 socket of GMM TST3!! ' ' Added instructions: None. ' ' 23/04/11: uk_BASAVR_046.BAS - Ver 1.1 - By G.A. ' First version. ' ' '**************************** IDE Configurations ******************************* ' NOTE: in order to coorectly use this demo program, please execute the following ' steps: ' 1) Check the availability of M8DEF.DAT file into the directory where the ' BASCOM AVR is installed and copy it if not present. ' 2) Into the window "Options | Compiler | Chip" set: ' Chip: m8def.dat ' XRAM: None ' HW Stack: 64 ' Soft Stack: 32 ' Framesize: 64 ' XRAM waitstate: disabled ' External Access Enable: disabled ' 3) Into the window "Options | Communication" set: ' COM port = the PC line connected to GMM AM08, through GMM TST3 ' Baudrate = 19200 ' Parity = None ' Databits = 8 ' Stopbit = 1 ' Handshake = None ' Emulation = TTY ' Font = Terminal, Normal, 12 points, white colour ' Backcolor = Navy ' 4) At the end of compilation, after the code is programmed on GMM AM08, open ' the terminal emulation window of BASCOM AVR with the option: Tools | ' Terminal emulator (Ctrl+T) and then reset or powen on the Mini Module. '************************* Compiler directives ********************************* $regfile "M8DEF.DAT" ' Definitions file for used microcontroller $romstart = &H0 ' Code start address on FLASH $crystal = 7372800 ' Microcontroller crystal frequency $hwstack = 64 ' Hardware stack space $swstack = 32 ' Software stack space $framesize = 64 ' Frame space $map ' Generate debug information $baud = 19200 ' Serial communication speed: 19200 Baud ' Other parameters fixed to: 8 bit x chr ' 1 Stop bit ' No parity '******************************* Definitions *********************************** ' The resources used by program are connected as described in following table. ' !!! Note: On GMM TST3 the jumpers must be set in following positions: ' J1 in 2-3 ; J2 in 1-2 ; J3 in 1-2 ; J5 in 2-3 ; J7 in 2-3 ; J8 in 2-3 ' J9 in 2-3 !!! ' ' Servo GMM TST3 pin Z2 pin Signal Signal ' signal resource GMM TST3 GMM AM08 GMM AM08 uP ' PCM CN4.3 30 24 PB1 OC1A PB1 ' GND CN4.17 20 14 GND GND ' ' Signal pin COMx pin CN5 pin Z2 pin Signal Signal ' PC DB9 GMM TST3 GMM TST3 GMM AM08 GMM AM08 uP ' TX 3 3 9 3 RxD RS232 PD0 ' RX 2 2 10 4 TxD RS232 PD1 ' GND 5 5 20 14 GND - ' This table shows that the connection cable between PC COM line and CN5 of ' GMM TST3 is a normal pin to pin cable or direct. Grifo(r) can supply it by ' requesting the CCR 9+9E code. Pinservo1 Alias Portb.1 ' Bit with output signal connected to Servomotor 1 Pinrx Alias Ddrd.0 ' Bit with direction signal connected to GMM AM08 RxD Pintx Alias Ddrd.1 ' Bit with direction signal connected to GMM AM08 TxD '************************* Constants declaration ******************************* Const Pcmmid = 306 ' PCM pulse duration equal to Servo stopped (about 1,5 msec) '************************* Variables declaration ******************************* Dim Hlpb As Byte ' General purpose help byte variable Dim Dtservo As Word ' Pulse duration for Servo Dim Hlpw As Word ' General purpose help word variable '************************ Subroutines declaration ****************************** Declare Sub Ini_pcmtmrirq() ' Initialize timer for PCM signal generation Declare Sub Pcm_pulse() ' Generate Servo controlling pulse on PCM signal '****************************** Main program *********************************** Main: Pinrx = 0 ' Initialize signals for serial communication Pintx = 0 ' as digital inputs Pinservo1 = 1 ' Initialize signals connected to Servo 1 as digital output at high level Ddrb.1 = 1 Print ' Separate from previous visualization by showing an empty new line Print Print " Low level management of continuos rotation Servomotor" Print "Mount Mini Module on Z2 of GMM TST3, connect Servo PCM signal to CN4.3." ' The Servomotor management is performed with low level instructions plus ' interrupt and assembly. These generates a signal that exactly matches the ' timing specifications of the continuos rotation Servo control signal PCM, ' and they allow to increase and reduce the pulse duration, in order to obtain ' all the Servo rotation speeds. ' The program uses a periodic interrupt generated by TIMER0, that can't be ' used for other functions!!! ' This demo defines the PCM pulse duration, thanks to value assigned to ' variable Dtservo, expressed in multiply of about 4.882 microseconds. ' The resolution of this duration defines also the resolution on speeds. ' As the PCM signal duration ranges from 1.25 to 1.75 milliseconds, you ' obtain: ' 1750 - 1250 = 500 microseconds ' 500 / 4.882 = 102 pulse durations = 102 different speeds Dtservo = Pcmmid ' Servo on middle position Call Ini_pcmtmrirq() ' Initialize timer for PCM signal generation Print Print "Generation of PCM signal with middle duration for Servo stopped. Please rotate" Print "the Servomotor trimmer until the shaft is completely stopped and then press a" Print "key to continue..." Hlpb = Waitkey() ' Wait key pressed on console Print Do ' Begin endless loop ' The speed inserted by user change from the maximum in clockwise direction ' to maximum in reversed clockwise direction, by passing through the central ' condition with shaft stopped. Print Print "Value for shaft stopped = " ; Pcmmid ; ". Lower values produce rotation in" Print "clockwise direction and higher values in reversed clockwise direction. The" Print "rotation speed is as much higher as the value difference increase." Input "Insert new rotation speed:" , Hlpw Dtservo = Hlpw ' Define PCM pulse duration with inserted value Loop ' End endless loop Stop Timer0 ' Stops TIMER0 and associated functions End '*************************** End of main program ******************************* '*********************** Subroutines used by program *************************** ' Initialize periodic interrupt generation by TIMER0 of microcontroller, used ' for all the times management of the program. The remarks of this subroutine ' briefly specify the executed operations but detailed informations are ' available in data sheet of microcontroller and inside on line help of BASCOM. ' The loaded time constant produce a 20 msec period and it has been obtained ' as follow: ' TIMER0 counting frequency = Clock Frequency / 1024 = 7372800 / 1024 = 7200 Hz ' TIMER0 counting period = 1 / TIMER0 counting frequency = 1 / 7200 = 0,000138888 sec ' TIMER0 interrupts counter = 0,02 / TIMER0 counting period = 0,02/ 0,000138888 = 144 Sub Ini_pcmtmrirq() Config Timer0 = Timer , Prescale = 1024 ' TIMER0 as 8 bit timer with 1024 prescaler and internal activation On Ovf0 Timer0_irq ' Define TIMER0 overflow interrupt service routine Load Timer0 , 144 ' Load time constant for 20 usec Enable Timer0 ' Enable interrupt from TIMER0 Enable Interrupts ' General interrupts enable Start Timer0 ' Enable TIMER0 End Sub ' Subroutine that generates pulse on PCM signal of Servo, with a duration defined ' by value passed in global variable Dtservo, through the below formula: ' (4,882 * Dtservo + 4) in microseconds. The duration doesn't exactly match the ' formula result, but differences have microseconds fractions, and so they are ' meaningless. ' Input: Dtservo = PCM pulse duration, as in reported formula ' Output: None Sub Pcm_pulse() Pinservo1 = 1 ' Set PCM Servo control signal high ' Generates delay in assembly in order to obtain maximum resolution and to ' use the lower number of microcontroller registers. $asm push R24 ' Save R24 register: 2 clk in R24,sreg ' Get SREG register: 1 clk push R24 ' Save SREG register: 2 clk PUSH R25 ' Save R25 register: 2 clk ' The duration of each delay loop is not exactly 5 microseconds but: ' Clock frequency = 7372800 ' Clock period = 1 / 7372800 = 0,000000135 sec ' Duration single delay loop L = 12+12+12+12+24 = 36 periods ' Duration single delay loop L = 36 * 0,000000135 = 0,000004882 sec LDS R24,{Dtservo} ' Initialize delay loops counter: 2 clk LDS R25,{Dtservo+1} ' R24 is byte L, R25 is byte H: 2 clk Delpcm: ' Start delay loop NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk NOP ' 1 clk DEC R24 ' Decrease loops counter L: 1 clk CPI R24,255 ' Check end of delay loop L: 1 clk BRNE Delpcm ' If delay loop L not completed, repeat it: 2 clk DEC R25 ' Decrease loops counter H: 1 clk CPI R25,255 ' Check end of delay loop H: 1 clk BRNE Delpcm ' If delay loop H not completed, repeat it: 2 clk POP R25 ' Restore R25 register: 2 clk pop R24 ' Restore SREG register: 2 clk Out Sreg , R24 ' Set SREG register: 2 clk pop R24 ' Restore R24 register: 2 clk $end Asm Pinservo1 = 0 ' Set PCM Servo control signal low End Sub ' Interrupt service routine associated to periodic TIMER0 overflow. ' It generates a pulse on Servo control signal, with the duration defined by ' variable Dtservo, each 20 msec. ' Even if the routine is very short, it uses three registers of microprocessor ' and it can't be declared with Nosave directive. Timer0_irq: Load Timer0 , 144 ' Reload time constant for 20 usec Start Timer0 ' Re-enable TIMER0 Call Pcm_pulse() ' Generate Servo pulse control on PCM signal Return '******************* End of subroutines used by program ************************