whats wrong with this code?

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

Hello,
I'm writing the code for a fairly simple digital timer with a 2 digit multiplexed 7 segment display. I'm using a 32kHz crystal on timer2 to give me a timebase but i run into trouble before I even enable interrupts. As per the mega48 datasheet I put in a delay to allow th crystal to spin up before setting the timer to async mode. Heres the setup code:

static inline void hardwareSetup()
{
int i,j;

//configure i/o pins
DDRB = 0;//port b0-b3 i/p leave rest as i/p
PORTB = 0b00001111;//configure pullups on port c0-c3
DDRC = 0b00110000;//port c0-c3 i/p c4,c5 o/p c6 config as reset
PORTC =0b00001111;//configure pullups on port c0-c3
DDRD = 0xff;//port d all outputs

//setup async timer for simple overflow interrupt interrupts at 128hz
TIMSK2 = 0;//disable timer2 interrupts 
#ifndef NOLOOP
PORTD = 0b00111111;//set display to show zeros
for(i = 0; i<0x00ff;i++)//wait for clock to stabilize
{
	for(j = 0;j < 0x00ff;j++)
		PORTD ^= 0b10000000;//mux display
}
#endif
#ifndef DEBUG
ASSR =(1<<AS2);//set AS2 bit in ASSR for async mode
#endif

TCCR2A = 0;//normal mode
TCNT2 = 0;//clear timer

//shut down unused peripherals
ACSR =(1<<ACD);//disable comparator
ADCSRA = (1<<ADEN);//dissable adc

#ifndef DEBUG
PRR =(1<<PRTWI)|(1<<PRTIM0)|(1<<PRTIM1)|(1<<PRSPI)|(1<<PRUSART0)|(1<<PRADC);
set_sleep_mode(SLEEP_MODE_PWR_SAVE);//sleep mode in power save mode
#endif

while(ASSR & 0x0f);//wait for updates to finish

return;
}

The problem i have is that the AVR somehow gets stuck in the for loop section. It just sits there displaying a single zero which to me says that its not even multiplexing the display. If I lower the number on the outer loop to 0x0040 it works just fine. I feel like I'm missing something obvious but I can't tell what I'm doing wrong :oops:

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

Are u sure that it is stuck in for loop.

Shanthi

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

Watchdog timer on and not cleared/reset? then it continually fires in a few ms and you do it all again?

Lee

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

koyashanthi wrote:
Are u sure that it is stuck in for loop.

yes. If I
#define NOLOOP

then the circuit behaves as it should. If I comment it out my 2 digit display shows 1 zero which means that bit 7 isnt toggling since the only time the display is set to show zeros is in that code block theres no other place it can be as far as I can tell. The realy weird part is that the whole program works just fine on the simulator.
theusch: As far as I know I never enabled the watchdog at all. None of my code touches it

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

twidget2 wrote:

If I lower the number on the outer loop to 0x0040 it works just fine.

Change the number on the outer loop to some value other than 0x40 and check.

After your for loop re initialise PORTD = 0b00111111 and check if it is working.

Shanthi

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

Well what does the generated Asm look like and what happens when you single step through it in the simulator (or better yet using an OCD interface to the chip)?

Cliff

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

clawson: I tried debugwire originally but that ended with an avr that was apparently in neither isp nor debugwire mode. Apparently something didn't like me playing with the PRR register while debugging. I'm kinda afraid of trying again since this is my last DIP mega48. The code simulates perfectly btw. I don't know how to generated ASM from my c code and I wouldn't know what I was looking at in any case. I'll be happy to post it if you can tell me how to generate it though.
After further tinkering with the code I have decided that the for loop probably isn't the problem.I tried commenting out anything involving the sleep function and the problem seems to have gone away. Of course it was intermittent before so I could just have not gotten it yet. Also I got the same results initially by removing the for loop. Whatever this thing is its doing a good job of hiding from me.

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

Check the ASM code in the generated .lss file.

Shanthi

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

Though the .lss can be a bit muddled as it's an attempt to disassemble the final .ELF, if you use an Mfile generated Makefile then "make filename.s" will show you the assembler generated by the C compiler for filename.c and is usually "easier to read".

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

I've been using avrstudio combined with winavr. I know where the makefile is but what is the actual command to make the project?I assume I open a terminal and do something like c:\ make filename.s but I don't have much command line experience with windows.
Also i just went over the mega48's datasheet again over lunch and it says that the xt2 pins are optimized for 6pF crystals. I'm not sure what the capacitance is for the crystal I used but I think it might be of the 12.5pF variety. Could the difference in capacitances be enough to cause the crystal to intermittently stop oscillating during power save mode?

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

If you use Studio then when you go to the Build menu and select Build All what happens is that in a sub-directory called "default" created off the directory where your .c, .h and project files are it temporarily creates a Makefile and then invokes the command line "make.exe" tool which goes on to read the commands in the Makefile and process them. So you don't have to worry about command line making. But this does mean you can't use "make filename.s". However in that default sub-dir, as long a your project config has a tick in the "generate lss" box there will be a complete disassembly file called projectname.lss created.

Cliff