Nu har jag problem med att få två knappar att fungera. Till och börja med här är förutsättningarna:
uC: PIC16F886
Kompilator: MikroC
Koppling: Porta: 7 segments display segment A-DP
Portb: RB0 en fototransistor via en vanlig transistor för att invertera signalen.
RB1 utgång till blixt via optokopplare
RB2-3 Knappar för att styra displayen
Portc:RC0-3 transistorer för att välja rätt display
Knapparna är kopplade enl. mellan RB2 och +5v 100k motstånd och mellan RB2 och GND är knappen. Likaså för RB3
config:
Kod: Markera allt
__CONFIG _CONFIG1, _DEBUG_OFF & _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF &
_CPD_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
__CONFIG _CONFIG2, _WRT_OFF & _BOR21V
Kod: Markera allt
/************************************************************/
// //
// Flash delay timer V1.0 //
// Developer: Karl-Fredrik Johansson //
// //
// Decription: //
// A delay timer for a flash for taking highspeed photos. //
// Using a IR-diode and a phototransistor to sense when //
// a BB-gun is fired. A PIC16F886 processes this //
// information and triggers a flash after a deired time. //
// To display and choose the delay time I'm using a //
// 4*7 segments display and two buttons. //
// //
// Copyright Karl-Fredrik Johansson //
// Mail: kalf89@gmail.com //
/************************************************************/
//Functions
void display(void);
//variables
unsigned short shifter;
unsigned short digit;
unsigned short porta_index;
unsigned int number;
unsigned short porta_array[4];
unsigned short digit1 = 0;
unsigned short digit2 = 0;
unsigned short digit3 = 0;
unsigned short digit4 = 0;
unsigned short last_digit1 = 0;
unsigned short last_digit2 = 0;
unsigned short last_digit3 = 0;
unsigned short last_digit4 = 0;
unsigned short cnt_value = 0;
unsigned short real_cnt_value = 0;
unsigned short oldstate = 0;
//Mask values to display the correct values on the display
unsigned short mask(unsigned short num) {
switch (num) {
case 0 : return 0x3F;
case 1 : return 0x06;
case 2 : return 0x5B;
case 3 : return 0x4F;
case 4 : return 0x66;
case 5 : return 0x6D;
case 6 : return 0x7D;
case 7 : return 0x07;
case 8 : return 0x7F;
case 9 : return 0x6F;
default: return 0x40;
}
}
//interrupt
void interrupt()
{
if(INTCON.T0IF == 1) //If TMR0 generats interrupt
{
PORTC = 0; //Turns the segments off
PORTA = porta_array[porta_index]; //Assaign the correct value of the correct digit
PORTC = shifter; //Turn on the correct digit
//Shift display
shifter <<= 1;
if (shifter > 8u) shifter = 1;
//move on to next display
porta_index++;
if (porta_index > 3u) porta_index = 0; // turn on 1st, turn off 2nd 7seg.
TMR0 = 0; // reset TIMER0 value
INTCON = 0x20; // Clear T0IF
}
}
//Display function
void display(void)
{
//Display 0000 for a start value
porta_array[0] = mask(0);
porta_array[1] = mask(0);
porta_array[2] = mask(0);
porta_array[3] = mask(0);
while(1)
{
//Display the current digits
porta_array[0] = mask(digit1);
porta_array[1] = mask(digit2);
porta_array[2] = mask(digit3);
porta_array[3] = mask(digit4);
//Get digits from value
real_cnt_value = cnt_value;
digit1 = cnt_value % 10;
cnt_value = cnt_value / 10;
digit2 = cnt_value % 10;
cnt_value = cnt_value / 10;
digit3 = cnt_value % 10;
cnt_value = cnt_value / 10;
digit4 = cnt_value % 10;
cnt_value = real_cnt_value;
//increase value on display
if (button(&PORTB, 2, 50, 1)) oldstate = 1;
if (button(&PORTB, 2, 50, 0))
{
cnt_value++;
if (cnt_value > 9999) cnt_value = 0;
oldstate = 0;
}
//decrease value on display
if (button(&PORTB, 3, 50, 1)) oldstate = 1;
if (button(&PORTB, 3, 50, 0))
{
cnt_value--;
if (cnt_value > 9999) cnt_value = 9999;
oldstate = 0;
}
}
}
//Main
void main()
{
//input output assignment
TRISA = 0b00000000; //7-segment display Segment A-DP
TRISB = 0b00001101; //RB0 sensor input RB1 Flash trigger output RB2-3 Input button RB4-7 N-A
TRISC = 0b00000000; //RC0-3 Digit selection RC4-7 N-A
//Timer and other settings
OPTION_REG = 0b10000000; //PORTB Pull-ups are dissabled
INTCON = 0b10100000; //enable GIE and T0IE
//Clearing and setting regs, bits and varibles
PORTA = 0; //Clears PORTA
PORTB = 0; //Clears PORTB
PORTC = 0; //Clears PORTC
TMR0 = 0; //Clears TMR0
shifter = 1;
porta_index = 0;
//Write to display Startup sequence
porta_array[0] = 0x40;
porta_array[1] = 0x40;
porta_array[2] = 0x40;
porta_array[3] = 0x40;
delay_ms(1000); // Create a delay to fake a loading sequence
display(); //Go to display()
}
Nu till det resultatet jag får:Button
Prototype unsigned short Button(unsigned short *port, unsigned short pin, unsigned short time, unsigned short active_state);
Returns Returns 0 or 255.
Description Function eliminates the influence of contact flickering upon pressing a button (debouncing).
Parameter port specifies the location of the button; parameter pin is the pin number on designated port and goes from 0..7; parameter time is a debounce period in milliseconds; parameter active_state can be either 0 or 1, and it determines if the button is active upon logical zero or logical one.
Requires Button pin must be configured as input.
Example Example reads RB0, to which the button is connected; on transition from 1 to 0 (release of button), PORTD is inverted:
do {
if (Button(&PORTB, 0, 1, 1)) oldstate = 1;
if (oldstate && Button(&PORTB, 0, 1, 0)) {
PORTD = ~PORTD;
oldstate = 0;
}
} while(1);
Displayen lyser upp med: ---- detta lyser i 1s som den skall. Sedan visas 0000. Också detta som planerat. Men det händer ingenting när jag trycker på knapparna. Det förväntade resultatet skall vara att displayen räknar upp respektive ner beroende på vilken knapp som trycks ner.
Fråga
Vad är fel? Jag kan inte hitta något direkt fel med koden eller inkopplingen. Några idéer på hur jag skall fortsätta i min felsökning?
MVH
Kalf