That's a strange behaviour... The motor should spin only when D0=D1=1 and D2=0. At any other case it should stop. If this is not the behaviour, then something else is wrong. Of course it could be improved, but you must be sure first. Did you debug the code?
1) Which breakpoint is hit after reset?
2) Which breakpoint is hit when you connect D2 to ground?
PS: Don't forget the PORTD |= 7; command before while (1), to make the pull up resistors.
blackcsc said:I taken out the pull up resistors command because i wan D2 = 1 to spin..
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 int main(void) { DDRB |= (1<<PB1); TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM11); TCCR1B|=(1<<WGM13)|(1<<WGM12)|(1<<CS11); DDRD = 0x00; ICR1 = 9999; OCR1A = 0; PORTD |= 0x04; //make D2 pull up while(1) { if (PIND & 0x04) //if D2 pin is unconnected { OCR1A = 0; } else //pin is grounded { OCR1A = 1520; } } return 0; }
blackcsc said:how do i use the debug with the hardware @@ I thought debug is only for programming in avr studio ? I dont know which breakpoint is hit..
That explains a lot... The code you originally posted turns the motor if D2 = 0 and not 1.
Do you want to do something simpler? Download this code:
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 int main(void) { DDRB |= (1<<PB1); TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM11); TCCR1B|=(1<<WGM13)|(1<<WGM12)|(1<<CS11); DDRD = 0x00; ICR1 = 9999; OCR1A = 0; PORTD |= 0x04; //make D2 pull up while(1) { if (PIND & 0x04) //if D2 pin is unconnected { OCR1A = 0; } else //pin is grounded { OCR1A = 1520; } } return 0; }
The scenario is that you don't care for other pins any more, except D2. Leave D2 unconnected and the motor is NOT spinning. Give ground to D2 and the motor starts spinning. When you remove ground again from D2 pin, motor stops spinning. Try that to verify that your PORTD code runs OK. If the PORTD code is OK and still there are problems, then we will figure out what is wrong.
I don't use AVR Studio a lot. When I do I use AVR Studio 4. Go to Menu bar and then Debug->Select Platform and device and then select JTAGICE mkII (if mkII is already selected, then skip this step). Then Debug->Start Debugging. When you enter the debug mode, click the cursor on OCR1A = 0; line and click F9 (that is place breakpoint). Do the same with OCR1A = 1520; line. Two red spots on the left should appear, which means that breakpoints are placed. Leave D2 pin unconnected and push F5 (run). Where did the code stopped? It should stop to OCR1A = 0; line. Then connect D2 to ground, leave the ground there and press F5 again. This time the code should stop at OCR1A = 1520; line. If that happens, remove breakpoints (again with F9) and press F5 to run, you should have a working code from PORT code point of view.
blackcsc said:when D0 & D1 is "1", then motor spin and when D0, D1 and D2 is "1" then i turn back to 0.. That is why i need the case to be 0x03 and 0x07 in PortD to set the condition.. Can this rule applied to your code ?
Sure. Instead of if-else, use your cases as described in posts 12 and 13 and place breakpoints inside cases to see if they will be hit.
blackcsc said:u mean using back the same pull up at PD2 |= 0x04 and replace the if else condition with my cases ?
PORTD |= 0x07 and yes, replace if - else with the cases. Try to debug efficiently.
blackcsc said:instead of GND it to turn the motor, i want it to be HIGH then it'll turn the motor..
if (PIND & 0x07) //if D0=D1=D2=1
{
OCR1A = 1520;
}
else //even one of D0, D1, D2 is low
{
OCR1A = 0;
}
if (PIND=0x03) line, means that the motor starts moving when D0=D1=1 and ALL other PORTD pins including D2 is 0. So the motor should spin ONLY when D0=D1=1 and D2=0.
So it is expected from the motor to turn when you give 5V to D1. But not D2. According to your code the motor will spin ONLY when D2=0.
Code:if (PIND & 0x07) //if D0=D1=D2=1 { OCR1A = 1520; } else //even one of D0, D1, D2 is low { OCR1A = 0; }
I think this is what you are asking, when D0, 1 and 2 qre high, motor is spinning. Else motor stops.
---------- Post added at 12:25 ---------- Previous post was at 12:05 ----------
Also post your circuit to see how you drive inputs.
alexxx said:if (PIND & 0x07) //if D0=D1=D2=1
Code C - [expand] 1 if (PIND & 0x07) //if D0=1 OR D1=1 OR D2=1
Code C - [expand] 1 if ((PIND & 0x07)==7) //if D0=1 AND D1=1 AND D2=1
According to what you read above, this was an expected behaviour.blackcsc said:When i simulated it, either D0 D1 = 1 it will turns..
blackcsc said:i tried the code below but the motor do not response again.. WHY !!! haix
Code C - [expand] 1 2 3 4 5 6 7 8 if (PIND == 0x03) { OCR1A = 1520; } else { OCR1A = 0; }
Code C - [expand] 1 2 3 4 5 6 7 8 if ((PIND & 0x03)==3) //if D0=D1=1 { OCR1A = 1520; } else //D0 or D1 or both are low { OCR1A = 0; }
Sorry blackcsc, I made a mistake at my previous post.
This is wrong. The right thing to say was:
Code C - [expand] 1 if (PIND & 0x07) //if D0=1 OR D1=1 OR D2=1
if you needed all D0, D1 and D2 ports to be 1, you should write:
Code C - [expand] 1 if ((PIND & 0x07)==7) //if D0=1 AND D1=1 AND D2=1
According to what you read above, this was an expected behaviour.
PIND is an 8 bit register. Every bit represents the status of the corresponding pin. LSB = D0 and MSB = D7. So PORTD=0x03 means that PORTD=00000011b, which means that D0=D1=1, AND D2=D3=D4=D5=D6=D7=0. According to the above code, PIND should be 0x03 to start the motor, that is D0=1 AND D1=1 AND all other pins=0. So if one of D0 or D1 is low, motor won't start. If D0 AND D1 are high but another PORTD pin is also high, then motor won't start again. If you need the motor to depend ONLY on D0 and D1, then you should edit your code as follows:
Code C - [expand] 1 2 3 4 5 6 7 8 if ((PIND & 0x03)==3) //if D0=D1=1 { OCR1A = 1520; } else //D0 or D1 or both are low { OCR1A = 0; }
Hope that helped.
blackcsc said:if ((PIND & 0x07)==3) //if D0=D1=1
if ((PIND & 0x03)==3) //[I]if D0=D1=1 (we don't care about D2 anymore)[/I]
blackcsc said:But could you explain what is PIND & 0x03 ? D0 or D1 or D2 ?? & is OR ?
Not exactly. The exact explanation would be: if D0=D1=1 AND D2=0
What you meant was:
Code C - [expand] 1 if ((PIND & 0x03)==3) //[I]if D0=D1=1 (we don't care about D2 anymore)[/I]
About AVR I/O read the datasheet carefully, it is a simple part to understand. In quick words:
DDRX register controls if PORTX pins will be inputs or outputs
PORTX registers controls a) The pull up if pin is input and b) Pins logic level ('0' or '1') if pin is output
PINX register is read only, you read it to discover if a pin has '1' or '0' on it.
After you read AVR ports carefully, take a look at this thread, you will learn a delicate way to handle your AVR Ports in AVR studio, read it from the beggining:
https://www.edaboard.com/threads/218763/#post930071
This is bitwise AND, you do it to keep only bit0 and bit1 unchanged, all other bits go to 0. So since you know that all bits except bit0 and bit1 are 0, the possible results could be 0, 1, 2 and 3. If the result is 3 and since we are talking about PIND, then D0 = D1 = 1.
Alex
Code C - [expand] 1 2 3 4 5 8Mhz clock freq with prescaler of 8 I get 50 hz and 20ms circyle then i got ICR1 = 9999 Motor datasheet : 1520 is in neutral position // 90 degree ? what should i get for 0 degree ?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?