Counter Problems

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

Hi Guys.

Don't know if I should say welcome back or if you guys must say it to me? It's been a long time since I last visisted freaks.

Anycase, happy new year to all. Hope this is a great freak year.

I have this one tiny problem is is giving me a HUGE headache. I have a hardware setup as follows. 5x 7 segment displays, driven from 7447 and the date is clocked serially to the displays via shift registers. They work 100% fine as I want them to.

Then I have resistor matrix for a Keypad that I run through the ADC0. this also works as it should. I can read the key and display either the ADCH or the key value (Key_Val = 0x01 for example) on the displays.

Now, I have a counter that should increase when "Key 1" is pressed. I simulate the code in AVR Studio and I added a whatch window and it does what I want it to. For some od reason, the hardware doesn't want to display the required routine when the counter increases.

I've commented out all the different routines I've tried, maybe that will help to explain my problem.

Please have a look at my code and comment.

Thank you

#include  
#include  
#include  

/******************************************************************************
AVR pins connected to 74HCT565
******************************************************************************/
#define DISP_PORT                PORTC
#define DISP_CLOCK_PIN           5
#define DISP_RSDS_PIN            4
#define DISP_LATCH_ENABLE		 3
#define DISP_MR					 2

/******************************************************************************
Variables
******************************************************************************/
volatile char Key_Val = 0x00;
volatile char freq_cntr = 0x00;
volatile int K_function = 0;

/******************************************************************************
ADC Init
******************************************************************************/
void ADC_Init()
	{
   		ADCSR |= (1<<ADPS1)|(1<<ADPS2); 	// Prescale 64 -> ADC clock is 125kHz 
   											// Leave MUX3-0 in ADMUX = 0 for ADC0 
   		ADMUX |= (1<<REFS0)|(1<<ADLAR); 	// AVCC with external capacitor 
   											// at AREF pin, Left justify    
   		ADCSR |= (1<<ADEN); 				// Enable the ADC 
 	}

/******************************************************************************
Write Shift Register
******************************************************************************/
void DISP_load_byte(uint8_t out_byte)
	{
   		DISP_PORT &= ~_BV(DISP_CLOCK_PIN);
    	DISP_PORT &= ~_BV(DISP_LATCH_ENABLE);    
        	int i;
        	for(i=0; i<8; i++)
        		{
                	if (out_byte & 0x80)
                		{
                        	DISP_PORT |=_BV(DISP_RSDS_PIN); 
                		}
                	else
                		{
                            DISP_PORT &= ~_BV(DISP_RSDS_PIN);
                		}
        			out_byte = out_byte << 1;
					DISP_PORT &= ~_BV(DISP_CLOCK_PIN);
					DISP_PORT |= _BV(DISP_CLOCK_PIN);
        		}
		//DISP_PORT |= _BV(DISP_LATCH_ENABLE);
	}

/***********************************************************************************
Read Key
***********************************************************************************/
void Read_Key()
 	{
   		ADCSR |= (1<<ADSC); 					// Start conversion 
   		while(! (ADCSR & (1<<ADIF)) ); 			// Wait for ADC conversion complete 
   		ADCSR |= (1 << ADIF);
 	}

/******************************************************************************
Frequency Selection
******************************************************************************/
void Freq_Disp()
 {
   switch (freq_cntr)
	 {
	case 0x00 :
		DISP_load_byte(0xFF);
		DISP_load_byte(0xFF);
		DISP_load_byte(0xFF);
		//DISP_PORT |= _BV(DISP_LATCH_ENABLE);
	 break;

	case 0x01 :
		DISP_load_byte(0xFF);
		DISP_load_byte(0x12);
		DISP_load_byte(0x50);
		//DISP_PORT |= _BV(DISP_LATCH_ENABLE);
	 break;
	 
	case 0x02 :
	 	DISP_load_byte(0xFF);
		DISP_load_byte(0x25);
		DISP_load_byte(0x00);
		//DISP_PORT |= _BV(DISP_LATCH_ENABLE);
	 break;

	case 0x03 :
	 	DISP_load_byte(0xFF);
		DISP_load_byte(0x50);
		DISP_load_byte(0x00);
		//DISP_PORT |= _BV(DISP_LATCH_ENABLE);
	 break;

	case 0x04 :
		DISP_load_byte(0xF1);
		DISP_load_byte(0x00);
		DISP_load_byte(0x00);
		//DISP_PORT |= _BV(DISP_LATCH_ENABLE);
	 break;
   }
 DISP_PORT |= _BV(DISP_LATCH_ENABLE);
}

/******************************************************************************
Selection Routine
******************************************************************************/
void Selection_Routine()
 {
	switch(Key_Val)
	 {
		case 0x00:
			asm("NOP" ::);
		break;

		case 0x01:
			freq_cntr += 1;
			Freq_Disp();
			Key_Val = 0x00;
		break;

		case 0x02:
			freq_cntr = 2;
			Freq_Disp();
		break;

		case 0x03:
			freq_cntr = 3;
			Freq_Disp();
		break;

		case 0x04:
			freq_cntr = 4;
			Freq_Disp();
		break;

		case 0x05:
			DISP_load_byte(0xFF);
			DISP_load_byte(0xFF);
			DISP_load_byte(0xFF);
			DISP_PORT |= _BV(DISP_LATCH_ENABLE);
			Key_Val = 0x00;
		break;
	 }
 }

/******************************************************************************
Key Detection
******************************************************************************/
void Key_ADC_Val()
	{
		if ((ADCH >= 0x18) && (ADCH <=0x25))		//9
		 {	
			Key_Val = 0x01;	
			_delay_ms(5);
		 }

		if ((ADCH >= 0x27) && (ADCH <=0x2D))		//5
		 {	
			Key_Val = 0x02;	
			_delay_ms(5);						
		 }
		
		if ((ADCH >= 0x31) && (ADCH <=0x34))		//1
		 {	
			Key_Val = 0x03;							
			_delay_ms(5);
		 }
		
		if ((ADCH >= 0x40) && (ADCH <=0x43))		//10
		 {	
			Key_Val = 0x04;
			_delay_ms(5);
		 }
		
		if ((ADCH >= 0x5A) && (ADCH <=0x5F))		//6
		 {	
			Key_Val = 0x05;							
			_delay_ms(5);
		 }
		
		/*if ((ADCH >= 0x6F) && (ADCH <=0x73))		//2
		 {	
			Key_Val = 0x06;							
			_delay_ms(5);
		 }
		
		if ((ADCH >= 0x90) && (ADCH <=0x95))		//11
		 {	
			Key_Val = 0x07;							
			_delay_ms(5);
		 }
		
		if ((ADCH >= 0xB0) && (ADCH <=0xBE))		//7
		 {	
			Key_Val = 0x08;							
			_delay_ms(5);
		 }
		
		if ((ADCH >= 0xC1) && (ADCH <=0xCE))		//3
		 {	
			Key_Val = 0x09;							
			_delay_ms(5);
		 }
		
		if ((ADCH >= 0xDA) && (ADCH <=0xDF))		//12
		 {	
			Key_Val = 0x0A;	
			_delay_ms(5);
		 }
		
		if ((ADCH >= 0xE9) && (ADCH <=0xEC))		//8
		 {	
			Key_Val = 0x0B;							
			_delay_ms(5);
		 }
		
		if ((ADCH >= 0xED) && (ADCH <=0xF9))		//4
		 {	
			Key_Val = 0x0C;							
			_delay_ms(5);
		 }*/
	}

/******************************************************************************
Main
******************************************************************************/
int main(void)
	{

		ADC_Init();
		DDRC |= (1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2);	//Set PC2,3,4,5 as output
		DDRC &= ~(1<<PC0);								//Set PC0 as input
		sei();											//Enable global interrupt
		DISP_PORT |= _BV(DISP_CLOCK_PIN);

		while(1)
			{
				Read_Key();
				Key_ADC_Val();
				Selection_Routine();
				
			}
	}

/******************************************************************************
END*****END*****END*****END*****END*****END*****END*****END*****END*****END****
******************************************************************************/

I've edited the code so that it's a bit shorter and not so many text that's not being used.

Last Edited: Wed. Jan 7, 2009 - 02:21 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

For some odd reason, the hardware doesn't want to display the required routine when the counter increases.

On the face of it, it looks like it should work so can you tell us some more about what that sentence means? Is Freq_disp() simply not being called (and how do you determine that?) or is it always showing the same thing? Could it simply be that because in real life these things are going to work 1,000's of times faster than the simulator that it's just looping through values 0x00 to 0x0B so quickly that you never seen them? (there's a strong argument here for ALWAYS including a "default:" case in a switch statement!). I don't see you doing anything to handle the situation of wrapping freq_cntr back to 0x00 when it reaches 0x0B

Cliff

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

I Clawson. Long time no see/read.

Ok, on startup, the displayes display 00000. as soon as I press "Key 1" it displays 125. It keeps displaying it until I press Key 9 or B that I just added for testing purposes.

Key 9 display 6000 and key 12 display nothing, well FFFFF actually which clears the displays.

I haven;t inserted the wraparound yet cause I can't get it to display 250 when I press key 1. If I press K12 and the displays are cleared (due to FFFFF being writen to the 7 seg disp) and I press K1 again, 125 will be displayed again, even K9 will display 6000. I can then again press K1 and 125 will display. But according to me, if I press K1 twice, the counter should increase 2 times and 250 should be displayed.

btw, I use the shift program 3 times before I clock the latches so that I can move in 24bit of date of that routine.

thanks

Hope this is enough info? Let me know if you need more.

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

Hi All.

Do you guys need more info? Just wondering why I don't get any replies.

:( :( :(