Добавил:
Eatmore
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:отчеты по лабораторным работам / драйвер клавиатуры / my / SRC / index
.c#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;
}
}
}
}