Developing the line follower car with assembly language using Atmel studio(atmega328p)

Go To Last Post
26 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello everyone:)

 

So now I have learned how to use external interrupts in assembly language. And I learned how to use timer interrupts as well (with CTC config). Now I think this is enough to build a line following car. We can use ir sensors with external interrupts and the motor speeds can be adjusted with timer interrupts. I created simple circuits with external interrupts and learned how to change the duty cycle with timer interrupts.

 

So code wise I have to combine these two things I have learned. If someone could supply me with a skeleton code, That would help so much.

 

Here's what I can think of.

 

Edit: I updated this post with the final working code. Hope someone will find this helpful :)

 

.ORG 0x0					;location for reset
  JMP MAIN
.ORG OC2Aaddr
  JMP timer2_compareMatch_A_Routine
.ORG OC2Baddr
  JMP timer2_compareMatch_B_Routine
.ORG OC0Aaddr
  JMP timer0_compareMatch_A_Routine
.ORG OC0Baddr
  JMP timer0_compareMatch_B_Routine

MAIN:

	  LDI R20,HIGH(RAMEND)
	  OUT SPH,R20
	  LDI R20,LOW(RAMEND)
	  OUT SPL,R20

	  //Setting input ports for sensor input
	  CBI DDRB,2
	  CBI DDRB,3
	  //Set 

	  //Right Motor Configuration with Timer2
	  SBI DDRB,1
	  SBI DDRD,5
          SBI DDRD,4

	  SBI PORTD,5
	  CBI PORTD,4

	  LDI R20,239
	  STS OCR2A,R20

	  LDI R20,(1<<WGM21)
	  STS TCCR2A,R20							

	  LDI R20,0x01
	  STS TCCR2B,R20							

	  LDI R20,(1<<OCIE2A)	| (1<<OCIE2B)
	  STS TIMSK2,R20
	  //Right motor configured

	  //Left Motor Configuration with Timer0
	  SBI DDRB,0
	  SBI DDRD,7
	  SBI DDRD,6

	  SBI PORTD,7
	  CBI PORTD,6

	  LDI R20,239
	  OUT OCR0A,R20

	  LDI R20,(1<<WGM01)
	  OUT TCCR0A,R20							

	  LDI R20,0x01
	  OUT TCCR0B,R20							

	  LDI R20,(1<<OCIE0A)	| (1<<OCIE0B)
	  STS TIMSK0,R20
	  //Left Motor Configured

	  SEI						

 HERE:
		SBIS PINB,2	//Right sensor
		LDI R20,100
		OUT OCR0B,R20
		SBIC PINB,2
		LDI R20,30
		OUT OCR0B,R20

		SBIS PINB,3	//Left sensor
		LDI R21,100
		STS OCR2B,R21
		SBIC PINB,3
		LDI R21,30
		STS OCR2B,R21

		JMP HERE

timer2_compareMatch_A_Routine:							;Controls right motor

  CBI PORTB,1
  RETI 

timer2_compareMatch_B_Routine:							;Controls right motor

  SBI PORTB,1
  RETI 

timer0_compareMatch_A_Routine:							;Controls left motor

  CBI PORTB,0
  RETI 

timer0_compareMatch_B_Routine:							;Controls left motor

  SBI PORTB,0
  RETI

 

 

Last Edited: Wed. Nov 6, 2019 - 02:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

esavrperson wrote:
If someone could supply me with a skeleton code, That would help so much.

 

With all your threads on these topics I would think you could merge your needs together yourself.

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

You've suggested that this is part of a school class - surely, that should be teaching you how to do this?

 

If you haven't reached that point yet, it may be better to put effort into really understanding the bits you have done - rather than run ahead and possibly miss important bits?

 

Speak to your teacher for recommendations on appropriate "extra work" (s)he will be able to recommend stuff that will really help in the progress of the class.

 

For getting your outline design - or "skeleton" - you should not be jumping straight to code. Certainly not to assembly code!

 

Assembler is fine-detail - not overview!

 

Get a pencil and paper (or virtual equivalent) and draw some block diagrams.

 

Think about

 

  • what are your inputs?
  • what are your outputs?
  • what processing needs to be done on the inputs to give you the outputs
  • etc, ...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the replies :) This forum helped me a lot.

Last Edited: Mon. Nov 4, 2019 - 11:14 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
.ORG 0
	JMP MAIN
.ORG 0x02
	JMP E1
.ORG 0x04
	JMP	E2
.ORG 0x1C
	JMP T1
.ORG 0x1E
	JMP T2

Just to note that this could be a lot more readable and portable if you wrote:

.ORG 0
	JMP MAIN
.ORG INT0addr
	JMP E1
.ORG INT1Addr
	JMP	E2
.ORG OC0Aaddr
	JMP T1
.ORG OC0Baddr
	JMP T2

The full list of 328p vector names are in the m328pdef.inc file:

; ***** INTERRUPT VECTORS ************************************************
.equ	INT0addr	= 0x0002	; External Interrupt Request 0
.equ	INT1addr	= 0x0004	; External Interrupt Request 1
.equ	PCI0addr	= 0x0006	; Pin Change Interrupt Request 0
.equ	PCI1addr	= 0x0008	; Pin Change Interrupt Request 0
.equ	PCI2addr	= 0x000a	; Pin Change Interrupt Request 1
.equ	WDTaddr	= 0x000c	; Watchdog Time-out Interrupt
.equ	OC2Aaddr	= 0x000e	; Timer/Counter2 Compare Match A
.equ	OC2Baddr	= 0x0010	; Timer/Counter2 Compare Match A
.equ	OVF2addr	= 0x0012	; Timer/Counter2 Overflow
.equ	ICP1addr	= 0x0014	; Timer/Counter1 Capture Event
.equ	OC1Aaddr	= 0x0016	; Timer/Counter1 Compare Match A
.equ	OC1Baddr	= 0x0018	; Timer/Counter1 Compare Match B
.equ	OVF1addr	= 0x001a	; Timer/Counter1 Overflow
.equ	OC0Aaddr	= 0x001c	; TimerCounter0 Compare Match A
.equ	OC0Baddr	= 0x001e	; TimerCounter0 Compare Match B
.equ	OVF0addr	= 0x0020	; Timer/Couner0 Overflow
.equ	SPIaddr	= 0x0022	; SPI Serial Transfer Complete
.equ	URXCaddr	= 0x0024	; USART Rx Complete
.equ	UDREaddr	= 0x0026	; USART, Data Register Empty
.equ	UTXCaddr	= 0x0028	; USART Tx Complete
.equ	ADCCaddr	= 0x002a	; ADC Conversion Complete
.equ	ERDYaddr	= 0x002c	; EEPROM Ready
.equ	ACIaddr	= 0x002e	; Analog Comparator
.equ	TWIaddr	= 0x0030	; Two-wire Serial Interface
.equ	SPMRaddr	= 0x0032	; Store Program Memory Read

This has the advantage that if you later scale the code down into an 88p or a 48P then for those your code remains the same (almost) but the actual addresses are:

; ***** INTERRUPT VECTORS ************************************************
.equ	INT0addr	= 0x0001	; External Interrupt Request 0
.equ	INT1addr	= 0x0002	; External Interrupt Request 1
.equ	PCI0addr	= 0x0003	; Pin Change Interrupt Request 0
.equ	PCI1addr	= 0x0004	; Pin Change Interrupt Request 0
.equ	PCI2addr	= 0x0005	; Pin Change Interrupt Request 1
.equ	WDTaddr	= 0x0006	; Watchdog Time-out Interrupt
.equ	OC2Aaddr	= 0x0007	; Timer/Counter2 Compare Match A
.equ	OC2Baddr	= 0x0008	; Timer/Counter2 Compare Match A
.equ	OVF2addr	= 0x0009	; Timer/Counter2 Overflow
.equ	ICP1addr	= 0x000a	; Timer/Counter1 Capture Event
.equ	OC1Aaddr	= 0x000b	; Timer/Counter1 Compare Match A
.equ	OC1Baddr	= 0x000c	; Timer/Counter1 Compare Match B
.equ	OVF1addr	= 0x000d	; Timer/Counter1 Overflow
.equ	OC0Aaddr	= 0x000e	; TimerCounter0 Compare Match A
.equ	OC0Baddr	= 0x000f	; TimerCounter0 Compare Match B
.equ	OVF0addr	= 0x0010	; Timer/Couner0 Overflow
.equ	SPIaddr	= 0x0011	; SPI Serial Transfer Complete
.equ	URXCaddr	= 0x0012	; USART Rx Complete
.equ	UDREaddr	= 0x0013	; USART, Data Register Empty
.equ	UTXCaddr	= 0x0014	; USART Tx Complete
.equ	ADCCaddr	= 0x0015	; ADC Conversion Complete
.equ	ERDYaddr	= 0x0016	; EEPROM Ready
.equ	ACIaddr	= 0x0017	; Analog Comparator
.equ	TWIaddr	= 0x0018	; Two-wire Serial Interface
.equ	SPMRaddr	= 0x0019	; Store Program Memory Read

You would, however have to change the JMPs into RJMPs - BTW, unless the vector handlers are a long way from the IVT you may want to do that anyway. The handlers need to be in the first 4K though. (so consider placing them after the IVT but before "MAIN:")

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello clawson, sir, Thank you very much for the very informative and useful reply. And thank you for your help in all the other questions I asked here. Good luck with everything:)

Last Edited: Mon. Sep 23, 2019 - 04:59 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why use external interrupts with the sensors? Figure out what sample rate you need and use the timer for the sample timing. My guess is around 10ms would be a good start.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello again, I developed this code to do the line (black line) following. This isn't the smoothest. The problem is the car sometimes goes off track. It would mean alot someone could help me with this as I wrote this code from scratch and it would mean so much to me if I can get this to work. Thanks. This is a school assignment so using external and timer interrupts are compulsory.

 

.ORG 0x0
	JMP MAIN
.ORG 0x02
	JMP ISR1    //External Interrupt service Routine location (INT0)
.ORG 0x04
	JMP ISR2    //External Interrupt service routine location (INT1)
.ORG 0x0E
	JMP T2R1    //ISR location for Timer2 compare match A
.ORG 0x10
	JMP T2R2    //ISR location for Timer2 compare match B
.ORG 0x1C
	JMP TSR1    //ISR location for Timer0 compare match A
.ORG 0x1E
	JMP TSR2    //ISR location for Timer0 compare match B

MAIN:

	//Initializing the stack

	LDI R20,HIGH(RAMEND)
	OUT SPH,R20
	LDI R20,LOW(RAMEND)
	OUT SPL,R20

	//Initializing stack is done

	LDI R17,0xF     //Both interrupts are triggered with rising edges
	STS EICRA,R17   //so when the IR sensor detects a black line it would trigger an interrupt

	LDI R17, (1<<INT0)| (1<<INT1)
	OUT EIMSK,R17                 //INT0 and INT1 are enabled

	SBI DDRB,0
	SBI DDRD,7
	SBI DDRD,6

	SBI PORTD,7      //Jumper wires from these two ports are connected to the motor controller
	CBI PORTD,6

	LDI R20,239      //set compare match A for Timer0
	OUT OCR0A,R20							

        LDI R20,(1<<WGM01)
	OUT TCCR0A,R20							

	LDI R20,0x01
	OUT TCCR0B,R20	//Start timer 0,ctc no scaler						

	LDI R20,(1<<OCIE0A)	| (1<<OCIE0B)
	STS TIMSK0,R20

	SBI DDRB,1
	SBI DDRD,5       
	SBI DDRD,4

	SBI PORTD,5      //Jumper wires from these two ports connect to the motor controller
	CBI PORTD,4

	LDI R16,239     //Set compare match A for timer2
	STS OCR2A,R16

	LDI R16,(1<<WGM21)
	STS TCCR2A,R16

	LDI R16,0x01
	STS TCCR2B,R16   //Start timer2 ctc no scaler

	LDI R16,(1<<OCIE2A) | (1<<OCIE2B)
	STS TIMSK2,R16

	SEI										

HERE:

	JMP HERE

T2R1:
	CBI PORTB,1      //Connects to motor driver to control motor speeds
	RETI

T2R2:                    //Connects to motor driver to control motor speeds
	SBI PORTB,1
	RETI

TSR1:
	CBI PORTB,0      //Connects to motor driver to control motor speeds
	RETI

TSR2:                    //Connects to motor driver to control motor speeds
	SBI PORTB,0
	RETI

ISR1:
	LDI R21,30        //What I tried to do in the two service routines was increase one motor's speed and decrease the other motors speed based on the sensor input
	OUT OCR0B,R21     //so it would change direction

	LDI R21,60
	STS OCR2B,R21
	RETI
ISR2:
	LDI R21,60
	OUT OCR0B,R21

	LDI R21,30
	STS OCR2B,R21
	RETI

 

Last Edited: Thu. Oct 3, 2019 - 02:49 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Explain the design. How does this actually work?

 

(I wouldn't ask this if there had been comments in there to explain what each part was doing).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for the reply sir. I updated the post with comments. Please tell me If I missed something in doing that :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well that helps but the design is still not clear from simply reading the code/comments. I can see there are two motors that seem to PWM pulsed on/off by the A/B matches on timers 0 and 2 - can we guess (because it doesn't say) that those are driving th left/right wheels so presumably you "steer" by increasing the speed on one side and decreasing it on the other - presumably that's what the 30/60 compare values are all about?

 

But the whole INT0/INT1 thing escapes me. Am I supposed to guess that there is some kind of optical sensor or rather two optical sensors and they are some how wired to create INT0/INt1 interrupts?

 

Put yourself in my place - if you didn't know the circuit/schematic and all you were presented was that code with the comments you have now added do you think it entirely explains how things are connected and how the design is supposed to work?

 

In professional engineering projects there's usually (I hope!) a third element. There's not only a schematic (or at least "system diagram") that shows how everything is wired - what the inputs and outputs are and there's also the hopefully heavily commented code that gives a narrative about what it's setting up or what it is reading in and how it's attempting to do the controlling job but perhaps the most important is the requirements/specification that is a document (even better with some pictures) that says exactly what the thing is and what it is designed to do. Usually you spend the first few months writing that document to try and capture all that the device will do and how it will work and it naturally leads on to the design of both the circuit and the software to then implement that design requirement.

 

Modern engineering students seem to be taught the schematic/wiring thing and the coding thing but no one bothers to tell them that they have to spend time (a LOT of time) up front thinking about how the design will actually work.

 

I know modern world time pressures say that we must get something going as fast as possible but in reality you pay more (in terms of time and effort) from not planning/designing than if you had done that upfront.

 

Anyway the bottom line is the line following is rarely as easy as just a yes/no decision about "line lost on right, turn back towards it a bit". There's book and myriad internet articles about how to do this. I think you'll find that some of this involves concepts like PID. That's a bit like a lift driving to the 7th floor. You don't just run the motor until a sensor says "here's the 7th, stop". You drive for a while and as you approach the floor you are aiming for you gradually back off until you come to a smooth stop where you want to be. Heating controls are also a but like this. Your central heating doesn't just burn fiercely until it's exactly at the target temperature but it backs off a bit as it gets closer.

 

So I think you'll find that robot steering equally is rarely about bang-bang, on-off control but that as you approach where you want to be you make smaller and smaller adjustments. In other word you hard coded 30/60 pules width values may not be exactly the solution you require.

 

But like I say a LOT has been written about line followers so all this has been worked out before you. True a lot is probably in C or C++ or Java or something but the point is that whether you write Asm or whatever the concept/algorithm likely remains the same - it's just coded differently. So I'd read some background design research about this first - find out how this should be done - then write your Asm (and possibly redesign your electronics) to match.

 

EDIT: for example I googled "line follower robot design" and one of the top hits was:  https://www.researchgate.net/publication/224132741_A_line_follower_robot_from_design_to_implementation_Technical_issues_and_problems . I'm not suggesting that first hit is the solution but after you have read the first 50 or 100 articles like that you should have a much clearer picture about how to approach this.

Last Edited: Thu. Oct 3, 2019 - 04:26 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the reply sir,

 

The digital out pins of the left and right are connected INT1 and INT0. I hope this picture would explain it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

esavrperson wrote:

	SBI DDRB,0
	SBI DDRD,7
	SBI DDRD,6

Why are you setting DDRD twice with different values, is this a typo?

 

Jim

DUH( head slap) my asm is a bit rusty, OP is setting two bits on the same port!  Sorry

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

Last Edited: Fri. Oct 4, 2019 - 01:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the reply sir. Via those lines I am setting PB0,PD7,PD6 as output ports. And I am setting PD7 as high and PD6 as low. This configuration is to control one motor. I made this picture to explain the configuration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There's a thing called 'fritzing' for doing these drawings.

 

 

For the timer generating pwm for your motors, no interrupts are required. This might be a good place to start some experimenting. Get your motor controls working first.

 

Next, set up a timer in CTC mode to give you, say, a 10ms interrupt.

 

Do some experiments using the timer tick to create 'soft' timers. 

 

Then you can move onto using the sensor inputs. Why you'd use interrupts for these is beyond me - it would have to be the worst application for interrupts! Many have found this the hard way! Personally, I'd use the timer tick to read the sensor inputs, debounce/filter them then give you a left/middle/right result.

 

A Cliff mentions, you need a control algorithm. If you simply respond immediately to the input, the system will oscillate and act unpredictably. Motors do not accelerate/decelerate immediately - the unit has mass 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
Why you'd use interrupts for these is beyond me - it would have to be the worst application for interrupts! Many have found this the hard way!

 

I think I am one of those many. I now realize that using external interrupts might not be the best way to do this. But I am not sure why. The reason I can guess is bouncing. And I cant think of a way to reset speeds after a turn. I think the best way to do this polling + timer interrupts. I can set a polling code in the main program (between the tag HERE and line JUMP HERE). 

 

do you agree with what I said above?

 

Thanks for the reply good sir:)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think the point is that core of your program is:

HERE:

	JMP HERE

If you aren't doing anything else here then you might as well move the sensor reading into this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes sir, I removed the external interrupts completely. I am moving the sensor readings to the above spot. I have to get few batteries to check the car. I'll update this thread with my progress :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In #8, esavrperson wrote:
This is a school assignment so using external and timer interrupts are compulsory.

Now, esavrperson wrote:
 I removed the external interrupts completely

Eh ??!

 

surprise

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am sorry lol. I have misunderstood what our instructor said. We were told to use timer interrupts. I think after everything I tried, Timer interrupts + Polling seems to work the best. Sorry my mistake :)

Last Edited: Fri. Oct 4, 2019 - 08:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry for my late update.I made a working line follower car with following code :)

 

.ORG 0x0					;location for reset
  JMP MAIN
.ORG 0x0E
  JMP timer2_compareMatch_A_Routine
.ORG 0x10
  JMP timer2_compareMatch_B_Routine
.ORG 0x1C
  JMP timer0_compareMatch_A_Routine
.ORG 0x1E
  JMP timer0_compareMatch_B_Routine

MAIN:

	  LDI R20,HIGH(RAMEND)
	  OUT SPH,R20
	  LDI R20,LOW(RAMEND)
	  OUT SPL,R20

	  //Setting input ports for sensor input
	  CBI DDRB,2
	  CBI DDRB,3
	  //Set 

	  //Right Motor Configuration with Timer2
	  SBI DDRB,1
	  SBI DDRD,5
          SBI DDRD,4

	  SBI PORTD,5
	  CBI PORTD,4

	  LDI R20,239
	  STS OCR2A,R20

	  LDI R20,(1<<WGM21)
	  STS TCCR2A,R20							

	  LDI R20,0x01
	  STS TCCR2B,R20							

	  LDI R20,(1<<OCIE2A)	| (1<<OCIE2B)
	  STS TIMSK2,R20
	  //Right motor configured

	  //Left Motor Configuration with Timer0
	  SBI DDRB,0
	  SBI DDRD,7
	  SBI DDRD,6

	  SBI PORTD,7
	  CBI PORTD,6

	  LDI R20,239
	  OUT OCR0A,R20

	  LDI R20,(1<<WGM01)
	  OUT TCCR0A,R20							

	  LDI R20,0x01
	  OUT TCCR0B,R20							

	  LDI R20,(1<<OCIE0A)	| (1<<OCIE0B)
	  STS TIMSK0,R20
	  //Left Motor Configured

	  SEI						

 HERE:
		SBIS PINB,2
		LDI R20,90
		OUT OCR0B,R20
		SBIC PINB,2
		LDI R20,0
		OUT OCR0B,R20

		SBIS PINB,3
		LDI R21,90
		STS OCR2B,R21
		SBIC PINB,3
		LDI R21,0
		STS OCR2B,R21

		JMP HERE

timer2_compareMatch_A_Routine:							;Controls right motor

  CBI PORTB,1
  RETI 

timer2_compareMatch_B_Routine:							;Controls right motor

  SBI PORTB,1
  RETI 

timer0_compareMatch_A_Routine:							;Controls left motor

  CBI PORTB,0
  RETI 

timer0_compareMatch_B_Routine:							;Controls left motor

  SBI PORTB,0
  RETI 

 

Last Edited: Tue. Oct 22, 2019 - 06:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

esavrperson wrote:
Sorry for my late update.

Still better than no feedback!

 

laugh

 

If it's now solved, see Tip #5.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Four interrupt sources? You only needed one timer for pwm and no interrupts. The PWM modes of the timers actually do the port bit output for you. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, It is possible to do this without timer interrupts. But designwise wouldn't this be better because the cpu is not always tied down? What are your thoughts on it?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I told you my thoughts! You crudely implement pwm using interrupts and code - the timer hardware can do this for you - no interrupts and no code! No cpu intervention required.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That made sense, Thank you sir :)