Can't read PC0 and PC1

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

Hi Guys,

 

I'm stuck with a problem. As in the title I can't read the PC0 and PC1 register when they are set as inputs. I am trying to read an 8 button array.

 

Here's what I know:

 

- The pins on the microcontroller are definitely being pulled low by the external button circuitry. (Logic low on pin is fine)

- The code relating to the reading of the pins works when pins from the B register are used instead of the C register.

 

Here's my code, it's for stepper driver control. The buttons currently stop and start a repeating square wave, the PC inputs are supposed to control the ramping routine. I used arrays to hold variables for the debouncing and everything seems to work except the above problem.


#define F_CPU 8000000
#include <avr/io.h>				// this is always included in AVR programs
#include <avr/interrupt.h>
#include <util/delay.h>



/*************************
~~Interrupt Service Routines~~
This ISR increments a tick that is counted in the code
for task orchestration.

 *************************/ 

volatile uint8_t tick = 0;

    ISR(TIMER1_COMPA_vect) {
	    tick += 1;
    }
    
	
	

int main(void)
{
	
/*************************
~~Inputs and Outputs~~

 *************************/ 	
	/*
	B0 = Input => 
	B1 = Input => 
	B2 = Input =>  
	B3 = Input => 
	B4 = Input => 
	B5 = Input => 
	
	C0 = Input => 
	C1 = Input =>
	
	C4 = Output => Enable
	C5 = Output => Direction
	D0 = Output => Step
	D1 = Output => 
	
	 */ 

/*************************
~~Microcontroller Setup~~

 *************************/ 
	MCUCR |= (1 << PUD); // Set inputs to high impedance 
	
	UCSR0B &= ~(1 << RXEN0);
	UCSR0B &= ~(1 << TXEN0);// Turn off USART
	
	PORTB = (1 << PINB0) | (1 << PINB1) | (1 << PINB2) | (1 << PINB3) | (1 << PINB4) | (1 << PINB5);
	DDRB =  0; //(1 << PINB2) | (1 << PINB3) | (1 << PINB4);// | (1 << PINB6) | (1 << PINB7); 1 = output
	
	PORTC = (1 << PINC0) | (1 << PINC1);
	DDRC = 0;//(1 << PINC0) | (1 << PINC1) | (1 << PINC2) | (1 << PINC3);
	
	PORTD = 0; //(1 << PIND2) | (1 << PIND3) | (1 << PIND4) | (1 << PIND5) | (1 << PIND6) | (1 << PIND7);
	DDRD = (1 << PIND0) | (1 << PIND1);

	ADCSRA = 0; // Turn off ADC circuity in case it is interfering with C register input reading

    TCCR1B = 0;
    TCCR1B = 0;
	OCR1A = 399; // set OCR1A value based on. OCR1A = (Clock frequency / (prescaler * target frequency)) - 1
	// 79 = 10us tick, 399 = 50us tick,	7999 = 1ms tick
	// CS10 no prescaler used.
	// WGM12 is the clear timer on compare enable.
    TCCR1B |= (1 << CS10 ) | (1 << WGM12); 
    TIMSK1 |= (1 << OCIE1A); // Enable output compare register.
   
    sei(); // Globally enable interrupts
    //cli() to disable interrupts
 
   
/*************************
~~Code Variables~~
Variables used in the code are initialized heres

 *************************/     

	int stepTimer = 0; // Counter for the step incrementing task
	int Bin[8] = {0}; // Button inputs for debouncing
	int Blast[8] = {1}; // Stored Button input states
	int BT[8] = {0}; // Keeps track of how many times a button is seen HIGH
	uint8_t timeValue = 10; // Minimum debouncing delay
	bool run = true; // Links debouncing and Output Wave task
	bool rampUp = false; // Links debouncing and ramping task
	bool rampDown = false; // Links debouncing and ramping task
	//bool stepState = true;
	//bool passArr[7] = {0};
	int stepDel = 255;
	

    while (1)
    {
		
/*************************
~~Tick~~
The tick value is incremented by the ISR. Task counters are incremented by the 
tick value before it is reset. The tasks are effectively driven by a prescaler
of the devices clock

 *************************/ 		
	    if(tick > 0)
	    {
			// put counting routines here
			stepTimer+= tick;
			
			tick = 0;
		}
		
// ******** This code will only execute when the task counter has reached a value ********
		if(stepTimer >= stepDel) 
	{
		if( run == 1)
		{
			
/*************************
~~Ramping routines~~


 *************************/ 		
			// code for ramping up delay	
			if (rampUp == true)
			{
				stepDel -= 10;
				if (stepDel <= 40) 
				{
					stepDel = 40;
					rampUp = false;
				}
				
			}
		
			// code for ramping down delay	
			if (rampDown == true)
			{
				stepDel += 10;
				if (stepDel >= 255)
				{
					stepDel = 255;
					rampDown = false;
				}
				
			}
		PIND |= (1<<0);// These set the motor to step
		PIND |= (1<<1);
	//	PINC |= (1<<4);
	//	PINC |= (1<<5);
	
	}
	


			stepTimer = 0;
	}
	
/*************************
~~Debouncing Routines~~
The next task reads though the devices inputs and debounces them
since they are mechanical switches driving the input register values
 *************************/ 

	// Input B0
	Bin[0] = PINB &(1 << 0);
	if (Blast[0] != Bin[0])
	BT[0]++;
	if(BT[0] > timeValue)
	{
		if(Bin[0] == 0)
			{
				run = true;
			}
		
		Blast[0] = Bin[0];
	}
	if(Bin[1] == 1)
	BT[1] = 0;
	
	// Input B1
	Bin[1] = PINB &(1 << 1);
	if (Blast[1] != Bin[1])
	BT[1]++;
	if(BT[1] > timeValue)
	{
		if(Bin[1] == 0)
			{
				run = true;
			}
		
		Blast[1] = Bin[1];
	}
	if(Bin[1] == 1)
	BT[1] = 0;
	
	// Input B2
		Bin[2] = PINB &(1 << 2);
		if (Blast[2] != Bin[2])
		BT[2]++;
		if(BT[2] > timeValue)
		{
			if(Bin[2] == 0)
			{
				run = false;
			}
	
			Blast[2] = Bin[2];
		}
		if(Bin[2] == 1)
		BT[2] = 0;
		
	// Input B3	
		Bin[3] = PINB &(1 << 3);
		if (Blast[3] != Bin[3])
		BT[3]++;
		if(BT[3] > timeValue)
		{
			if(Bin[3] == 0)
			{
				run = false;
			}
			
			Blast[3] = Bin[3];
		}
		if(Bin[3] == 1)
		BT[3] = 0;
		
	// Input B4
		Bin[4] = PINB &(1 << 4);
		if (Blast[4] != Bin[4])
		BT[4]++;
		if(BT[4] > timeValue)
		{
			if(Bin[4] == 0)
			{
				run = false;
			}
			
			Blast[4] = Bin[4];
		}
		if(Bin[4] == 1)
		BT[4] = 0;
		
	// Input B5	
		Bin[5] = PINB &(1 << 5);
		if (Blast[5] != Bin[5])
		BT[5]++;
		if(BT[5] > timeValue)
		{
			if(Bin[5] == 0)
			{
				run = false;
			}
			
			Blast[5] = Bin[5];
		}
		if(Bin[5] == 1)
		BT[5] = 0;
		
	// Input C0
		Bin[6] = PINC &(1 << 0);
		//Bin[6] = PINB &(1 << 4);
		if (Blast[6] != Bin[6])
		BT[6]++;
		if(BT[6] > timeValue)
		{
			if(Bin[6] == 0)
			{
				rampDown = false;
				rampUp = true;
			}
			
			Blast[6] = Bin[6];
		}
		if(Bin[6] == 1)
		BT[6] = 0;
		
	// Input C1
		Bin[7] = PINC &(1 << 1);
		//Bin[7] = PINB &(1 << 5);
		if (Blast[7] != Bin[7])
		BT[7]++;
		if(BT[7] > timeValue)
		{
			if(Bin[7] == 0)
			{
					rampDown = true;
					rampUp = false;
			}
	
			Blast[7] = Bin[7];
		}
		if(Bin[7] == 1)
		BT[7] = 0;




    }
    
    }

 

 

I'm stumped. Any ideas?

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

What AVR are you using?

 

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274

 

 

 

Last Edited: Wed. May 15, 2019 - 07:26 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry, it's an ATmega328p.

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

I'm not seeing anything in the code, could it be a h/w problem?   Mis-wiring perhaps.

How sure are you of loading the code with the portc polling, could you be loading the portb poling code by mistake?

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274

 

 

 

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

Is this the  'haven't connected supply voltage to AVCC pin' ?

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

MrKendo wrote:
Is this the  'haven't connected supply voltage to AVCC pin' ?

+1

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

MrKendo wrote:

 

Here's my code, it's for stepper driver control. The buttons currently stop and start

+1

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

theusch wrote:
MrKendo wrote:

Is this the  'haven't connected supply voltage to AVCC pin' ?

 

+1

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

Muffins wrote:
As in the title I can't read the PC0 and PC1 register when they are set as inputs.
Define "can't read". Clearly it does read something - are you saying it's stuck 0 or stuck 1 or showing random reading unrelated to button state or what? "can't read" isn't really a fault report.

 

Also can you say how you are observing this? Is this a watch window on BT[6]/BT[7] in a debugWire debugger or something else?

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

Hi guys, sorry for the delay.

 

I have the chip setup in a PCB I designed. I have checked the routing and the connections and it's good. The board just adds some protection diodes and resistors to each pin, there is no difference from the C0 and C1 pins to the other pins, they have the same circuitry. I have also uploaded the code to a separate 328p and the same problem occurs.

 

Jim, how would I load the port polling code incorrectly? What do you mean by this?

 

The supply voltage is connected to and present at the AVCC pin. Checked with my scope to confirm.

 

clawson,

 

I have my scope setup on my circuit, watching the signal alternate between low and high and the chip not responding to this. The same code on different pins works fine. My setup is very basic. I have been plugging the chips into an arduino UNO board to upload code to them, then removing them from that board and inserting them into my board.

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

How is your code working for Pin B? 

Last Edited: Sat. May 18, 2019 - 07:34 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Muffins wrote:

	Bin[7] = PINC &(1 << 1);

 

even if PC1 goes HIGH this statement will not be true, because (1<<1) != 1 

 

Muffins wrote:

if(Bin[7] == 1)

 

and similarly, The following statement will always be true

Muffins wrote:

Bin[7] = PINC &(1 << 1);
//Bin[7] = PINB &(1 << 5);
if (Blast[7] != Bin[7])