Trouble programming an ATMega88 with USBAsp

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

Hey.

 

I created a program in which I would have a blinking led (500ms on / 500ms off) + a led controlled via pwm (brightness wise) + a 1Hz square wave output.

I built the code multiple times and I haven't spotted an error yet (I might be doing something wrong, though).

 

At the moment, I'm following a lot of tutorials on how to program my micro using AVRDude / USBAsp. I'm using multiple computers (with multiple OS's - Win7 and Win10) but none of them seem to work. My guess is: either the drivers are wrongly installed or everything's right exept the code. When I run the program on AVRDudes, my breadboard's leds stay off and nothing really seems to change.

 

Any help given that my work is due on Sunday?

 


 

#include <avr/interrupt.h>
#include <stdio.h>
#include <avr/io.h>
#define LED 1

volatile unsigned char count = 2;								// Counter
volatile unsigned char led ;									// Verifies if LED is turned ON or OFF

void inic(void) {
	
	PORTD = 0b00001001;											// Defined PD0 / PD3 as outputs. PD0: Blinking LED ; PD3: LED (pwm) [OC2B].
	DDRD = 0b00001001;

	TCCR0A = (1<<WGM01);										// COM0Ax: Normal port operation ; COM0Bx: Normal port operation ; Bits 3&2: Reserved and read as zero ; CTC mode (T = [Prescaler/Clock] * (OCR0 + 1)
	TCCR0B = (1<<CS02)|(1<<CS00);								// FOC0x: Read as zero ; Bits 5&4: Reserved and read as zero ; Prescaler = 1024 & Clock = 1Mhz
	TIMSK0 = (1<<OCIE0A);										// Timer/Counter0 Compare Match A interrupt enabled
	OCR0A = 243;												// 0,245 = [1024/1MHz] * (OCR0 + 1) <=> OCR0 = 243 (0,249 ms)

	TCCR2A = (1<<COM2B1) | (1<<WGM21) | (1<<WGM20);				// COM2Ax: Normal port operation ; COM2Bx: Clear OC2B on Compare Match & Set OC2B at Bottom ; Bits 3&2: Reserved and read as zero ; Fast PWM
	TCCR2B = (1<<CS21)|(1<<CS20);								// FOC2x: Read as zero ; Bits 5&4; Reserved and read as zero ; Prescaler = 32 & Clock = 1Mhz
	OCR2B = 0;

	ADMUX =  (1<<REFS0)|(1<<ADLAR)|(1<<MUX2)|(1<<MUX0);			// External capacitor on AREF pin (potentiometer) ; ADLAR adjusted to the left: Bit = 1 ; Bit 4 ; Reserved and read as zero ; PC5 (ADC5) defined as input
	ADCSRA = (1<<ADEN)|(1<<ADIE)|(1<<ADPS1)|(1<<ADPS2);			// ADEN enabled: Bit = 1 ; ADSC set when converting ; ADATE: Disabled auto triggering of the ADC ; ADIF: Set when conversion completes ; Prescaler = 8

	sei();														// global int enable
}

ISR(ADC_vect) {													// ADC interruption
	
	OCR2B = ADCH;												// Transfers the value of the potentiometer to the led on PD3
	ADCSRA |= (1<<ADSC);										// Starts the conversion
}

ISR(TIMER0_COMPA_vect) {										// Led blink interruption
	
	count--;													// Counts 250ms
	led = (PORTD & LED);										// Blinking LED
	
	if (count==0 && led==0) {									// Count = 2 by default. 250ms * 2 = 500ms. Half a second on, Half a second off. Comes here if led is turned off
		PORTD |= LED;											// LED ON
		count = 2;												// Reset counter
	}

	if (count==0 && led==1) {									// Comes here if led is turned on
		PORTD &= ~LED;											// LED OFF
		count = 2;												// Resets counter
	}
}

int main (void) {
	inic();														// Calls the inic function
	
	ADCSRA |= (1<<ADSC);										// Starts the ADC conversion

	while(1){
	}
}

 

Last Edited: Wed. Oct 9, 2019 - 01:41 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Jonaas18 wrote:
My guess is: either the drivers are wrongly installed or everything's right exept the code.
But you haven't actually said if avrdude succeeds or not.

 

Anyway it seems to me you are trying to develop too many things at once here. Forget the ADC, forget the PWM. Just get an LED to blink for starters.

 

What's more forget about using CTC on a timer to even do that. Start by simply putting a toggle of the LED bit in PORTB into the while(1) with a delay. That is your first step - that proves the LED connection. 

 

Then enable the PWM LED and this time change while(1) so that it gradually increments the OCR for the PWM. Does it get dimmer/brighter over time?

 

Keep doing this - enable one part in isolation and test that. When each subsection is proven glue them all together so that the ADC interrupt varies the PWM duty (or maybe and/or the CTC frequency)

 

If you write one plateful of spaghetti, shove it into the micro, switch on and nothing happens you won't have the first idea which bit (or several?) is failing!

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

Understood, perhaps my bad for trying to make it all work at once. I will start by creating a simple led blinking code and pass it on to the micro. Will update in a bit!

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

Update1: 

 

I wrote my code, built it on atmel studio. All fine. After connecting my breadboard circuit to the USBAsp pins (image below) and installing drivers from: https://www.fischl.de/usbasp/ , I tried the Detect function on AVRDudess and it replies "Unable to detect MCU".

 

#define F_CPU 8000000
#include <avr/interrupt.h>
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>


void inic(void) {
	
	DDRD |= (1<<PD0);								// Setting LED (connected to PD0 as output)
}

int main(void) {
	
	inic();
	while(1) {
		PORTD |= (1<<PD0);							// LED ON
		_delay_ms(1000);								
		PORTD &= ~(1<<PD0);							// LED OFF
		_delay_ms(1000);
	}
}

 

Attachment(s): 

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

Why are you even bothering to sohw AVr C code? If you can't program it into the micro at all then what's actually in the .hex is of little/no relevance.

 

The trick when using avrdude is that you can add -v (several in fact) to the command line, the more you add (up to 4) the more verbose avrdude gets about what it's sending/receiving and just generally about what is going on.

 

It may be easier to drop the kid's toys like "avrdudess" and drive avrdude.exe directly so you know exactly how it's being invoked.

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

I've also tried that. From what I can see, it asks me to update the firmware which (according to numerous internet posts) means that I have to flash a .hex file (downloaded from the USBasp website I linked earlier) into the ATMega (there's a ATMega88.hex file + a makefile88)

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

Update2:

 

Found out the problem. Apparently there was a cap connecting 2 pins in the USBas. A classmate told me to take the cap out and place it on another pins, worked like a charm (even though I have no idea why that mattered). My led blinking code worked, aswell as my first one. 

 

There's only one thing bothering me: The led controlled by pwm isn't gradually getting brighter / darker when I mess with my potentiometer. It either goes from full bright to a low bright light. How can I change that (looks better overall)?

Attachment(s): 

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

At 500ms on and 500ms off, persistence of vision (POV) does not come into play very much. Period is 1 second, total; POV does not effect things much until the period it under 0.05 seconds or so. So, if you change the on/off time or duty cycle (duty cycle = ONtime/period), what you see is a flash that varies in how long it is on, but maybe only appears dimmer when you get down to the very shortest on time.

 

IF you want varying apparent brightness, then try a period around 0.01 second (10ms, 100 flashes per second) or shorter.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

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

Not sure if I misunderstood your answer or if you misunderstood my question. I was talking about not beeing able to control the PWM led (for example, if the pontentiometer is on 0 Ω , the led is BRIGHT, if the potentiometer is on 2200 Ω the led is almost TURNED OFF). There's no inbetween. I have no idea how to change that given that I'm messing with a potentiometer (I made a project a year ago in which I changed a led brightness with switches (if SW1 was pressed, pwm +5, if SW2 was pressed, pwm -5)

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

Jonaas18 wrote:
I have no idea how to change that given that I'm messing with a potentiometer

 

What have you done to troubleshoot that?

 

One approach is to break it into two parts:

1) Using PWM to vary the brightness of the LED.

       Use an array of constants to set the PWM value.

       For example, 10%, 50%, and 90%, pausing at each setting for 1 to 2 seconds.

 

2) Reading a value from the ADC and sending it to the PC.

 

Once you have the two parts working separately, you can combine them.

 

 

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

Use an array of constants to set the PWM value.

I understand that that's the same as, i.e., setting the PWM value to 10%, 20%, 30% etc with switches (did that before, like explained earlier). The value would then be linked to another variable (OCR2B if I'm not mistaken) and change the actual brightness of the led / fan speed.

 

  Reading a value from the ADC and sending it to the PC.

Got it. In order to do so I can, perhaps, do something like:

 


> Get voltage value from pin "x";

> If voltage value is a < value < b, then:

    > pwm set as c %;


And so on and so on.. Don't know if it's the right approach or the one you would suggest me to but still. That's my idea.

 

Edit1: I think that I would also need to convert the value read in the pin "x" into common voltage numbers in a [0 .. 5]V scale. Right?

Last Edited: Thu. Oct 10, 2019 - 12:32 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For testing the ADC, I'm suggesting that you read the output of the ADC (an integer),

convert it to an ASCII string, and using the UART, send it to your PC running a terminal

program to display the values.  As you vary the potentiometer, the values displayed on the

PC should change.

 

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

Got it. I've made something like that before. Thing is (without wanting to be disrespectful), that would be a waste of time since this is a "preparatory work" for a massive project later on this semester. Displaying the potentiometer values on a PC terminal would be a great addition but I doubt that it would mean something to my teacher. My idea of wanting a bigger range of brightness values (%) instead of a "either 100% bright or 10% bright" approach is because everyone is doing that. I wanted to make a better project (a more responsive one, per say) by tinkering the PWM section of the code.

 

Nontheless, thanks a lot for this suggestion and it's something I might implement on my project later this year since it's a nice touch to almost any circuit!

Last Edited: Thu. Oct 10, 2019 - 12:50 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you want to learn? or just get the answers and move on to the next thing?

Debugging a problem is something you have to learn, you have to find the problem and what things do I have available to get that done.

That is never ever a waste of time, as in the future you might not have a fancy debugger, but all you have is a product with an ISP connection and a programmer.

Then you need to become inventive and think of ways to be bale to get any information out of your product to see what it is doing, then a simple uart or even blinking a single led can be a real eye opener......

Also while it now seems a waste of time, it could be that when you see the output values you immediately know what is going wrong, instead of having to wait for someone to be online, hold your hand and tell you what to do.

In addition it gives us more information as at this point it can be a lot of things that can be wrong.

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

No, that wasn't my intention when writing the previous reply. I'm just saying that doing something more than asked won't help anything in my grade. I've also have other projects to do (since I'm not only studying micros), that's the reason why I can't dedicate that much time implementing something for the sake of learning (I've already done that some months ago, though I'm not even near a decent coder in USART matters) / fun. Nontheless, I'll have to use USART in my main project in a few weeks so hopefully I'll be able to code it properly. 

 

Also, the code was working fine. The LED wasn't getting brighter gradually because one cable was missconected. I swapped cables and it worked just fine.