//набросок программы "Кальклятор".
#include<p18cxxx.h>
#include<delays.h>
#pragma config OSC=RC
#pragma config WDT=OFF
#pragma config LVP=OFF
#pragma config BOR=OFF
#pragma config MCLRE=OFF
#define LCD     PORTB
#define SDATA   PORTBbits.RB6
#define CLOCK   PORTBbits.RB5
#define E       PORTBbits.RB4
#define KEYPORT PORTA
#define DELAY   15
rom far char lookupKey[]=
{
    7,4,1,-0x30,
    8,5,2,0,
    9,6,3,0x0d,
    -0x01,-0x06,-0x03,-0x05
};
char buffer[5];
long result;
char count;
long value1;
long value2;
char pmdu;
char position1;
char position2;
char ic;
#pragma code
extern long ltoBCD(long Value,char* BCD);
//###########################################################
//преобразует BCD число в 32-х разрядное
void BCD2long(unsigned char num)
{
    count++;
    if((num>=0)&&(num<=9)){
        if(count==1){
            result=num;
            return;
        }
        else if(count==2){
            result*=10;
            result+=num;
            return;
        }
        else if(count==3){
            result*=10;
            result+=num;
            return;
        }
        else if(count==4){
            result*=10;
            result+=num;
            return;
        }
        else if(count==5){
            result*=10;
            result+=num;
            return;
        }
        else if(count==6){
            result*=10;
            result+=num;
            return;
        }
        else if(count==7){
            result*=10;
            result+=num;
            return;
        }
        else if(count==8){
            result*=10;
            result+=num;
            return;
        }
        else if(count==9){
            result*=10;
            result+=num;
            return;
        }
        else if(count==10){
            result*=10;
            result+=num;
            return;
        }
    }
    else{
    count=0;
    }
}
//######################################################
//преобразует BCD число в ASCII код
unsigned char key2asc(unsigned char keyNum)
{
    return keyNum+='0';
}
void Switch(char sw)
{
    do{
        while((KEYPORT&sw)!=sw);
        Delay1KTCYx(DELAY);
    }while((KEYPORT&sw)!=sw);
    do{
        while((KEYPORT&sw)==sw);
        Delay1KTCYx(DELAY);
    }while((KEYPORT&sw)==sw);
}
unsigned char Key(void)
{
    #define MASK 0x0F
    #define ROWS 4
    char a;
    char keyCode;
    PORTB=keyCode=0;
    Switch(MASK);
    PORTB=0x0e;
    while((PORTA&MASK)==MASK)
    {
        PORTB=(PORTB<<1)|1;
        keyCode+=ROWS;
    }
    for(a=1;a!=0;a<<=1)
    {
        if((PORTA&a)==0){
            break;
        }
        keyCode++;
    }
    BCD2long(lookupKey[keyCode]);
    return key2asc(lookupKey[keyCode]);
}
//#########################################################
//для вывода на LCD
void clockShiftReg(void)
{
    CLOCK=1;
    CLOCK=0;
}
void clearShiftReg(void)
{
    char a;
    SDATA=0;
    for(a=0;a<6;a++)
        clockShiftReg();
}
void sendNibble(char nib,char RS)
{
    
    char a;
    clearShiftReg();
    SDATA=RS;
    clockShiftReg();
    for(a=0;a<4;a++)
    {
        SDATA=nib&1;
        clockShiftReg();
        nib>>=1;
    }
    E=1;
    E=0;
}
void SendLCDdata(char data,char RS)
{
    sendNibble(data>>4,RS);
    sendNibble(data,RS);
}
void InitLCD(void)
{
    Delay1KTCYx(20);
    sendNibble(3,0);
    Delay1KTCYx(4);
    sendNibble(3,0);
    Delay1KTCYx(12);
    SendLCDdata(0x32,0);
    SendLCDdata(0x28,0);
    SendLCDdata(0x08,0);
    SendLCDdata(0x01,0);  
    Delay1KTCYx(2);
    SendLCDdata(0x06,0);
    SendLCDdata(0x0c,0);
    clearShiftReg();
}
void clrLCD(void)
{
    SendLCDdata(0x01,0);
    Delay1KTCYx(4);
}
//################################################################
//выводим 32-разрядное число на экран
void sendLCDlong(long l)
{
    char a;
    char b=0;
    char adr=0xc1;
    ltoBCD(l,buffer);                  //возвращает в 5 байтов 32-х разрядное число-long
    for(a=0;a<5;a++)                   //ищет ноли,которые не нужно выводить,возвращает в b число цифр BCD
    {
        if(((buffer[a]>>4)&0x0f)==0){
            b++;
            if((buffer[a]&0x0f)==0)
                b++;
        }
        if(((buffer[a]>>4)&0x0f)!=0)
            break;
        if((buffer[a]&0x0f)!=0)
            break;
    }
    if(b==0){
        return;
    }
    for(a=b;a<10;a++)
    {
        b=a/2;
        if(a%2){
            SendLCDdata(adr++,0);
            SendLCDdata((buffer[b]&0x0f)+0x30,1);
        }
        else{
            SendLCDdata(adr++,0);
            SendLCDdata(((buffer[b]>>4)&0x0f)+0x30,1);
        }
    
    }
}
//###############################################################
//выводит на LCD числа и проверяет кнопки
void DisplayNum(unsigned char key,char i)
{
    if((key>=0x30)&&(key<=0x39)||(key==0x2b)||(key==0x2a)||(key==0x2f)||(key==0x2d))
    {
        if(i<16){
            SendLCDdata(position1+i,0);
            SendLCDdata(key,1);
        }
        else if(i>=16&&i<32){
            SendLCDdata(0xc0+i-16,0);
            SendLCDdata(key,1);
        }
        if(key==0x2b)
        {
            value1=result;
            pmdu=1;
        }
        else if(key==0x2a)
        {
            value1=result;
            pmdu=2;
        }
        else if(key==0x2f)
        {
            value1=result;
            pmdu=3;
        }
        else if(key==0x2d)
        {
            value1=result;
            pmdu=4;
        }
    }
    else if(key==0x3d)
    {
        SendLCDdata(0xc0,0);
        SendLCDdata('=',1);
        value2=result;
        switch(pmdu)
        {
            case 0:
               break;
            case 1:
               result=value1+value2;
               break;
            case 2:
               result=value1*value2;
               break;
            case 3:
               result=value1/value2;
               break;
            case 4:
               result=value1-value2;
               break;
        }
        sendLCDlong(result);
        value1=0;
        value2=0;
        pmdu=0;
        if(i<16)
           position1--;
        else if(i>=16&&i<32)
           position2--;
    }
    else if(key==0)
    {
        clrLCD();
        SendLCDdata(0x80,0);
        SendLCDdata('0',1);
        SendLCDdata(0xc0,0);
        SendLCDdata('=',1);
        SendLCDdata(0xc1,0);
        SendLCDdata('0',1);
        value1=0;
        value2=0;
        pmdu=0;
        result=0;
        sendLCDlong(result);
        count=0;
        position1=0x80;
        position2=0xc0;
        ic=-1;
    }
}

void main(void)
{
    ADCON1=0x7f;
    TRISB=0;
    TRISA=0x0f;
    PORTB=0;
    PORTA=0;
    result=0;
    count=0;
    value1=0;
    value2=0;
    pmdu=0;
    position1=0x80;
    position2=0xc0;
    InitLCD();
    SendLCDdata(0x80,0);
    SendLCDdata('0',1);
    while(1)
    {
        
        for(ic=0;ic<32;ic++)
            DisplayNum(Key(),ic);
    }
}



НАЗАД                                                                                                                                         ДАЛЕЕ