реклама на сайте
подробности

 
 
> AVR и AT клавиатура, Читается белиберда
hd44780
сообщение Mar 3 2008, 11:35
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Вот решил прикрутить комповую клаву к контроллеру.

Вот весь код (пока только печатает сканкоды на LCD):
Компилятор -CvAVR

Код
/*
Chip type           : ATmega32
Clock frequency     : 16,000000 MHz
*/

#include <mega32.h>
#include <delay.h>
#include <stdio.h>

#include "hd44780lib.h"
//#include "scancodes.h"

#define LED1    PORTD.4
#define LED2    PORTD.5
#define LED3    PORTD.6
//#define LED4    PORTD.7  

//#define BUTTON1 PINC.0
//#define BUTTON2 PINC.1
//#define BUTTON3 PINC.2

// Keyboard data
#define KBD_DATA        PINC.3

// переменные
volatile u32 ms = 0;        // миллисекунды
volatile u08 hour = 0, min = 0, sec = 0;

////////////////////////
// Клавиатура

#define KEYB_DATA_PIN   PINC.3
#define BUFF_SIZE 64

u08 edge, bitcount;                // 0 = neg.  1 = pos.

u08 kb_buffer[BUFF_SIZE];
u08 *inpt, *outpt;
u08 buffcnt;

void init_kb ( void );
void decode ( u08 sc );
void put_kbbuff ( u08 c );
u08 kb_getchar ( void );
int isKbBufferEmpty ( void );

////////////////////////

// инициализация CPU
void cpuInit ( void );

// External Interrupt 0 service routine
// Прерывание клавиатуры ()
interrupt [EXT_INT0] void ext_int0_isr(void)
{
// Place your code here
static u08 data;                // Holds the received scan code

if (!edge)                                // Routine entered at falling edge
{
  if(bitcount < 11 && bitcount > 2)    // Bit 3 to 10 is data. Parity bit,
  {                                    // start and stop bits are ignored.
   data = (data >> 1);

   if( KBD_DATA )
    data = data | 0x80;            // Store a '1'
  } // if

  MCUCR = 0x03;                         // ISC01..00 = 11 - INT0 by rising edge
  edge = 1;    
} // if
else
{ // Routine entered at rising edge
  MCUCR = 0x02;                            // Set interrupt on falling edge
  edge = 0;

  if ( --bitcount == 0 )
  { // All bits received
   decode ( data );
   bitcount = 11;
  } // if
} // else
} // ext_int0_isr

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr( void)
{
// Reinitialize Timer 0 value
TCNT0 = 0x06;

// Place your code here
ms ++;              

if ( ms % 1000 == 0 )
{ // прошла секунда
  sec ++;
        
  if ( sec == 59 )
  { // прошла минута
   sec = 0;
   min ++;
            
   if ( min == 59 )
   { // прошел час
    min = 0;
    hour ++;
                
    if ( hour == 23 )
     hour = 0;
   } // if
  } // if
} // if
} // timer0_ovf_isr

// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
// Place your code here
} // timer2_ovf_isr

void main(void)
{
// Declare your local variables here
char *m1 = "Тест AT клавиатуры";
char sBuf [ 25 ];
u08 kbCode;

// инициализация CPU
cpuInit ( );

// инициализация LCD
lcdInit ( );

lcdPutsXY ( 0, 0, m1 );  
delay_ms ( 500 );

LED1 = 1;
delay_ms ( 250 );
LED1 = 0;
delay_ms ( 250 );
LED2 = 1;
delay_ms ( 250 );
LED2 = 0;
delay_ms ( 250 );
LED3 = 1;
delay_ms ( 250 );
LED3 = 0;
delay_ms ( 250 );
// LED4 = 1;
// delay_ms ( 250 );
// LED4 = 0;
// delay_ms ( 250 );
      
init_kb ( );        // Initialize keyboard reception

while ( 1 )
{
  sprintf ( sBuf, "%02d:%02d:%02d", hour, min, sec );
  lcdPutsXY ( 0, 1, sBuf );    
  
  if ( isKbBufferEmpty () == 0 )
  { // буфер не пуст
   kbCode = kb_getchar ( );
   sprintf ( sBuf, "%d", kbCode );
   lcdPutsXY ( 0, 2, sBuf );        
  } // if

} // while
} // main

// инициализация CPU
void cpuInit ( void )
{
// Input/Output Ports initialization
// Port A initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTA=0x00;
DDRA=0xFF;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=Out Func1=Out Func0=In
// State7=T State6=T State5=T State4=T State3=0 State2=0 State1=0 State0=T
PORTB = 0x00;
DDRB = 0x0E;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=P State2=P State1=P State0=P      
// PC3 - KBD_DATA
PORTC = 0x0F;
DDRC = 0x00;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In
// State7=0 State6=0 State5=0 State4=0 State3=P State2=P State1=T State0=T
PORTD = 0x0C;
DDRD = 0xF0;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 250,000 kHz
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0 = 0x03;
TCNT0 = 0x06;
OCR0 = 0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x05;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
// INT1: Off
// INT2: Off
GICR |= 0x40;                  // Enable INT0
MCUCR = 0x02;                  // ICS01..00 = 10 - INT0 by falling edge
MCUCSR = 0x00;                 //
GIFR = 0x40;                   // Reset INT0 flag

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK = 0x41;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR = 0x80;
SFIOR = 0x00;

// Global enable interrupts
#asm ( "sei" );
} // cpuInit

void init_kb ( void )
{
inpt =  kb_buffer;                        // Initialize buffer
outpt = kb_buffer;
buffcnt = 0;

// MCUCR = 2;                                // INT0 interrupt on falling edge
edge = 0;                                // 0 = falling edge  1 = rising edge
bitcount = 11;
} // init_kb

void decode ( u08 sc )
{
put_kbbuff ( sc );
} // decode

void put_kbbuff ( u08 c )
{
if (buffcnt<BUFF_SIZE)                        // If buffer not full
{
  *inpt = c;                                // Put character into buffer
  inpt++;                                    // Increment pointer

  buffcnt++;

  if (inpt >= kb_buffer + BUFF_SIZE)        // Pointer wrapping
   inpt = kb_buffer;
} // if
} // put_kbbuff

u08 kb_getchar ( void )
{
u08 kb_byte;

while(buffcnt == 0);                        // Wait for data

kb_byte = *outpt;                                // Get byte
outpt++;                                    // Increment pointer

if (outpt >= kb_buffer + BUFF_SIZE)            // Pointer wrapping
  outpt = kb_buffer;
    
buffcnt--;                                    // Decrement buffer count

return kb_byte;
} // kb_getchar

int isKbBufferEmpty ( void )
{
if ( buffcnt == 0 )
  return 1;             // буфер пуст

return 0;
} // isKbBufferEmpty


Основа кода - AppNote AVR313.
KBD_CLK - INT0,
KBD_DATA - PC3.
Проблема в том, что печатает на экране белиберду. Даже нажимая одну и ту же клавишу, я вижу на LCD разные коды.
Кто-нибудь может помочь?

Спасибо.


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 19:39
Рейтинг@Mail.ru


Страница сгенерированна за 0.01356 секунд с 7
ELECTRONIX ©2004-2016