Society of Robots - Robot Forum
Software => Software => Topic started by: HarbingTarbl on May 22, 2009, 11:38:10 AM
-
I know it's possible, but I'm not sure how to go about it. In fact the majority of the code supplied in the tutorial absolutely confuses me. For example, F_CPU is set to 3.69Mhz even though from what I understand the mega8 operates at 1Mhz? After reading a bit of the code I understand the Initialization block and how the ports are configured and the adc is setup, one thing about the port configuration that I don't understand is how to include the DDRC, DDRB, PORTC, etc whenever I include them and try to assign values to them in either C or Avr assembly I always get an error. Is it possible to write an assembly program that would accomplish the same goal as the $50 robot? To me assembly seems much easier than C and I have already gotten further in using assembly(I can make a light blink in assembly where as in C I get errors upon compiling..). If anyone could help me understand how the code works a bit better I would be extremely grateful, also if anyone knows where I could find information on some of the other parts of Avr assembly? I have already read through the instruction sets but there are still some things that I can't find documentation on. Like the include files for the pin definitions, or a breakdown of the different registers(An example would be some information on the purpose of the lower registers, 0-15 I think?) and what certain instructions mean that are not included in the instruction set, like .cseg, when to use .equ and when to use .def.
-
Don't want to know a lot then !!!
Yes you could use an ATMega32 instead of ATMega8. Just check the datasheets.
F_CPU is irrelevant - you can set its value in the C compiler to match your clock settings. Yes the ATMega8 has an internal clock of 1MHz or 8MHz but by using an external crystal/oscillator it can be any old value within the chips limitations.
IO Ports eg DDRB, PORTC etc - you need to read up some more. Cant see why you would get an error. What error do you get and show us your source code? Can you compile the standard Photovore code?
Assembler directives like '.cseg' are NOT instructions - they are just directives to the compiler. If you dont understand what they mean (ie code segment) then I would suggest that you stick with C for now. Assembler assumes a much higher level of understanding of the chipset and means your code is less portable from one cpu to the next. However: it is excellent in time/space critical functions - but this should be the exception rather than the norm.
-
If F_CPU doesn't matter, how are delay functions calculated? I mean for something that is time sensitive(Controlling the pulse sent to the servo) it would make sense that F_CPU would be used to find the number of cycles needed to get closest to the delay required. Or do you mean that F_CPU is automatically changed by the compiler depending on the chip being used? To me, C seems much more confusing than assembly, maybe it is because I have taken a class on programming a HC6811 in assembly, but even though I know how to use C in programming on a computer, avr C just boggles my mind.
It seems like in C there are an insane amount of settings that need to be changed when creating a program for an avr, with most of these settings being spread out in multiple header files. I just have a very hard time keeping track of every header file that needs to be included, as well as what things need to be changed.
So far the only thing holding me back in writing creating the photovore bot using assembly is fine tunning the ADC converter, I know how to turn it on, but even after looking through all the example programs I could find(Not many people use assembly it seems) and going over the manuals on Atmel's website I can't find anything on what the different bits in the ADC options do. I know from my experience with the HC6811 that some bits control which pins are doing the converting, the rate of conversion, if it's constant conversion or one time but I don't know which bits do what.
-
If F_CPU doesn't matter, how are delay functions calculated? I mean for something that is time sensitive(Controlling the pulse sent to the servo) it would make sense that F_CPU would be used to find the number of cycles needed to get closest to the delay required. Or do you mean that F_CPU is automatically changed by the compiler depending on the chip being used? To me, C seems much more confusing than assembly, maybe it is because I have taken a class on programming a HC6811 in assembly, but even though I know how to use C in programming on a computer, avr C just boggles my mind.
Well the CPU speed does matter, as you say, for timings. But F_CPU is just a '#define', ie a constant variable if you like. So the code can compile differently depending on what value you specify for F_CPU at compile time. Ie if you say F_CPU=1Mhz then the delay function will waste a certain number of cycles but if you say F_CPU=8Mhz and recompile the program then the delay function will take 8x more cycles. However: this issue happens irrespective of the language, C/Basic/Assembler/etc, that you are using since if you ask it to pause for 1ms then it MUST need to know what speed the CPU is being clocked at otherwise it will fail.
It seems like in C there are an insane amount of settings that need to be changed when creating a program for an avr, with most of these settings being spread out in multiple header files. I just have a very hard time keeping track of every header file that needs to be included, as well as what things need to be changed.
I think a lot of the settings you see may be down to the fact that the code is portable - ie it will work on just about any ATmel processor you can think of. Of course you could delete a lot of the redundant definitions if you know what you are doing and you only want the code to run on a given cpu. Most of these definitions are probably in library files anyway (which you need not concern yourself with). Just looking at photovore.c then thats all you need to know.
Each of the ATmel datasheets has a section on the ADC: and if you are struggling to understand it then you will have a problem regardless of the language you use. More value therefore in using a higher language library, like C, where you can just say 'give me the value' and let it do all the work under the hood.
-
Could you please give me some pointers on using the ADC in assembly? I found that section you were talking about in the manual, but for some reason the converter is not working correctly... I'm not sure if I have just missed something simple or what. Here is my code, at the moment It is not completely finished, I had wanted to ensure that the adc worked before anything else. Once I have the adc working I will use a bit mask to create a threshold at which it will decide if it needs to turn or not.
.include "m32def.inc"
.def SensorLeft = r19
.def SensorRight = r20
.def wreg = r21
.def T1 = r24
.def T2 = r25
.equ Multi = 32 ; ~.1ms delay kinda/almost
.equ Center = 15 ;~1.5ms delay...Kinda
.equ Refresh = 150
.equ Servo_Pins = 3 ;Pins not chosen yet
.org $0000
; Pin D1 will be the left motor
; Pin D2 will be the right motor
Reset:
ldi r16, low(RAMEND)
out Spl, r16
ldi r16, high(RAMEND)
out sph, r16
ldi wreg, Servo_Pins
out DDRB,wreg
sbi ADCSRA, 7 ; Turns the ADC hardware on(Or at least should)
sbi ADMUX, 5 ; Selects single run mode?
ldi T1, Multi
ldi T2, Center
rjmp Main
Main:
cbi ADMUX, 0 ; Select Pin 0 of the ADC
sbi ADCSRA, 6 ; Tell it to take a conversion
ldi SensorLeft, ADCH
ldi wreg, ADCL;Needed only for it to be ready to redo it's conversion
sbi ADMUX, 0 ; Select Pin 1 of the ADC
sbi ADCSRA, 6 ; Tell it to take a conversion
ldi SensorRight, ADCH
ldi wreg, ADCL ; Needed only for it to be ready to redo it's conversion
; It should now have the light sensor values needed.
; Comparing the different values, to check which light sensor is higher
ldi T2,100
rcall Delay
;Uhhhh found out servo's don't like sending a constant repeated signal, this is suppoed to give it some time
cp SensorLeft, SensorRight
brsh MotorLeft_G
rjmp MotorRight_G
MotorLeft_G:
ldi wreg, Servo_Pins
out PORTB, wreg
; the delay numbers will most likely need to be changed depeneding on how I assemble the robot
ldi T2, 10
rcall Delay
cbi PORTB, 0
ldi T2, 10
rcall Delay
cbi PORTB, 1
rjmp Main
Delay:
dec T1
brne Delay
ldi T1, Multi
dec T2
brne Delay
ret
MotorRight_G:
ldi wreg, Servo_Pins
out PORTB, wreg
; the delay numbers will most likely need to be changed depeneding on how I assemble the robot
ldi T2, 10
rcall Delay
cbi PORTB, 1
ldi T2, 10
rcall Delay
cbi PORTB, 0
rjmp Main
You have told me that it would be a waste of time to continue trying to use assembly but I would at least like to learn it, I thought that was the whole point of trying something new. I could work more with C, give up on my work so far and take weeks longer to understand what I am doing, or I could learn something new. To me it would be near impossible to understand how C works without understanding how the assembly instructions work.
-
I quick look suggests that you may not be setting the prescaler and reference voltage and putting it into single value mode (ie not free running). But the main problem is that once you've asked it to start a conversion your program doesn't loop round till the ADC indicates that the conversion has finished.