Timer maximum

I’m using my LV168 to send pulses to a stepper motor driver with this code:


void delay_10us(int d) {
	unsigned int i;	
	for(i=0; i<d; i++) {_delay_loop_1(67); // apprx 10us}
}

int main(){

	// set DDRx register to output
	DDRD |= 1 << PD1; // PD1 ->output

	TCCR1B|=(1<<CS10);//Set up timer

	while(1){

		if(TCNT1>20000){

		// set PD1 high
		PORTD |= 1 << PD1;
		delay_10us( 10 );

		// set PD1 low
		PORTD &= ~(1 << PD1);
	
		TCNT1 = 0;
		}
  	}   
}

The reason I use the TCNT1 timer is because I want to be able to drive two steppers at the same time later on, so the code can’t be ‘hung up’ on delays for the pulse timing.

I have three questions which I hope can be answered:

What is the value maximum of the TCNT1 timer? (and where can I find this kind of information myself in the future? :wink: )
When I try to use PD3 or PD4 as the output ports I can’t get it to work. Do I need to set something special (other than the DDRx register) to use these ports?
Where can I find some more information about how to use interrupts (if nothing is available I will look at buzzer.c to see how I can use them)

Thanks for the help!

The datasheet is the place to go for answers to most questions having to do with the ATMega168’s internal hardware. You can find the full-text datasheet here, or a much shorter summary datasheet here.

TCNT1 is a 16-bit timer/counter, so it can count from zero up to 65535 (2^16-1).

There’s nothing particularly special about PD3 and PD4, you should be able to set them both as outputs in the DDRD register: DDRD|=(1<<PD3)|(1<<PD4);

To learn more about interrupts you might take a look at Craig Limber’s tutorial: Interrupts and how the heck to deal with them. Craig has a bunch of AVR tutorial pages here.

WinAVR includes a nice macro function “ISR” for catching interrupts, without having to include the signal library or define vectors, and there’s a good explanation of that here.

Out of curiosity are you using AVR Studio with WinAVR, or the Arduino environment? It think the “ISR” macro is implemented in both, but I don’t have as much experience with Arduino.

Anyway, good luck, and of course come back with more questions if you have them.

-Adam

P.S. If you’re interested I can recommend a good comprehensive book on AVR programming in C.

Thanks, that confirms my suspicion (my stepper motor wouldn’t go slower, the timer not being long enough).

[quote]To learn more about interrupts you might take a look at Craig Limber’s tutorial: Interrupts and how the heck to deal with them. Craig has a bunch of AVR tutorial pages here.
WinAVR includes a nice macro function “ISR” for catching interrupts, without having to include the signal library or define vectors, and there’s a good explanation of that here.[/quote]

Thanks for the links, I’ll look throught them when I have the time. It looks like exactly what I need.

I’m using AVR Studio with WinAVR for my programming.

Go right ahead, maybe if I get stuck I might want to dive into the details. I hope I won’t need it because what I am trying to do is pretty simple (move some stepper motors and trigger a camera). My evolutionairy ‘trial and error’ programming skills will hopefully be enough.

Trial and error (and forums and web searches) will take you really far, but eventually I hit a wall.

Someone (on this forum no less) recommended “C Programming for Microcontrollers” by Joe Pardue. It’s a really well written easy read (not the usual dry textbook), and covers almost everything you can do with AVR microcontrollers (and what it doesn’t cover, it leaves you in a better position to coax from the datasheet or find elsewhere). It’s examples use the ATMega169-based AVR Butterfly evaluation board, but it’s applicable to any 8-bit AVR microcontroller.

You can get it from Joe directly at his website: smileymicros.com/ . You can buy the book alone alone, with a variety of kits (probably not necessary if you already have an LV168 to play with) or as an e-book. You can also download Joe’s free AVR quick-start guide, which is really an updated (to include Vista) version of the first three chapters of the book, just to get an idea of his enjoyable writing style.

-Adam

P.S. Not sure if you’re familiar with these, but if you want to timer-interrupt drive your stepper more slowly, you can use different timer prescalers. The way you initialize the timer (TCCR1B|=(1<<CS10):wink: sets it to count every clock tick, so your timer frequency is the same as your system clock frequency. By setting different bits in the TCCR1B register, you can set the timer to count once for every 8, 64, 256, or 1024 system clock ticks. The prescaler bit values are described in table 15-5 on page 134 of the datasheet. It’s a trade off of course, since it lets you generate lower frequencies, but also limits the highest frequency.

Thanks for the book suggestion, I browser through the first chapters and he does indeed have a humerous writing style!

I still can’t get any other pins than PD0 and PD1 to drive the stepper motor driver. Below is the program I used to test, I’ve stripped it to its essentials. I’m treating the PD2 and PD3 exactly the same as the PD0 and PD1 pins, but my stepper motor is not doing anything.

void delay_10us(int d) {
	unsigned int i;	

	for(i=0; i<d; i++) {
			_delay_loop_1(67); // apprx 10us
			}
}

int main(){

	// set DDRx register to output
	DDRD |= 1 << PD0; // PD0 ->output
	DDRD |= 1 << PD1; // PD1 ->output
	DDRD |= 1 << PD2; // PD2 ->output
	DDRD |= 1 << PD3; // PD3 ->output

	while(1){

	// set ports high
	PORTD |= 1 << PD0;
	PORTD |= 1 << PD1;
	PORTD |= 1 << PD2;
	PORTD |= 1 << PD3;
	delay_10us( 50 );

	// set ports low 
	PORTD &= ~(1 << PD0);
	PORTD &= ~(1 << PD1);
	PORTD &= ~(1 << PD2);
	PORTD &= ~(1 << PD3);
	delay_10us(50);
  	}
}

On a side not: I’ve tested the terminal connection to the Orangutan with LV168Demo4 and it worked the first time, I’m well pleased with that! :astonished: It means I can drive my camera rig using a serial connection from a laptop (sending rotate commands to the Orangutan over a serial connection). I can control the rig much easier that way, and I might be able to program most of the stuff in PHP (which I have a bit more experience with).

Hello.

How are you connecting your stepper motor to pins PD2 and PD3? If you look at the schematic, you can see that pin PD2 is one of the LCD control lines, and PD3 controls one side of one of the H-bridges. It sounds like you want to be using the user I/O lines, in which case you’re restricted to pins PD0, PD1, and PC0 - PC5. The silkscreen on the back of the PCB tells you which user I/O pin is which.

- Ben

That was indeed what I was doing. I mistakenly assumed the IO lines were named PD0-PD7.

Thanks for helping me out Ben!