|
|
View previous topic :: View next topic |
Author |
Message |
Somor
Joined: 18 Dec 2014 Posts: 12
|
Problem with PIC16F628A program |
Posted: Thu Dec 18, 2014 5:47 pm |
|
|
Hello, guys. I'm new in programming PICs, so i am stucked on my new project. The main idea is to make program, that shuffles 2 numbers. So that two numbers i'm trying to display on 2 digits 7 segment indicator VQE 24 (common Anode)
When i compile it (successful) and program then the PIC. After powering the schematic indicator displays F F and dont lights OFF. When in delete the rest of the code after and rebuild and reprogram and put the chip back on the same board with same schematic, the indicator stays F F for 3 seconds then goes OFF as it should be.
The main idea is after FF goes OFF with push button, connected on RB5 pin to shuffle numbers, on release of the button indicator displays 2 numbers.
I'm stucked. I tried to simulate the same source on Proteus and everything works fine.
My not working code is this:
Code: |
#include <new123.h>
#include <stdlib.h>
int8 decoder(int dec)
{
int8 a;
switch (dec)
{
case 0: a = 96;
break;
case 1: a = 249;
break;
case 2: a = 164;
break;
case 3: a = 176;
break;
case 4: a = 57;
break;
case 5: a = 50;
break;
case 6: a = 34;
break;
case 7: a = 248;
break;
case 8: a = 32;
break;
case 9: a = 48;
break;
case 15: a = 46;
break;
}
return a;
}
void main()
{
setup_oscillator(OSC_4MHZ);
set_tris_a(0x00);
set_tris_b(0x20);
int8 player1,player2,num1,num2,out1,out2;
output_a(46);
output_b(46);
delay_ms(3000);
output_a(255);
output_b(255);
while(!input(PIN_B5));
while(player1 == player2)
{
while(!input(PIN_B5));
while(input(PIN_B5))
{
player1 = rand() % 6 + 1;
}
out1 = decoder(player1);
output_a(out1);
while(input(PIN_B5));
while(!input(PIN_B5));
while(input(PIN_B5))
{
player2 = rand() % 6 + 1;
}
out2 = decoder(player2);
output_b(out1);
if(player1==player2)
{
player1=0;
player2=0;
}
}
while(input(PIN_B5))
while(TRUE)
{
while(!input(PIN_B5));
while(input(PIN_B5))
{
num1 = rand() % 6 + 1;
num2 = rand() % 6 + 1;
}
while(input(PIN_B5));
out1 = decoder(num1);
out2 = decoder(num2);
output_a(out1);
output_b(out2);
}
}
|
if matters here is my header source:
Code: |
#include <16F628A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#USE FAST_IO(A)
#USE FAST_IO(B)
#use delay(internal=4MHz,restart_wdt)
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Fri Dec 19, 2014 3:02 am |
|
|
Your documentation, is foul.
I was taught years ago, that code should be rejected, unless it was possible to read it. Like a book.
What current limiting resistors are you using on the LED's?. One thing that Proteus will miss, is the PIC being overloaded.....
Have you tested your display more simply (just counting for example).
What pull up are you using on the switch?. (again Proteus's inputs don't behave as real ones do).
Have you got hardware debouncing on the switch?. You need it.
Only part of the code re-written
Code: |
#include <new123.h> //processor definitions
#include <stdlib.h> //system standard library - has rand.
int8 led_segments[] = {
//fgxedcba - seems to be the pattern though I haven't checked
0b10011111, //zero
0b00000110, //one
0b01011011, //two
0b01001111, //three
0b11000110, //four
0b11001101, //five
0b11011101, //six
0b00000111, //seven
0b11011111, //eight
0b11001111, //nine
0b00000000, //not used
0b00000000, //not used
0b00000000, //not used
0b00000000, //not used
0b00000000, //not used
0b11010001 //'F'
};
#define BUTTON PIN_B5
#define PRESSED (input(BUTTON))
//You seem to code as if the input is high when the button is pressed
//is this right?. Normally buttons are 'pull down', not 'pull up'.
void main()
{
int8 player1=0,player2=0,num1,num2;
//always initialise all variables _before_ code. This is required in some C's
//Remember the contents of a variable are _not_ guaranteed unless you
//specify it.
setup_oscillator(OSC_4MHZ);
set_tris_a(0x00);
set_tris_b(0x20);
//everything as output, except BUTTON
output_a(~led_segments[0xF]); //'F' segments are low for on
output_b(~led_segments[0xF]);
delay_ms(3000);
output_a(~led_segments[0]); //'0'
output_b(~led_segments[0]);
//while (!PRESSED)
// ; //no point in this, since it waits in the loop...
while (player1 == player2) //Not guaranteed to be true on a chip
//unless you specify the value when initialising the variables...
{
while (!PRESSED) //wait for button
;
while (PRESSED)
{
player1 = rand() % 6 + 1;
} //loop while button is pressed to get a good random result.
output_a(~led_segments[player1]);
//when you get here, the button will be not pressed. It is almost
//impossible for it to have gone on again (unless you have a bounce
//problem - look at hardware debouncing.
while(!PRESSED)
;
while(PRESSED)
{
player2 = rand() % 6 + 1;
}
output_a(~led_segments[player2]);
if (player1==player2)
{
player1=0;
player2=0; //what is the point of this?. The value won't be displayed
//till you have gone round the loop again, and if the values are equal,
//you will loop.
}
} //exit 'while' if player values are different
//stopping here
|
My guesses would be that either you are overloading the PIC (look at both the individual pin drive, and the _total_ drive allowed), or are seeing switch bounce. If the latter, you need to either look at a hardware or software solution to this. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Fri Dec 19, 2014 6:22 am |
|
|
wow.. Mr T has done it again !!! I got lost' trying to read the code BUT saw something else buried in the code ...
Generally speaking you should NOT enable the WDT. Unless you handle it properly the PIC might not perform as expected. With 'simple' programs like this( maybe 90% of code presented here), the WDT is not needed.
Now enabling the PUT ( Power Up Timer) should be done. It allows the PIC to 'get organised' before he 'real code' is executed.
hth
jay |
|
|
Somor
Joined: 18 Dec 2014 Posts: 12
|
|
Posted: Fri Dec 19, 2014 7:05 am |
|
|
Ttelmah, thank you for the code you wrote, i will try it later, cause i have to go out. I do not use any resistors to led indicator, because it's consumption is big enough, with two resistors 330 ohms on the anode pins i just make digits darker.
temtronic, i posted the code of my .h file where all the fuses are set and WDT is OFF. The PUT is ON by default.
Also before wrote that macros and make the code more complex. I made with same scheme with same function - decoder(int decode) counter from 99 to 00 then goes back 99. And it worked perfect.
Maybe i really overload it somehow, because when i touch the chip sometimes i sense its warm/very warm but not hot. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Fri Dec 19, 2014 8:21 am |
|
|
Without any resistors, you are overloading the PIC. You don't want resistors on the anode pins. Doing this will make the display get dimmer the more segments are on. The maximum the PIC is rated to deliver is 25mA/pin. The LED's probably have a forward voltage of about 2.1v. The output of the PIC will go up to about 4.2v. You need a resistor of about 100R, in each line from the PIC, to allow the chip to actually work. Without this operation of the chip will be unreliable. Currently the only reason the LED's are not being destroyed is the internal protection in the PIC....
You need to finish the code, I've only done the first half. |
|
|
Somor
Joined: 18 Dec 2014 Posts: 12
|
|
Posted: Sat Dec 20, 2014 6:05 am |
|
|
Yes, of course i will finish it. And thank you again. Well maybe the missing resistors is the problem, because i tried your code just to see will it process the code correct, so i have to put my input pin on ground, else the FF don't go off, when i put the pin to ground after FF displays 00 then if i un-attach the pin from ground it then generates one number and if i put it back on ground or 5V or ground then 5 v or ground and unattach it nothing happens, so the Player 2 doesn't have any number. Well, i will try with 100 ohm resistors, by the way the PUT is auto enable even if it is not described in fuses. It is OFF when i write #FUSE NOPUT.
So about fuses i am doing everything correct.
I will try with 100-200 ohms resistors and will write again. |
|
|
Somor
Joined: 18 Dec 2014 Posts: 12
|
|
Posted: Sun Dec 21, 2014 5:52 am |
|
|
Sorry for the double post, but i want to be sure you will read it.
So i put 150 ohms resistor on the pic outputs and everything works, even with my suggested code.
Thank you a lot guys, i even asked in microchip's forum, but you gave me the solution! |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|