#include "aduc812.h" 
#define MAXBASE 8

#define FBUFSize 16
#define FBUFSS FBUFSize-1
struct FIFOb{ //описываем структуру буфера последовательного канала 
	unsigned char buf[FBUFSize];
	char start;//начало буфера
	char end; //конечная позиция
};

struct FIFOb wFIFO, rFIFO, dFIFO, uFIFO;
unsigned char key;
unsigned short itime;

void WriteMax (unsigned char xdata *regnum, unsigned char val) //функция записи в регистр ПЛИС
{
	unsigned char oldDPP = DPP; 
	DPP = MAXBASE; 
	*regnum = val;
	DPP = oldDPP;
}

void WriteLED(unsigned char value) //функция "зажигания" сетодиодов
{
	WriteMax(7, value); 
}

unsigned char ReadMax (unsigned char xdata *regnum) //функция чтения из ПЛИС
 {
	unsigned char oldDPP = DPP; 
	unsigned char val1;
	DPP  = MAXBASE;
	val1 = *regnum;
	DPP  = oldDPP;
	return val1;
}


unsigned char GetDIP() //читает положение Dip-переключателей
{
	unsigned char val = ReadMax(2);
	return ~val;
}


void SetVector(unsigned char xdata * Address, void * Vector)// Функция, устанавливающая 
							//вектор прерывания Vector по адресу Address
{
	unsigned char xdata * TmpVector;
	*Address   = 0x02;
	TmpVector  = (unsigned char xdata *)(Address+1);
	*TmpVector = (unsigned char) ((unsigned short)Vector >> 8);
	++TmpVector;
	*TmpVector = (unsigned char) Vector;
}

void SendChar(char sch)//функция отправки символа
{
	TI = 0; // Обнуление флага завершения посылки
	SBUF = sch; // Инициация посылки символа sch
	while( !TI ); // Ожидание завершения посылки
}

void SendString(const char* str) //функция отпраки строки
{
	unsigned char i=0;
	while(i<80){
		if (str[i]=='\0') break;
		SendChar(str[i++]);
	}
}

unsigned char RcvChar(void) //получение символа
{
	char res;
	while(!RI);//когда RI=1 - вызов обработчика прерываний
	res = SBUF; //начинаем процесс передачи
	RI = 0;
	return res;
}

void PushF(struct FIFOb* a, unsigned char c) //запись в буфер FIFO
{
#define Ae (a->end)
#define As (a->start)
	a->buf[Ae] = c; //записываем символ в конец буфера
	if (++Ae > FBUFSS) Ae=0; //контроль переполнения буфера, если буфер заполнен - начинать сначала
	if (Ae == As){
		if(++As > FBUFSS) Ae = 0;
	}
}

unsigned char PopF(struct FIFOb* a) //извлечение из буфера FIFO
{
#define Ae (a->end)
#define As (a->start)
	unsigned char c;
	if (Ae == As) return 0;
	c = a->buf[As];
	if(++As > FBUFSS) As=0;
	return c;
}

void APIWrite(unsigned char s) 
{
	EA = 0;      // Запрещение прерываний
	ES = 0;
	PushF(&wFIFO, s); //запись в буфер символа
	EA = 1;      // Разрешение прерываний
	ES = 1;
}

void APIUChar(unsigned char res)
{
	unsigned char rr[3], c;
	char i;
	for(i=0; i<3; i++){
		c = res % 10;
		c |= 0x30;
		rr[i]=c;
		res /= 10;
		if(res == 0) break;
	}
	for(;i>=0; i--) APIWrite(rr[i]);
}

void APIString(const unsigned char* str) //функция записи строки в буфер
{
	unsigned char i=0;
	while(i<80){
		if (str[i]=='\0') break;
		APIWrite(str[i++]);
	}
}

unsigned char APIKeyUp() 
{
	return PopF(&uFIFO);
}

unsigned char APIKeyDown()
{
	return PopF(&dFIFO);
}

unsigned char APIRead(void) //чтение из последовательного канала
{
	unsigned char c;
	EA = 0;      // Запрещение прерываний
	ES = 0;
	c = PopF(&rFIFO);
	EA = 1;      // Разрешение прерываний
	ES = 1;
	return c;
}

void Echo(unsigned char c)
{
	unsigned char i;
	if((c<0x80) || (c>0xEF)) return;
	if((c>0xAF) && (c<0xE0)) return;
	if(c>0x9F) c -= 0x20;
	if(c>0x9f) c -= 0x30;
	
	SendChar(c);
	if(c>0x8F)
		{ c+=0x50; }
	else
		{ c+=0x20; }
	for(i=0; i<5; i++){
		if(++c>0xEF) break;
		if((c>0xAF) && (c<0xE0)) c+=0x30;
		SendChar(c);
	}
	SendChar('\n');
	SendChar('\r');
	return;
}

void DoMath(void)
{
#define ERR_MSG "\n\rIOError\n\r\0"
	unsigned char c=0, s1=0, s2=0, i, f=0;
	for(i=0; i<2; i++){
		c  = 0;
		while(!c) c = APIKeyDown(); //ожидаем нажатия клавиши
		if(c == 'B'){
			APIWrite('-');
			f=10;
			break;
		}
		APIWrite(c);
		if((c<0x30) || (c>0x39)){
			f=1;
			break;
		}
		s1 *= 10;
		s1 += c & 0x0F;
	}
	if(f==1) {APIString(ERR_MSG); return;}
	if(f!=10){
		c=0;
		while(!c) c = APIKeyDown();
		if(c != 'B') {APIWrite(c); APIString(ERR_MSG); return;}
		APIWrite('-');
	}
	
	f=0;
	for(i=0; i<2; i++){
		c   = 0;
		while(!c) c = APIKeyDown();
		if(c == '#'){
			APIWrite('=');
			f=10;
			break;
		}
		APIWrite(c);
		if((c<0x30) || (c>0x39)){
			f=1;
			break;
		}
		s2 *= 10;
		s2 += c & 0x0F;
	}
	if(f==1) {APIString(ERR_MSG); return;}
	if(f!=10){
		c=0;
		while(!c) c = APIKeyDown();
		if(c != '#') {APIWrite(c); APIString(ERR_MSG); return;}
		APIWrite('=');
	}
	APIUChar(s1 - s2);
	
	//ERROR MESSAGE
	APIWrite('!');
	APIWrite('\n');
	APIWrite('\r');
}

void SIO_ISR( void ) __interrupt ( 4 ) //прерывание от последовательного канала
{
	unsigned char c;
	if(TI){
		c = PopF(&wFIFO);
		if(c){
			SBUF = c;
			TI=0;
		}
	}
	
	if(RI){
		PushF(&rFIFO, SBUF);
		RI=0;
	}
}

void InitUART(void)
{
	TH1   =   0xFD;   // Скорость 9600
    TMOD  = 0x21;   // Таймер 1 в режиме autoreload, а 0 16bit
    TCON  = 0x50;   // Запуск таймера 1 & 0
    SCON  = 0x50;   // 8 bit UART, разрешение приема
    PCON &= 0x7F;   // Отключение дублирования скорости, установленной в TH1
	TI = 1;

	EA    = 0;      // Запрещение прерываний
	wFIFO.start = wFIFO.end = rFIFO.start = rFIFO.end = 0;
	SetVector(0x2023, (void *) SIO_ISR); //устанавливаем вектор прерывайний в пользовательской таблице от UART
}

unsigned char Scan(unsigned char col_row)
{
	WriteMax(0, 0x01);
	if( ( ReadMax(0) & 0xF0 ) == 0xF0 ){
		switch (col_row){
		case 0xE0:
			return 0x31;
		case 0xD0:
			return 0x34;
		case 0xB0:
			return 0x37;
		case 0x70:
			return 0x2A;
		}
	}
	WriteMax(0, 0x02);
	if( ( ReadMax(0) & 0xF0 ) == 0xF0 ){
		switch (col_row){
		case 0xE0:
			return 0x32;
		case 0xD0:
			return 0x35;
		case 0xB0:
			return 0x38;
		case 0x70:
			return 0x30;
		}
	}
	WriteMax(0, 0x04);
	if( ( ReadMax(0) & 0xF0 ) == 0xF0 ){
		switch (col_row){
		case 0xE0:
			return 0x33;
		case 0xD0:
			return 0x36;
		case 0xB0:
			return 0x39;
		case 0x70:
			return 0x23;
		}
	}
	WriteMax(0, 0x08);
	if( ( ReadMax(0) & 0xF0 ) == 0xF0 ){
		switch (col_row){
		case 0xE0:
			return 0x41;
		case 0xD0:
			return 0x42;
		case 0xB0:
			return 0x43;
		case 0x70:
			return 0x44;
		}
	}
	return 0;
}

void T0_ISR(void) __interrupt ( 1 ) //действия, выполняемы обработчиком прерываний таймера 0
{
	static unsigned char regENA = ReadMax(4);
	static unsigned char key=0, KeyPressed=0;
	static unsigned char ktime=0;
	unsigned char col_row;
    TH0  = 0xDC; //100 per sec
	TL0  = 0x01;
	itime++;
	
#define KEY_PRESSED     1
#define KEY_UNPRESSED   0
#define KEY_REPTIME    100
	
	WriteMax(0,0x00);
	col_row = ReadMax(0);//читаем регистр клавы
	ktime++;
	
	if (col_row == 0xF0){
		if(ktime<3) return;
		if (key != 0){
			PushF(&uFIFO, key);
			key=0;
		}
		KeyPressed=0;
		ktime=0;
		return;
	}

	regENA ^= 0x1c;
	WriteMax(4, regENA);

	if( ktime > KEY_REPTIME){
		ktime=0;
		KeyPressed=0;
	}
	
	if (!KeyPressed){
		key = Scan(col_row); //сканируем столбцы соответствующей строки клавы
		PushF(&dFIFO, key); //записываем в буфер введенный символ
		KeyPressed=1;
		return;
	}

}

void main(void)
{
	unsigned char c;
	SetVector( 0x200B, (void *)T0_ISR ); // Установка вектора прерываний от таймер 0 в пользовательской таблице
	InitUART(); //инициализацию UART
	ET0=1;  EA=1; // Разрешение прерываний от таймера 0

	key=0;
	while(1)
	{
		
		if(GetDIP() == 128){ //если установлен соответствующий ДИП-переключатель
			while(1){ //выполняем вывод на экран соответствующего введенного символа
			c = APIKeyDown(); //читаем кнопку
				if(c){
					SendChar(c);
				}
				if(GetDIP() != 128) break;
			}
		}
		
		if(GetDIP() == 1){
			while(1){
				DoMath();
				if(GetDIP() != 1) break;
			}
		}
	}
}
Соседние файлы в папке SRC
  • #
    09.05.201447.44 Кб34index.asm
  • #
    09.05.20148.03 Кб35index.c
  • #
    09.05.2014114.94 Кб34index.lst
  • #
    09.05.201422.6 Кб34index.rel
  • #
    09.05.2014114.94 Кб34index.rst
  • #
    09.05.201443.89 Кб34index.sym
  • #
    09.05.20142.02 Кб35kb.c