//набросок программы "Кальклятор".
#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);
}
}
НАЗАД ДАЛЕЕ