Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Need help on I/O for Atmega48 C coding

Status
Not open for further replies.

blackcsc

Junior Member level 1
Joined
Jul 18, 2011
Messages
17
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,424
Dear all,

I need help on this simple I/O detect and react c coding.. I'm using AVR Studio as the compiler and below is my codes, i tried alots of time and it jz doesnt works as aspected.. Could anyone help me up with this ? I just want the input detect on the 1st 3 pins on Port D to gives an output at PORTB as pwm signal..

while(1)
{
switch (PIND)
{
case (0x03):
{
OCR1A = 1520;
break;
}
case (0x07):
{
OCR1A = 0; // 0 Degree
break;
}
default:break;
}
}
 

You might need to set other registers to configure them as input/output
 

You might need to set other registers to configure them as input/output

Hi John, do u mind explain further ? which registers should i configure ?

DDRB |= (1<<PB1);
DDRD = 0x00;

i declared this 2 as input n output..
 

mind explaining what doesnt work as aspected? :)
 

Please also show us your PWM initialization code and tell us what is going wrong.
Is there a problem with I/O or PWM?
 

Please also show us your PWM initialization code and tell us what is going wrong.
Is there a problem with I/O or PWM?

DDRB |= (1<<PB1);
TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);
TCCR1B|=(1<<WGM13)|(1<<WGM12)|(1<<CS11);
DDRD = 0x00;

while(1)
{
switch (PIND)
{
case (0x03):
{
OCR1A = 1520;
break;
}
case (0x07):
{
OCR1A = 0;
break;
}
default:break;
}
}
return 0;
}

above is the coding that i'd tried.. What i actually wan is when i have input on Pind0 & PinD1 then OCR1A will have output then when PinD0 & PinD1 & PinD2 got input, i should have OCR1A back to 0.. It tat how i configure my code ?? Actually i'm trying to get my servo motor to turn with the codes above.. Is tat the way 2do it ?? Sorry i'm very new to mcu programming @@ Just started to learn on it.. Mind to help me here ? Thanks alot !!!
 

Your while(1) code looks OK. However, make sure that no other pin except D0, 1 and 2 is high, otherwise this code will not work.
About PWM initialization, I think that since you are using Fast PWM - Mode 14 you need to also store a value to ICR1 register, otherwise you start a count from 0 and ends to 0. I'm not 100% sure, but try this out and tell us what happened. It should be something like ICR1 = MCU_FREQUENCY_HZ / PWM_DESIRED_FREQUENCY_HZ.

Alex
 

thanks Alex, i left out the ICR1 when copy the code @@ I did have that but i still cant get the motor working when i burned it onto my mcu.. That's why i'm curious why the code doesn't work.. I checked through some other sample codings, it should be working @@ 1 more thing, if i test it on hardware right, can i just connect 5v to D0, D1 and D2 as input ? I cant get the motor reacting with inputs... Anyway to find out where is the problem ?

"make sure that no other pin except D0, 1 and 2 is high, otherwise this code will not work"
I tot the condition was in the loop ? Meaning that the mcu will continuously check on the input to response ? If other pin is high, it wouldnt response but once i get the correct condition then it will response ? Is this what i suppose to get ?

Anyone can help me to check on this codes ? where did i do wrong ?
 

blackcsc said:
If other pin is high, it wouldnt response but once i get the correct condition then it will response ? Is this what i suppose to get ?
To be independent of the other PORTD pins, edit your code as follows:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
volatile unsigned char _PIND;
while(1)
{
  _PIND = PIND & 0x07;  //No need to worry about D3 - D7 pins any more
 
  switch (_PIND)  //You now read only D0 - D2 pins
  {
   case (0x03):
   {
     OCR1A = 1520;
     break;
   }    
   case (0x07):
   {
     OCR1A = 0;
     break;
   }    
   default:break;   
  } 
}



I just noticed that if D0 = D1 = 1 (case 0x03), then you constantly feeding the OCR1A register with the same value over and over again, but still I don't think this is a problem since you just set the duty cycle and nothing more.


blackcsc said:
can i just connect 5v to D0, D1 and D2 as input ? I cant get the motor reacting with inputs
Of course. In the matter of fact do that. Then if you have an osciloscope, see on the MCU pin if PWM is produced or not. If no, then there is a problem with the code. If yes, then it is a hardware problem. Also supply the motor edges directly to + and - and see if it spins. If yes, then the motor is OK. What interface do you use in between of the MCU and the motor? Post your circuit, maybe there is a hardware problem.
 

To be independent of the other PORTD pins, edit your code as follows:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
volatile unsigned char _PIND;
while(1)
{
  _PIND = PIND & 0x07;  //No need to worry about D3 - D7 pins any more
 
  switch (_PIND)  //You now read only D0 - D2 pins
  {
   case (0x03):
   {
     OCR1A = 1520;
     break;
   }    
   case (0x07):
   {
     OCR1A = 0;
     break;
   }    
   default:break;   
  } 
}



I just noticed that if D0 = D1 = 1 (case 0x03), then you constantly feeding the OCR1A register with the same value over and over again, but still I don't think this is a problem since you just set the duty cycle and nothing more.


Of course. In the matter of fact do that. Then if you have an osciloscope, see on the MCU pin if PWM is produced or not. If no, then there is a problem with the code. If yes, then it is a hardware problem. Also supply the motor edges directly to + and - and see if it spins. If yes, then the motor is OK. What interface do you use in between of the MCU and the motor? Post your circuit, maybe there is a hardware problem.

I'm trying it on breadboard.. sadly after adding the edited codes, now the motor turns w/o meeting the condition that case 0x03 / 0x07... meaning, no input but the motor turns.. any idea what had caused it so ??
 

blackcsc said:
after adding the edited codes, now the motor turns w/o meeting the condition that case 0x03 / 0x07... meaning, no input but the motor turns..
That's good, it means that the circuit is working!:grin:

Check if you have pull up enable, that is check PORTD value! The three LSBs should be 0 (PORTD = XXXXX000b, X= don't care). If pull ups are disabled, then make sure you won't leave the inputs floating, give a clear signal '0' or '1'. Either way, it would not be a bad idea to enable pull up:

Code:
PORTD |= 0x07;  //make pull up on pins D0, D1 and D2


EDIT:
Or maybe you could also add a default case as well:

Code:
  default:  //Now the motor will turn only when D0, 1 and 2 are high
  {
    OCR1A = 0;
    break;
  }


Hope that helped.
 
Last edited:

That's good, it means that the circuit is working!:grin:

Check if you have pull up enable, that is check PORTD value! The three LSBs should be 0 (PORTD = XXXXX000b, X= don't care). If pull ups are disabled, then make sure you won't leave the inputs floating, give a clear signal '0' or '1'. Either way, it would not be a bad idea to enable pull up:

Code:
PORTD |= 0x07;  //make pull up on pins D0, D1 and D2


EDIT:
Or maybe you could also add a default case as well:

Code:
  default:  //Now the motor will turn only when D0, 1 and 2 are high
  {
    OCR1A = 0;
    break;
  }


Hope that helped.

Thanks alot Alexxx, i tried with your suggestion but still no luck, should i declare the pull up before while loop on inside while loop ? I couldnt get any response either after adding those codes and giving the clear 1 and 0..

#include <avr/io.h>
#include <util/delay.h>

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;

volatile unsigned char _PIND;
while(1)
{
_PIND = PIND & 0x07; //No need to worry about D3 - D7 pins any more
PORTD |= 0x07; //make pull up on pins D0, D1 and D2

switch (PIND)
{
case (0x03):
{
OCR1A = 1520; // 90 Degree
break;
}
case (0x07):
{
OCR1A = 0; // 0 Degree
break;
}
default:
{
OCR1A = 0;
break;
}
}
}
return 0;
}
 

blackcsc said:
I couldnt get any response either after adding those codes and giving the clear 1 and 0..

The PORTD |= 0x07; command should go before while(1), but anyway it doesn't affect the behaviour.
Furthermore, edit your code as follows:

Change the switch (PIND) line to switch (_PIND).


Hope that helped.
 

The PORTD |= 0x07; command should go before while(1), but anyway it doesn't affect the behaviour.
Furthermore, edit your code as follows:

Change the switch (PIND) line to switch (_PIND).


Hope that helped.

Hi Alex, earlier on i was testing on (_PIND) but i couldnt get it, so the code i copied is actually i changed it back to PIND and goes without the PORTD & 0x07.. And i also tried to place the PORTD |=0x07 before the while loop but the motor keep turning even without input from PIND, and from Proteus i saw the Pins was on even before the input was placed.. Is it strange that i couldnt get it work on the hardware ? Anyone have the codes that the hardware worked ? I curious how come my hardware doesnt work :( Did i missed out anything ? 1 more thing, i'm using Atmega48PA will that affect the circuit ?
 

OK. Are you using a debugger or a programmer? I mean can you run your code step by step?

Because the port is readed with the correct way. With this code you can leave all D0, 1 and 2 floating (and since the internal pull up is there they are high). When you give ground to D2, the motor is supposed to start and when you remove ground from D2 it is supposed to stop. This is not a problem of the port code. Did you check with the voltometer the voltage on D1, D2, D3 when motor spins?
 

OK. Are you using a debugger or a programmer? I mean can you run your code step by step?

Because the port is readed with the correct way. With this code you can leave all D0, 1 and 2 floating (and since the internal pull up is there they are high). When you give ground to D2, the motor is supposed to start and when you remove ground from D2 it is supposed to stop. This is not a problem of the port code. Did you check with the voltometer the voltage on D1, D2, D3 when motor spins?

Which mean now my input should be 0 to run the motor and 1 will not have output ? Programmer or debugger ? I'm using AVR Studio and programmer is AVR MKII.. Yes, i can run step by step in debugging mode..
 

OK you have a debugger that's good.

Place 2 breakpoints inside cases. One will go to OCR1A = 1520; (case 0x03) and one to OCR1A = 0; (case 0x07). Also put a third at OCR1A = 0; (case default). Leave all the inputs unconnected. Run at full speed (F5). The breakpoint inside case 0x07 should be hit. Do that 3-4 times in a row, all times the same breakpoint should be hit. Then connect D2 to ground. Run again. This time the 0x03 case breakpoint should be hit. Again verify it 3-4 times. If that works OK, then it is not a PORTD problem. If not, then measure the voltage to D0, 1 and 2 pins to see if they have the proper voltage.


Try that and tell us what happened.
 

OK you have a debugger that's good.

Place 2 breakpoints inside cases. One will go to OCR1A = 1520; (case 0x03) and one to OCR1A = 0; (case 0x07). Also put a third at OCR1A = 0; (case default). Leave all the inputs unconnected. Run at full speed (F5). The breakpoint inside case 0x07 should be hit. Do that 3-4 times in a row, all times the same breakpoint should be hit. Then connect D2 to ground. Run again. This time the 0x03 case breakpoint should be hit. Again verify it 3-4 times. If that works OK, then it is not a PORTD problem. If not, then measure the voltage to D0, 1 and 2 pins to see if they have the proper voltage.


Try that and tell us what happened.

Hi alexxx, u mean the debugger for the hardware ? Or just the AVR studio debugger ? Or the simulation debugger ? When i try the code in AVR debugger, it keeps hitting default case, that's why the condition cant achieve.. I tried to disable all input but yet still hitting default when running it.. If on hardware, D0 D1 and D2 all having proper input as i connected it to 5v..
 

blackcsc said:
If on hardware, D0 D1 and D2 all having proper input as i connected it to 5v..

Forget about simulator, I mean real time hardware debugging. Since you have all inputs at '1' after reset, then case 0x07 breakpoint should be hit. When you give ground to D2, then the 0x03 case breakpoint should be hit. The default case breakpoint should never be hit when debugging in real time. So tell us what happens when you hardware debug in real time.

Alex
 

Forget about simulator, I mean real time hardware debugging. Since you have all inputs at '1' after reset, then case 0x07 breakpoint should be hit. When you give ground to D2, then the 0x03 case breakpoint should be hit. The default case breakpoint should never be hit when debugging in real time. So tell us what happens when you hardware debug in real time.

Alex

I'd ignored the pull up, so when i tested on the hardware, this is what i get now, when D1 is pull out from GND, the motor turns, then i put it to 5v, motor remains, when i pull D2 from GND to 5v also the same.. Is that suppose to be like that ? Because of this :

volatile unsigned char _PIND;
while(1)
{
_PIND = PIND & 0x07; //No need to worry about D3 - D7 pins any more ??

When the inputs remain floating then the motor will turns once awhile.. Thanks alexxx :) At least i can have the motor turns with condition :) But can it be improved anyway ?
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top