AVR ATtiny USB Tutorial Part 2

This is the second part of my USB tutorial for ATtiny2313 and V-USB library. In the first part we learned how to get 3.3V from USB to power our circuits. In this part, we will expand our setup with following parts:

  • Larger breadboard and additional jumper wires
  • ATtiny2313
  • 12 MHz crystal oscillator
  • Two 27 pF ceramic capacitors to stabilize the crystal
  • Two 68 Ω resistors between USB data lines and the microcontroller pins
  • 1 MΩ pullup resistor for D+ and 1.5 kΩ pullup for D-
  • 6-pin header for programming the ATtiny and 4.7 kΩ pullup for reset pin

Update: Some people have noted that the setup I’m using here runs ATtiny2313 at 12 MHz with only 3.3V VCC, which is outside the specified range (frequencies over 10 Mhz require 4.5V or more). I’ve never had any problems, and many others have succeeded with this setup, but if you encounter persistent problems, I suggest you to power the ATtiny2313 straight from 5V of the USB line and use zener diodes on D+ and D- lines to drop their voltage, as is done in my later tutorial with the ATtiny85 microcontroller.

Breadboard setup

This time I will not walk you through every connection. Instead, I’ll just outline the steps needed and show the pictures of end result. Here is the schematic we’re building:



Basically it’s the regulator circuit we just built, pullups and line resistors for D+ and D- in the USB bus going to PD2 and PD3, and the ATtiny2313 with RESET pullup and MISO, MOSI, SCK and RESET connected to the 6-pin programming header, and a 12 MHz crystal. An easy order to make these connections is to:

  1. Reconstruct the power circuit from part 1 in one corner of the breadboard. Instead of connecting 5V from USB to the positive power rail, connect it straight to the input pin of the regulator – we won’t be needing 5V anywhere else
  2. Use jumper wires to connect regulator output and shared ground from USB to breadboard power rail
  3. If you have multiple power rails, you can use jumper wires to provide current to all of them
  4. Double-check the regulator pin connections and that capacitors are connected the right way
  5. Plug in the USB and use a multimeter to check you have 3.3V in power rails
  6. Insert the ATtiny and do standard wiring for power, reset pullup and 6-pin programming header
  7. If your programmer has a mode where it provides power to the chip – disable it
  8. Use programmer to check that the chip responds OK (i.e. gets power and acts in a stable manner)
  9. Connect the LED to PB0 and do a “test run” – flash a program that blinks the LED to see that it works
  10. Connect pullup resistors to D+ and D- (1M and 1k5)
  11. Connect D+ and D- to PD2 and PD3, respectively – use 68 ohm resistors in series here!
  12. Connect the 12 MHz crystal to PA1 and PA0, and ceramic capacitors between crystal pins and ground

Here’s how the end result should look like:

Here is another closeup of the power part and USB jumpers. Note how 5V from USB goes to regulator only and nowhere else.

By the way, if you need a refresher on how to connect the RESET pullup and 6-pin header and use the programmer, check out this excellent tutorial – wiring is the same but of course pin locations in ATtiny2313 are different than in ATtiny45. Connecting the crystal is also very easy, just connect the two legs of the crystal to PA0 and PA1, and add ceramic capacitors between each leg and ground (they need to be close to the crystal to make it stable).

Software side – preparing for V-USB

Now for the good stuff! If you did not already test that your ATtiny2313 setup is working, I suggest you to do that now. A good way to do it is to use the following simple test program:

#include <avr/io.h>

#define F_CPU 1000000UL  // 1 MHz
#include <util/delay.h>

int main() {
	DDRB |= 1; // LED on PB0
	
	while(1) {
		PORTB |= 1; // Turn LED on
		_delay_ms(500);
		PORTB &= ~1; // Turn LED off
		_delay_ms(500);
	}

	return 1;
}

This test program has the great additional feature that once we update the fuse bits for 12 MHz clock, it’s easy to verify that blink gets 12x faster. Now for ATtiny2313, we want to disable the internal clock/8 division and use an over 8 MHz clock with 14 clock cycles + 4.1 ms startup delay (CLKSEL=1111, SUT=10). This means that low fuse should be 0xEF, which is done using avrdude command “-U lfuse:w:0xef:m” (without quotes). In case you are using any other part or just want to check it yourself, use the excellent AVR Fuse Calculator.

Once you have updated the lfuse, reset or reprogram the chip to verify that the LED is now blinking 12 times per second. Update the blink example’s F_CPU to 12000000L and reflash to verify that the blinking returns to 1 Hz speed. Congratulations, everything is now ready for the V-USB -part of the tutorial! I will stop here for tonight, and post the third part of this tutorial shortly, covering the basic V-USB setup for our circuit.

Proceed to the next part of this tutorial

57 Comments or trackbacks to AVR ATtiny USB Tutorial Part 2

Marek:
January 26, 2012 at 12:33

A very nice tutorial! I am looking forward for the third part… :-)

reply

isik:
February 10, 2012 at 3:53

wow thanks this tutorial is really handy

reply

slink:
February 12, 2012 at 14:52

I read the hardware condiderations over at the V-USB page. I see that they consistently use the 1k5 pullup on D- but I don’t see them using any pullup on D+. What is the advantage of your 1M resistor in this schematic?

reply

jokkebk:
February 12, 2012 at 15:57

@slink
I went through several USB tutorials before making my own device, and one recommended such a resistor just to avoid current spikes generating spurious interrupts on INT0 pin of AVR. I think it was in V-USB’s example project “PowerSwitch”.

It is probably not needed and 1 M resistor won’t protect against much in any case. :)

reply

bjw908:
February 12, 2012 at 22:21

Is it possible to make this work with the ATtiny45-20PU? What changes would need to be made? Any help would be greatly appreciated.

reply

jokkebk:
February 13, 2012 at 9:20

@bjw908
I don’t see any problem with getting the example run on ATtiny45. If you use something else than a 12 MHz crystal you need to check that V-USB supports it.

Also, after crystal, reset, VCC and ground pins the only ones left are the three used by 6-pin programing header (SCK/MOSI/MISO lines), so you need to use them for both programming and USB lines / LED. Should not be a big problem as both USB lines and LED have series resistors. Should there be a problem with programming or USB operation, you can of course first detach USB, attach the programmer, and after flashing, detach the programmer and re-attach USB. :)

D+ needs to be connected to INT0 pin to avoid using two lines for it, so in ATtiny45 you need to have it in PB2. PB1 could probably be used for D- and PB0 for LED, or vice versa.

reply

BreathboardLover:
March 30, 2012 at 7:27

Hi, thanks for your tutorial, it’s great and i learnt a lot from this pages. I have a simple question, why did you use an external oscillator instead of the internal one (as in attiny85)?

reply

jokkebk says:
March 30, 2012 at 9:19

I had a ATtiny2313 with 12 MHz oscillator already wired when I started playing with V-USB, so that’s the reason. :) Also, the code becomes a little more complex with ATtiny85 because of oscillator calibration, so starting without that complication seemed like a good idea.

reply

BreadboardLover says:
March 30, 2012 at 22:22

Ahnn ok :-)

reply

ed:
April 22, 2012 at 0:08

No doubt I am missing something basic here which prevents me from grasping what is going on.
In the numbered list step 7 and 8, what is it exactly that you program into the chip? a bootloader AND a led flash program?
Anyway, then in ‘Software side’ you (re)program it again with a led flash program. Is that at that moment the only thing that is in that chip?
Anyway, then in part 3 of the tutorial you do a lot of jiggling with files and then Right above ‘WINDOWS DRIVER HELL, you maka something that makes you ‘ready to deploy the code to the chip’ Is that than actually what you do at that time? Flash the chip for a 3rd time with the actual VUSB code/bootloader/whatever.
Tnx

reply

jokkebk says:
April 25, 2012 at 22:00

Hi ed. Yeah, there is no bootloader in any point of the process – I actually first program a short program that just toggle’s the LED pin, and no bootloader at all, as I’m using a ISP programmer that does not need a bootloader. Same for the later steps, the flashing always replaces what was there before.

reply

Mauro:
May 2, 2012 at 19:24

Hi, thanks for your tutorial it’s great.
I have a doubt and I hope you can help.
I tried to do the same circuit but with Atmega16 and i use stk600 with AVR Studio 5.1.
I difine #define F_CPU 12000000UL and the fuses Ext. RC Osc. 8.0MHz – 12MHz; Startup time: 18CK + 0ms; (CLKSEL=1000, SUT=00) is this correct?
I did it in stk600 with ext. 12Mhz Cristal and works. But if i put the microcontroller in my circuit with the cristal nothing happens, why? i tried with Two 27 pF ceramic capacitors and nothing happens, i tried to Two 15 pF ceramic capacitors and noting happens too.
But if i program the fuses with the internal oscilator works fine.
Is not supose to work with the ext 12 MHz cristal?

Thanks

reply

jokkebk says:
May 2, 2012 at 19:29

External RC oscillator is different than crystal. Try some of the “External crystal/resonator High freq.” options, preferably with some of the longer startup times (SUT), you might have more luck with those!

reply

Mauro says:
May 2, 2012 at 19:39

Thank you very much.
With “External crystal/resonator High freq” works :)

reply

erko:
July 18, 2012 at 22:18

Hi, great tutorial!
You wrote: “11.Connect D+ and D- to PD3 and PD2, respectively – use 68 ohm resistors in series here!”
Shouldn’t that be: “PD2 and PD3″?

reply

jokkebk says:
July 20, 2012 at 12:21

Wow, you’re right! It seems I got it right two times out of three. Thanks for pointing this out, I corrected the mistake!

reply

abd rmdn:
July 23, 2012 at 19:34

hi, thanks for tutoring such helpful things.
i have this problem and i hope u help me with it::
im using atmega32a .. i dont c why i have to put an external crystal isnt the internal good enough,.?!
and what config do i need to do if external crystal should be added??!
and how can i set those (CLKSEL=1111, SUT=10) is it by software??! or giving a high voltage on specific pins??!

really appreciated …
and thanks in advance..

reply

jokkebk says:
July 23, 2012 at 22:25

The internal oscillator is quite inaccurate, so external crystal is a lot easier method to get the accuracy required by USB communications. Also, most AVR chips can only achieve 8 MHz with internal crystal. For ATtiny45/85, the internal oscillator combined with the build in phase-locked loop (PLL) multiplier can reach 16.5, but still needs to be calibrated – see my ATtiny85 post for details.

Fuses (clock, start-up time) are set using AVRstudio programming tools or “avrdude” command-line program – here’s a good tool to calculate the necessary fuse byte values:

http://www.engbedded.com/fusecalc/

I would recommend googling around a bit to understand the fuses so you don’t make any mistakes – wrong settings may render the chip unusable (for example, you can disable further programming completely…)

reply

abd rmdn says:
August 2, 2012 at 0:54

i sat the fuse bits … and made the circuit ..
but still when i plug the USB in .. it gives me USB cannot be recognized…
i sat the fuse bits as follow::
ext. crystal/resonator high freq; start-up time: 16ck-4 ms
for my 12Mhz crystal… and i tried the 16MHz also..
but nothing changed….
……
dont know if im mistaking with this configuration..
but to be clear i used a 22pF capacitors instead of 27pF… can that be a big difference that effects the circuit’s purpose…

i’m really working hard to get this USB circuit working but no news ..so i hope u help like u did before … :)

reply

jokkebk says:
August 7, 2012 at 15:55

There’s a simple test you can use to see if the crystal and fuses are working properly: Make a simple program that blinks a LED every five seconds or so, and time if it works as it should. There’s a test program template you can modify (just change F_CPU to match your crystal speed, e.g. to 12000000).

Second, the usbconfig.h also contains a #define that tells (in kilohertz) the V-USB library which frequency your circuit is running. Make sure it’s also correct, e.g. 12000 for 12 MHz crytal, 16000 for a 16 MHz one, and so on.

reply

Eugie Limpin:
August 7, 2012 at 16:46

Hello there! I’d like to follow this tutorial and I’m in the process of buying the parts I need. I noticed that there are 4 (as far as my shopping went) types of ATTiny 2313:
ATTINY2313-20PU, ATTINY2313A-PU, ATTINY2313V10PU and ATTINY2313V-10PU. The first two has 20MHz max freq while the latter two has 10MHz. Is there a particular model I should get to follow your tutorial?

Thanks!
Eugie

reply

jokkebk says:
August 7, 2012 at 19:01

The 20PU version capable of operating frequencies of over 10 MHz is needed to work with 12 MHz crystal used in the tutorial. :)

reply

Eugie Limpin says:
August 8, 2012 at 8:31

Thanks! I’ll buy that then. Wish me luck!

reply

Veggie:
August 30, 2012 at 5:24

This tutorial is incredibly useful for getting into this stuff.

The one deficiency I find is that you completely gloss over the AVR Fuse Calculator. That page has many options to select from, and I’m not really sure what options to set for my particular device to accommodate the 12 MHz crystal. Which options would you suggest I pay attention to?

Thanks!

reply

jokkebk says:
August 30, 2012 at 14:22

A good way is to use avrdude to read the current (default) fuse settings of your device, then use the Fuse Calculator to get those same fuses, after which you change just the crystal setting or any other settings you actually understand (that’s how I usually do it :).

You might also want to check my AVRweb utility, it can read the current fuses and update settings accordingly, although it’s still in early alpha stage, so double-check with AVR Fuse Calculator if you want to be sure…

reply

Mina:
January 18, 2013 at 16:30

do i need to put the pull-up resistors while using atmega32?
any btw any other changes would happen if i use atmega32?

reply

jokkebk says:
January 18, 2013 at 16:36

Yes, atmega32 (or atmega328?) will need the same setup. Usually only changes needed are to change the pins to corresponding ones in ATmega – if INT0 pin is something else, you’ll need to route D+ there and also update usbconfig.h accordingly.

reply

Buraev Ravil:
April 1, 2013 at 14:16

Can I use microcontroller AT90S2313-10SI instead ATtiny2313 ?
Can I use quartz 16 Mhz instead 12 MHz ?

reply

jokkebk says:
April 1, 2013 at 15:21

You’ll need to check MCU specs that the 16 MHz frequency is supported, some xxx-10 -models only go to 10 MHz. And of course you need to update V-USB config accordingly, I vaguely recall that 16 MHz is also supported, but you may want to double-check. Otherwise it will probably work just fine. :)

reply

adampater:
April 10, 2013 at 18:18

You specify ceramic capacitors to stabilise the crystal. Would tantalum work as well? That’s what I’ve used with a 16 MHz crystal and an ATTiny2313 – don’t recall why just now.

I set the fuses to “lfuse:w:0xff:m hfuse:w:0xdb:m”, intending to use the 16 MHz crystal, but the MCU the falls silent. If I shift it to a breadboard with an 8 MHz crystal it’s happy. I suspect the 16 MHz Xtl isn’t functioning correctly but don’t know how to confirm that without a CRO, apart from swapping out the xtl and caps.

With a good 5.05 Volts, shouldn’t it all “just work”?

reply

jokkebk says:
April 20, 2013 at 12:10

I’ve never seen tantalum caps in picofarad range, only nF. If you have too big caps, the high frequency crystal probably fails to reach stable oscillation. It could also be just the crystal, I’ve heard they are rather fragile. And some crystals might just be plain picky about the capacitor value (I’ve personally used 18-27 pF ones without issues, as long as both are the same).

reply

jokkebk says:
April 20, 2013 at 12:12

Oh and 5.05V sounds just fine. Of course if there are big swings, it might be an issue, but that’s rare (I once plugged an AC adapter to a DC regulator circuit, no wonder why the projects worked oddly :D)

reply

Hausy:
April 23, 2013 at 19:58

hy,
Can u please help and tell about programming attiny2313. What programmer did u use and what about boot loader?
Some coments or good tutorial would be great.
Do u programm microcontroller and then add it to circuit, or u are programming it in cicrcuit?
Actually i’m new in this and i didn’t get it.

reply

jokkebk says:
April 23, 2013 at 21:48

Hi. I suggest you go through some of the simpler tutorials on AVR Freaks forum’s tutorial section, or maybe this one I also linked in the post: http://imakeprojects.com/Projects/avr-tutorial/

I personally use USBtiny programmer from Adafruit, but have occasionally used an Arduino, too (there’s a tutorial about it in my blog, too). It’s often quite easy to leave the pins required to program the MCU free, so I can program the chip in circuit, not outside of it (also saves a ton of time when you need 20+ attempts to get the program to work properly…).

reply

Hassan:
July 29, 2013 at 8:49

Hi
I’ve a question from D+ line and Pull up D+ with 1M res.
in vusb\circuits\ D+ pulled down with 1M res.
ty

reply

jokkebk says:
July 29, 2013 at 9:37

The circuit is adapted from V-USB PowerSwitch reference project, which has a pullup. I think (but not certain) the pullup/down is used to indicate desired communication speed or something. Anyways, it has worked fine with pullup. :)

reply

Hassan says:
July 29, 2013 at 10:37

thank u
in your main() you used usbDeviceDisconnect() and usbDeviceConnect()
but in usbconfig.h in your project you didnt define USB_CFG_PULLUP_IOPORTNAME and USB_CFG_PULLUP_BIT
in vusb comments tells:

/* #define USB_CFG_PULLUP_IOPORTNAME D */
/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
* V+, you can connect and disconnect the device from firmware by calling
* the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
* This constant defines the port on which the pullup resistor is connected.
*/
/* #define USB_CFG_PULLUP_BIT 4 */
/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
* above) where the 1.5k pullup resistor is connected. See description
* above for details.
*/

and u just connect D- to Vcc with res and didnt connect to any pins of MCU then i think usbDeviceDisconnect() and usbDeviceConnect() dont work.
is it correct?

reply

Hassan says:
July 29, 2013 at 10:59

My second question is not relevancy to first question

my purpose from this sentence is connect D- to a pins of MCU to pulling up and pulling down D- for connect and disconnect USB device

sorry i cant type and speak English very well.

reply

jokkebk says:
July 29, 2013 at 11:53

No problem, your writing is perfectly understandable. :)

jokkebk says:
July 29, 2013 at 11:52

Yeah, exactly as you said, I went for the simplest option without support for connect/disconnect. You can probably implement that by uncommenting the lines and configuring them for the port pin you’ve chosen to use for connect/disconnect.

reply

Rahul:
October 7, 2013 at 15:34

Can I use this to burn firmware in atmega8?

reply

Joonas Pihlajamaa says:
October 7, 2013 at 15:59

The pins will be a bit different, but there are no big differences between the tiny and mega platforms, so I’d wager yes.

reply

Ashok:
November 5, 2013 at 18:47

Dear Joonas,

Firstly, Hats off, hats off to your excellent tutorial. I tried all the steps until programming the fuses successfully. But there was a problem at a point.

I am using

Atmega32A MCU,
16mhz clock
22pf capacitors
USBASP programmer

I tried to disable my programmer to power the target board by simply not connecting the power from my usbasp programmer and rather connected the power from the usb connector. When you meant to disable the power to the target from the programmer I assume it should ideally be a jumper setting in the programmer to do that right? Unfortunately my programmer does not have anything like that. Hence I decided not to connect it at all from my programmer. Now when I try programming my device with the power derived from the usb cable but not from the programmer it is inconsistent. The errors I see are,

* target doesn’t answer
* target answers but problem reading either of the fuses (hfuse or lfuse)
* sometimes it works fine.

Hence the state is not stable.

Do you have any ideas on how to go about this problem?

Regards,

Ashok
http://www.hashok.com

reply

Joonas Pihlajamaa says:
November 5, 2013 at 20:55

Thanks! In case you cannot disable power from programmer, just leave the USB power off – the programmer data signals are likely relative to it’s ground, and without common ground it’s likely to not work very well. You could even have the MCU completely removed from the project while programming (although that shouldn’t be necessary).

Theoretically you could just connect programmer ground but not VCC, but in that case you’d need to be sure that the grounds of your device and programmer are exactly the same (e.g. same USB hub), otherwise you can get nasty ground loops.

reply

Joonas Pihlajamaa says:
November 5, 2013 at 20:55

And with “USB power off” I mean disconnected while you program, and then disconnect the programmer when you rewire the USB power back…

reply

Ashok says:
November 6, 2013 at 4:06

Thanks for the quick reply mate! Will sure try what you have advised. BTW, when you meant “same USB hub” did you mean using an external usb (multi usb ports extension) hub connected at a single point the pc?

reply

Joonas Pihlajamaa says:
November 6, 2013 at 6:50

“Same USB hub” essentially meant any two ports that share a common ground. Adjacent USB ports in a computer, monitor, or USB hub all apply. :)

However, for example my monitor has a separate power supply and it’s ground is usually >0.1V different from PC. Probably nothing to worry about, but I’m still hesitant to use it (i.e. connect a device to monitor and use my USB scope connected to PC, for example). :)

Ashok says:
November 6, 2013 at 4:12

Forgot to tell you that meanwhile to handle this power/mcu randomized detection problem I flashed the MCU separately with the avr code and went on to the next of “Windows driver hell” step. It is true and as you said its really a hell for that step has not yet been sorted out for me. Hence thought of downloading your projects files and flash it first to see if the USB gets detected and the driver installed.

reply

jonny:
December 8, 2013 at 7:36

Nice Tutorial.
you have a very minor typo in the article: “Breaidboard setup”

reply

Joonas Pihlajamaa says:
December 9, 2013 at 21:37

Haha, thanks I’ll fix that. :)

reply

carlos:
December 16, 2013 at 5:48

Hi: I decided to use an attiny84, for lower size. But I have several troubles calculating the fuses for v-usb.
Whats the trick?

http://www.atmel.com/Images/doc8006.pdf attiny84

reply

Joonas Pihlajamaa says:
December 16, 2013 at 9:27

Easiest way is to use the AVR Fuse Calculator, or alternatively my AVRWeb GUI to flash (you first need to “Detect MCU” with avrweb and then go to fuse setup). The main things to change are disabling the 1/8 clock scale, and setting clock for 12 MHz crystal, I’d think the settings are very similar to ones described in the post, only the actual fuse value will be different.

reply

Leave a Reply

Your e-mail address will not be published.


nine × 2 =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>