Вот решил прикрутить комповую клаву к контроллеру.
Вот весь код (пока только печатает сканкоды на 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 разные коды.
Кто-нибудь может помочь?
Спасибо.
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда