Dostal jsem takovehle zadani:
Kódový zámek
V paměti EEPROM mikropočítače bude uložen osmimístný kód. Kód pro otevření se zadává z klávesnice (klávesy 0 – 9). Klávesa „*“ slouží na vymazání zadání. Po zadání všech 8 číslic se zjistí, je-li zadané číslo správné, nebo špatné. Pokud je špatné, vypíše se na displeji s obvodem M5450 slovo „bad“. Pokud je heslo správné, vypíše se „Good“. Pokud je nyní stisknuta klávesa „#“, Rozsvítí se na displeji desetinné tečky a přejde se do režimu nastavení kódu. To je možno zrušit klávesou „*“, v takovém případě tečky zhasnou a přejde se do normálního režimu, tedy do zadávání hesla (počáteční stav). Pokud je zadáno všech 8 číslic, data se zapíšou do EEPROM v mikropočítači. Program musí využívat SLEEP režim (v době mezi stisky kláves usnout). Program musí využívat také přerušení od klávesnice (jinak usne a už se neprobudí…).
Kontrola:
Program musí po stisknutí klávesy „1“ zobrazit „Good“ 2 po stisknutí klávesy „2“ zobrazit „bad“ na displeji.
Ale jsem debil na programovani, tak potrebuju pomoct. Pro nekoho kdo programuje to, myslim, nebude nic sloziteho. Diky za pomoc.
Fórum › C / C++
Program v C pro PIC18F452
A v čom je problém ?
>Mozna bych nastavil zobrazovani tech cisel na displeji, pripadne zobrazeni GOOD a BAD ...
S toho usudzujem, že vieš čítať s klávesnice, zobrazovať znaky na display(i), nič viac na splnenie tej úlohy nepotrebuješ, tak v čom je problém ?
To ani ne :( ja umim jenom nektere veci ale pak to dat dohromady je problem.
Treba tohle zmaknu:
const unsigned char znaky[]={0b11000000, //0
0b11111001, //1
0b10100100, //2
0b10110000, //3
0b10011001, //4
0b10010010, //5
0b10000010, //6
0b11111000, //7
0b10000000, //8
0b10011000, //9
0b10001000, //A
0b10000000, //B
0b11000110, //C
0b11000000, //D
0b10000110, //E
0b10001110}; //F
Nastaveni jak se maji ty jdenotlive znaky zobrazovat.
Pripadne jejich zobrazeni:
void main()
{
TRISD=0;
ADCON1=0x07;
TRISA&=0b11000011;
T1CON=0b0000001;
INTCON=0b11000000;
IPEN=0;
TMR1IE=1;
display[0]=znaky[0];
display[1]=znaky[12];
display[2]=znaky[0];
display[3]=znaky[11];
while(1);
}
Ale to je tak vsechno.
V tom prípade vám do poručujem, aby ste sa zastavili v knižnici vo vašom okolí (alebo v kníhkupectve) a zohnali si potrebnú literatúru. Čo sa týka používania klávesnice a zobrazovaní na display(i), je táto problematika riešená skoro v každej literatúre.
Problémom je práve ten fakt, že riešenie ktoré požadujete je velice silno závislé na použitých obvodoch, a dokonca aj na použitom zapojení týchto obvodov. Napríklad program realizujúci čítanie z maticovej klávesnice a „zápis“ na osemsegmentový display pre procesory rodiny atmel avr by mohol vyzerať nejako takto:
// using keyboard example (see avr_keyboard_sch.png in doc directory)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#define LEDDISP_PORT PORTA
#define LEDDISP_DDR DDRA
#define KEYBOARD_ROWS 4
#define KEYBOARD_COLUMNS 3
#define KEYBOARD_PORT PORTB
#define KEYBOARD_DDR DDRB
#define KEYBOARD_PIN PINB
#define KEYBOARD_CODE_NKP -1 // no key pressed
#define TC_INIT_VALUE 158 // 10x per socond
#define TC_PRESCALER_1024 ((1<<CS02)|(1<<CS00))
//! display number on led display
/*!
\param [in] number displayed number from 0 to 9
\param [in] disp display number you can use (0 or 1) */
void dispNumberOnLedDisp(uint8_t number, uint8_t disp);
//! get character from keyboard
void getc(int8_t * c);
//! scan keyboard row
/*!
\param [in] row keyboard row you can read
\return returns readed row code */
int8_t scanKeyboardRow(uint8_t row);
//! find first occurence of val
/*!
\param[in] first the first element address
\param[in] last behind the last element address
\param[in] val value to looking for
\return returns val position, if val isn't found
returns -1 */
int8_t find(uint8_t * first, uint8_t * last, uint8_t val);
#define keyboardCodesLen 12
const uint8_t keyboardCodes[keyboardCodesLen] = {
0x5e, // 0
0x37, // 1
0x57, // 2
0x67, // 3
0x3b, // 4
0x5b, // 5
0x6b, // 6
0x3d, // 7
0x5d, // 8
0x6d, // 9
0x3e, // -
0x6e // infinite
};
int8_t tKeyCode = KEYBOARD_CODE_NKP; // pressed keyboard code
ISR(TIMER0_OVF_vect)
{
TCNT0 = TC_INIT_VALUE;
static int8_t keyCodeOld = KEYBOARD_CODE_NKP;
static int8_t dispNum = 0;
int8_t keyCode = KEYBOARD_CODE_NKP;
getc(&keyCode);
// display key only if it changed
if (keyCode != keyCodeOld)
{
keyCodeOld = keyCode;
if (keyCode != KEYBOARD_CODE_NKP)
{
dispNumberOnLedDisp(keyCode, dispNum);
if (dispNum)
dispNum = 0;
else
++dispNum;
}
}
}
void main()
{
sei(); // global interrupt enable
TIMSK |= (1 << TOIE0); // timer overflow enable
TCNT0 = TC_INIT_VALUE;
TCCR0 |= TC_PRESCALER_1024; // set prescaler value
// clear led display
dispNumberOnLedDisp(0xF, 0);
dispNumberOnLedDisp(0xF, 1);
while (1)
continue;
}
void dispNumberOnLedDisp(uint8_t number, uint8_t disp)
{
LEDDISP_DDR = 0xFF; // set led display pins as output
switch (disp)
{
case 0: {
uint8_t tmp = LEDDISP_PORT;
tmp &= 0xF0;
number &= 0x0F;
tmp |= number;
LEDDISP_PORT = tmp;
break;
}
case 1: {
uint8_t tmp = LEDDISP_PORT;
tmp &= 0x0F;
tmp |= number << 4;
LEDDISP_PORT = tmp;
break;
}
}
}
void getc(int8_t * c)
{
int8_t i, keyCode = 0;
// scan all keyboard rows
for (i = 0; i < KEYBOARD_ROWS; ++i)
{
// read the same keyboard row until there were two same results
int8_t tmpKeyCode;
do
{
tmpKeyCode = scanKeyboardRow(i);
// wait a moment
uint8_t n;
for (n = 0; n < 25; ++n)
continue;
keyCode = scanKeyboardRow(i); // read again
}
while (keyCode != tmpKeyCode);
// there were pressed button in this row
if ((keyCode >> KEYBOARD_ROWS) < ((1 << KEYBOARD_COLUMNS)-1))
{
*c = find(keyboardCodes, keyboardCodes + keyboardCodesLen,
keyCode);
return;
}
}
*c = KEYBOARD_CODE_NKP; // no key pressed
}
int8_t scanKeyboardRow(uint8_t row)
{
uint8_t keyCode = 0x01;
keyCode = keyCode << row;
KEYBOARD_DDR = keyCode; // set keyboard pins direction
keyCode = ~keyCode;
KEYBOARD_PORT = keyCode; // set keyboard pins value
keyCode = KEYBOARD_PIN; // read keyboard code
return (keyCode & 0x7F);
}
int8_t find(uint8_t * first, uint8_t * last, uint8_t val)
{
uint8_t pos;
for (pos = 0; first != last; first++, pos++)
{
if (*first == val)
return pos;
}
return -1;
}
Diky za pomoc, ale vubec z toho nejsem chytry :smile10: . Spis bych to vzal uplne od zacatku.
Pokusim se udelat nejaky "vyvojovy diagram". Tak jestli to dobre chapu tak ja bych ten kod nejdriv precetl z te pameti, pak z klavesnice nacetl ty cisla a porovnal a pak to vyhodnotil. A na konec tam dal jeste to GOOD a BAD. Je tak spravne?
* No najprv by si mal zvládnuť ten display, tj. zobrazovať na ňom ľubovoľné znaky, na ľubovoľnej pozícii. V mojom príklade to je funkcia void dispNumberOnLedDisp(uint8_t number, uint8_t disp).
* Potom musíš zvládnuť tú klávesnicu, tj. „prečítať“ znej stlačenú klávesu a pomocou funkcii, ktoré si si napísal v predchádzajúcom bode hodnotu tej klávesy zobrazíš na display(i). V mojom príklade túto činnosť vykonáva funkcia void getc(int8_t * c).
* Dokiaľ nemáš zvládnuté oba predchádzajúce kroky je zbytočné pokúšať sa ten program spraviť naraz, teda ako celok. Pokiaľ zvládneš oba predchádzajúce body, tak potom je to už jednoduché, ale o tom potom.
Ted jsme delali neco s klavesnici, ale nevim jak ulozit ty znaky z klavesnice do nejake pameti, abych to mohl porovnat s tim kodem v te pameti:
#include <pic18.h>
#define RADEK1 TRISA2
#define RADEK2 TRISA3
#define RADEK3 TRISA4
#define RADEK4 TRISA5
#define SLOUPEC1 RB7
#define SLOUPEC2 RB6
#define SLOUPEC3 RB5
#define Tlacitko RB4
#define LED PORTD
unsigned char CASZAKMITU,STARAKLAV,KLAVESA;
bit BYLAZMENAKLAV;
void interrupt PRER(void)
{
unsigned char i;
if(TMR1IF)
{
TMR1H+=0xEE;
TMR1L+=0x00;
TMR1IF=0;
if (CASZAKMITU) CASZAKMITU--;
}
if(RBIF)
{
i=PORTB;
CASZAKMITU=0x50;
RBIF=0;
BYLAZMENAKLAV=1;
}
}
unsigned char READKEY(void)
{
unsigned char KLAV;
LATA&=0b11000011;
RADEK1=0;
RADEK2=1;
RADEK3=1;
RADEK4=1;
KLAV=0x80; while(KLAV--);
KLAV=PORTB&0b11100000;
switch(KLAV)
{
case 0b01100000:{TRISA&=0b11000011; return '1';}
case 0b10100000:{TRISA&=0b11000011; return '2';}
case 0b11000000:{TRISA&=0b11000011; return '3';}
}
RADEK1=1;
RADEK2=0;
RADEK3=1;
RADEK4=1;
KLAV=0x80; while(KLAV--);
KLAV=PORTB&0b11100000;
switch(KLAV)
{
case 0b01100000:{TRISA&=0b11000011; return '4';}
case 0b10100000:{TRISA&=0b11000011; return '5';}
case 0b11000000:{TRISA&=0b11000011; return '6';}
}
RADEK1=1;
RADEK2=1;
RADEK3=0;
RADEK4=1;
KLAV=0x80; while(KLAV--);
KLAV=PORTB&0b11100000;
switch(KLAV)
{
case 0b01100000:{TRISA&=0b11000011; return '7';}
case 0b10100000:{TRISA&=0b11000011; return '8';}
case 0b11000000:{TRISA&=0b11000011; return '9';}
}
RADEK1=1;
RADEK2=1;
RADEK3=1;
RADEK4=0;
KLAV=0x80;while(KLAV--);
KLAV=PORTB&0b11100000;
switch(KLAV)
{
case 0b01100000:{TRISA&=0b11000011; return '*';}
case 0b10100000:{TRISA&=0b11000011; return '0';}
case 0b11000000:{TRISA&=0b11000011; return '#';}
}
TRISA&=0b11000011;
return 0;
}
void main()
{
ADCON1=0x47; // Vypne analog
TRISE0=0; // REO vystupni
TRISD=0x00; // PORTD vystupni
RE0=1; // Zapnout 74HC573
PORTD=0;
T1CON=0b00000001;
INTCON=0b11001000;
RBPU=0;
PIE1=0b00000001;
BYLAZMENAKLAV=0;
LATA&=0b11000011;
TRISA=0b11000011;
while (1)
{
if ((BYLAZMENAKLAV)&&(!CASZAKMITU))
{
BYLAZMENAKLAV=0;
KLAVESA=READKEY();
if(STARAKLAV!=KLAVESA)
{
STARAKLAV=KLAVESA;
LED=KLAVESA;
}
}
}
}
No napríklad takto:
unsigned char keys[4];
for (int i = 0; i < 4; ++i)
keys[i]=READKEY();
To bola „len“ ukážka všeobecného postupu, veľkosť pola si môžete ľubovoľne meniť. A čo konkrétne sa vám na tých troch riadkoch zdá JAVA(ovské)?
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Program na téma Sériová komunikace v C pro PIC18F452 — založil Mik
Program pro java — založil Luke
Program pro 8051 — založil Wexter
Program pro prvočísla — založil Daniel
Dávka pro program — založil Kiki Lopez
Moderátoři diskuze