Posts: 36
Joined: Thu Jun 21, 2012 1:50 pm

Assembly function's/Servo Control

Sun Dec 23, 2012 6:20 pm

Hi guy's,

I've been going though the Cambridge Uni tutorials today to grasp the idea's behind assembly and bare metal programming.

It's not been going too badly but after completing the first set of tutorials i decided to set off and do my own thing which has invaribly gone wrong and i'm at a loss as to how to fix it!

Initally i took the GPIO control scripts and systemTimer we created to control a servo, i managed to get the servo to respond and stay in position by simply looping the commands over and adding a wait for the servo pulse of 1.2ms and another wait with GPIO off for the remaining 3.8ms (totalling 5.0ms which i believe is correct?)

Either way, this 'appeared' to work and locked the servo in position.

Next i moved on to trying to put this into a more useful funtion i could feed the required servo pulse time to.

The problem is, i've written a function and it doesnt appear to work. With no way of really debugging where it's going wrong i'm at a real loss and hoping someone might be able to assist a little?

Here is my slightly modified code in main.s

Code: Select all

mov r0,#23
mov r1,#0
ldr r2,=1200
bl ServoPulse
and my function:

Code: Select all

.globl ServoPulse
	ldr r3,=5000	/*Set the total width for pulse*/
	sub r3,r2		/*subtract the pulse width from the total width*/
	bl SetGpio		/*set the gpio to ON*/
	mov r0,r4		/*move r0 (gpio number) to r4 to use later*/
	mov r2,r0		/*set r0 to the servo pulse width*/
	bl Wait			/*wait for the servo pulse time period*/
	mov r4,r0		/*set r0 back to the gpio number*/
	mov r1,#1		/*set r1 to #1 to turn gpio OFF*/
	bl SetGpio		/*set GPIO to OFF*/
	mov r3,r0		/*set r0 to remaining pulse time*/
	bl Wait			/*Wait the remaining time*/
	mov pc,lr		/*resume*/
I know it's messy and probably not the right way at all to do it but for a n00b i'm really just trying to get it to do something!

If someone could point out why my function doesnt work i'd really appreciate it.


EDIT: Also, could someone explain my we sometimes use LoadRegister and sometimes appear to use Move? eg, here we are using Move when we are writing a new value:

Code: Select all

mov r0,#23
mov r1,#0
ldr r2,=1200
bl ServoPulse

Posts: 141
Joined: Wed Sep 12, 2012 8:10 am
Location: Paris

Re: Assembly function's/Servo Control

Mon Dec 24, 2012 5:39 pm

mov r1, r2
is moving r2 into r1 as
mov r1,#4
is moving 4 into r1

ldr is using 2 words:
1 for inst, and 1 to store the data
mov ri, #... is using only 1 word BUT
there are some restrictions of the value, only constant with only few bits are alowed...


Posts: 36
Joined: Thu Jun 21, 2012 1:50 pm

Re: Assembly function's/Servo Control

Thu Dec 27, 2012 5:47 pm

Thanks Philippe,

I've corrected those and i also discovered my timing was out and should of been 25000 pulse width. But i still cant quite get this working.

Trying to work out my bug's has posed a question that i cant find an answer to though. When doing a subtraction does the original value remain? EG. "sub r2,r1" should subtract r1 from r2 and leave the result in r2, but what happens to the value in r1? is it considered done with and cleared or does it stay in place?

EDIT: forgot to mention, i amended the code for my OK LED to pulse so i can tell each cycle of the code is working and it appears that the stop just stops for some reason when i goes into the servopulse function...

User avatar
Posts: 13931
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Assembly function's/Servo Control

Thu Dec 27, 2012 6:02 pm

Servos typically accept 50 pulses per second (i.e. every 20ms), each pulse being 1-2 ms in duration.

Posts: 36
Joined: Thu Jun 21, 2012 1:50 pm

Re: Assembly function's/Servo Control

Thu Dec 27, 2012 7:48 pm

Thanks Joan, i've corrected that now to have a pulse width of 20000 and servo pulse between 500-2500.

I've managed to improvise a method for debugging my code by flashing the OK LED after each line of code. It's certainly show up some odd problems.

Firstly, my function called ServoPulse wasnt even running. I can't figure out why but created a new one called ServoTest and copied the code in and it works! (in as much as i get a confirmation blink from the LED).

Basically i discovered the other functions i was calling were still overwritting my registers, as a temp solution i've re-created these functions using higher register numbers that don't conflict.

now, back to my previous post, i believe the subtraction is removing one of my values that i want to keep, so i'm going to have to create a duplicate of it before the subtraction i guess?

Posts: 36
Joined: Thu Jun 21, 2012 1:50 pm

Re: Assembly function's/Servo Control

Thu Dec 27, 2012 9:12 pm

Amazingly, i've got this sort of working!

slightly misleading but the Wait along with my LED flash was causing an unexpectedly long delay between the code. I removed the OK flashes and the servo is finally moving.

I have another bug that i'm struggling with though if anyone has any thoughts. the servo position settings are in a loop and when it reaches the end goes back to the start but the servo does not move after the first run though...

I've added an LED flash at the end and can confirm the loop is working as the LED continues to flash, just no servo movement.....

Posts: 49
Joined: Thu Oct 25, 2012 10:06 pm

Re: Assembly function's/Servo Control

Sat Jan 12, 2013 1:38 am

Hi Just looking at your code. and I looked threw an old assembly book and I think you can keep your old values when you use subtract a value, here is the syntax :
SUB {<sufix>} <destination>, <operand1>, <operand2>
ie SUB R10,R2,R4 R10= R2 - R4
I not too sure, I'm bit new to this my self
also have you tried looking at the risc os section of the forum? Tank as writ a great GPIO module and it pretty easy to use from bbc basic and bbc basic has a inline assembler built into it and it makes it easy to prototype ideas and make then a reality. has you can use simple basic constructs and then later refine then in assembly.

Return to “Bare metal, Assembly language”