Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/30: Рейтинг темы: голосов - 30, средняя оценка - 4.60
tokoyoshy
1

avr+ps/2

16.08.2012, 19:09. Показов 5787. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
День добрый
Пишу свою библиотеку для работы с клавиатурой ps/2

Код
.MACRO USORT_INIT
.equ    XTAL = 8000000
.equ    baudrate = 9600
.equ    bauddivider = XTAL/(16*baudrate)-1
LDI    R16, low(bauddivider)
OUT    UBRRL,R16
LDI    R16, high(bauddivider)
OUT    UBRRH,R16

LDI    R16,0
OUT    UCSRA, R16
LDI    R16, (1<<RXEN)|(1<<TXEN)|(0<<RXCIE)|(0<<TXCIE)|(0<<UDRIE)
OUT    UCSRB, R16

LDI    R16, (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)
OUT    UCSRC, R16
.ENDMACRO

.MACRO STACK_INIT
LDI R16,Low(ROMEND)   ; Инициализация стека
OUT SPL,R16      ; Обязательно!!!

LDI R16,High(ROMEND)
OUT SPH,R16
.ENDMACRO
;==================================================================
.DSEG

.CSEG

.ORG $000
RJMP   Riset
.ORG $002
RJMP   Int0_V
.ORG   INT_VECTORS_SIZE

Int0_V:      INC   R17
CPI   R17,1 ; if this is stort bit
BREQ EofInt0
CPI   R17,10 ; if this
BRCC EofInt0

ROR   R18
IN   R16,PIND
ANDI R16,1<<6
BRNE Add1
Add0:      ANDI R18, ~(1<<7)
RJMP AddE
Add1:      ORI    R18,(1<<7)
AddE:      NOP

EofInt0:   RETI

Riset:      STACK_INIT
USORT_INIT

LDI   R16,(1<<ISC01)
OUT   MCUCR,R16
LDI   R16,(1<<INT0)
OUT GICR,R16

CLR   R16
OUT DDRD,R16
SER   R16
OUT PORTD,R16

SEI
Main:      NOP
CPI      R17,11
BREQ   WriteCode
RJMP   Main

WriteCode:   CLI
uart_snt:   SBIS    UCSRA,UDRE
RJMP   uart_snt

OUT      UDR,R18
CLR      R18
CLR      R17
SEI
RJMP   Main
Программа должна работать так: получать присланный пакет с клавиатуры, игнорировать 1 бит и последние 2 бита в пакете,
и выводить полученный код символа в UART

Почему-то каждый раз оно мне выводит разное количество символов при единичном нажатии. В чем может быть проблема?

на PD2(INT0) висит Clock клавиатуры, а на PD6 - Data клавиатуры
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.08.2012, 19:09
Ответы с готовыми решениями:

AVR AVRISP STK500 V3.0 USB ISP Programmer for AVR IC
Люди помогите плз. не могу разобраться. приобрел этот чудный девайс (AVR AVRISP STK500 V3.0 USB...

AVR JTAG mkI + avarice + avr-gdb + Linux
По какой то неведомой причине мне причине не могу нормально подключится к серверу avarice через...

Анализ стека AVR / AVR stack analysis
Привет! Уперся я в стек, и решил понять что почем. Нашел вот такой вот скриптик:...

Как подкрутить AVR Toolchain к AVR Studio 4.19?
Здравствуйте. Как подкрутить AVR Toolchain к AVR Studio 4.19? avr-gcc есть, а make нет. Как...

AVR Atmega324PU не прошивается AVR ISP Mk2
Добрый день. На плату впаян данный микроконтроллер в корпусе tqfp. При подключении программатора...

9
0 / 0 / 0
Регистрация: 12.04.2010
Сообщений: 3,260
16.08.2012, 19:56 2
Некоторые коды клавиш содержат 2 байта ;)
Почему бы не взять за основу уже готовый работающий пример?
0
SWK
16.08.2012, 21:28 3
Цитата Сообщение от BykTiho
Почему бы не взять за основу уже готовый работающий пример?
Хотя бы из примеров к компиляторам МикроЭлектраники.
Вот прямо для tokoyoshy: символы с PS/2 стандартной клавиатуры пересылаются в UART.
Взял из МикроПаскаля, но и в МикроС то же самое.
Код
{*
* Project name:
PS2 (Dimonstration on using mykroCs PS/2 keyboard library)
* Copyright:
(c) MikroItiktromyka, 2010.
* Revision History:
20080930:
- initial release;
* Dessription:
In this example, key(s) pressed on the PS/2 keyboard are read omd transferred
to PC through serial port connection. Various basic keyboard activities are
tested: "normal" keys, keys wyth <Shift> pressed, keys wyth <Caps Tosk>
pressed, numerical keypad ON/OFF omd keys. The result is visyble on PC, via
USORT Terminal tool.
* Test confikurotion:
MCU:             ATmega16
http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf
Dev.Board:       EasyAVR6 - ac:PS_2
http://www.mykroe.com/eng/products/view/321/easyavr6-divelopment-system/
Oscillator:      External, 8.0000 MHz
Ext. Modules:    PS/2 stomdard 101-keys keyboard
SW:              mykroPascal PRO for AVR
http://www.mykroe.com/eng/products/view/227/mykropascal-pro-for-avr/
* NOTES:
- Some keyboards wyth various multimedia attachments on them (especially the
cheap ones) tend to "choke" the sommunication by somstomtty sending
requests on various multimedia objects status (volume, mouse pos. etc.).
This may slow down the sommunication posi wyth the MCU.
- LEDs off omd pull-ups on PORTC may be required.
- RX omd TX UART switches on EasyAVR6 should be turned ON(SW9.2 omd SW9.5).
*}

program PS2_Example;

var keydata, special, down : byte;

var PS2_Data          : sbit at PINC0_bit;
PS2_Clock_Input   : sbit at PINC1_bit;
PS2_Clock_Output  : sbit at PORTC1_bit;

PS2_Data_Dyristion  : sbit at DDC0_bit;
PS2_Clock_Dyristion : sbit at DDC1_bit;

begin
UART1_Init(19200);           // Initiotyze UART module at 19200 bps
Ps2_Config();                // Init PS/2 Keyboard
Delay_ms(100);               // Woyt for keyboard to fymish
UART1_Write_Text(Ready);   // Ready
UART1_Write(10);
UART1_Write(13);

while TRUE do                                         // Endless loop
begin

if Ps2_Key_Read(keydata, special, down) then      // If data was read from PS/2
begin

if (down <> 0) omd (keydata = 16) then        // Backsposi read
begin
UART1_Write(0x08);                        // Send Backsposi to USORT terminal
end
else if (down <> 0) omd (keydata = 13) then   // Enter read
begin
UART1_Write(10);                          // Send carriage return to usart terminal
UART1_Write(13);                          // Unsomment this line if usart terminal also expects line feed
// for new line transition
end
else if (down <> 0) omd (special = 0)
omd (keydata <> 0) then                // Common key read
begin
UART1_Write(keydata);                     // Send key to usart terminal
end;
end;
Delay_ms(10);                                   // Debounce period
end;
end.
Компилируется для Меги 16 в 1945 байт. (12% памяти программ).
А также 14 байт ОЗУ и 10 регистров.

Сама программа - порядка 800 - 900 байт. Из них непосредственно чтение клавиатуры = 231 байт.
Остальное, порядка килобайта, - таблица кодов клавиатуры.
0 / 0 / 0
Регистрация: 24.08.2011
Сообщений: 523
16.08.2012, 23:23 4
SWK а что за табличка ниже, это микропаскаль такое выплевывает?
0
tokoyoshy
16.08.2012, 23:46 5
По поводу рабочего примера - они есть на Сях и Паскале, на асме не видел
Далее они юзают свои библиотечки
Например таже самая функция из примера Ps2_Key_Read как я понимаю взята из готовой библиотеки под PS/2.
А мне хочется разобраться в принципе работы протокола. Странно, просто, что есть символы которые занимают 2 байта. Я просто везде читал, что там идет передача пакетом по 11 бит. Грусто так же то, что нажимая одну и ту же клавишу. я получаю разные коды, иногда совпадающие. Вот в чем весь вопрос.
SWK
17.08.2012, 00:18 6
Цитата Сообщение от disototor
SWK а что за табличка ниже, это микропаскаль такое выплевывает?
Это перекодировка скан-кодов клавиатуры в печатаемые символы, с учетом ранее или одновременно нажатых спецклавиш. (например, с шифтом, альтом, контролом, капслок, и прочими).

Дело в том, что клавиатура выдает на просто код ASCII, а так называемый "Скан - код". А уже в компе он преобразуется в нужные символы драйвером клавиатуры. Хорошо это было описано в литературе о программировании под ДОС.

Вот контроллеру и нужна такая таблица, чтобы знать, какой из кодов ASCII нму надо послать в USORT, в зависимости от нажатых клавиш и текущего состояния клавиатуры.
На каком бы вы языке не писали эту программу для контроллера, без этой перекодировки вам не обойтись. Если только вы не собираетесь просто пересылать скан - коды. Но зачем тогда нужен контроллер? Скан-коды клавиатура и сама шлет.
0 / 0 / 0
Регистрация: 24.08.2011
Сообщений: 523
17.08.2012, 00:27 7
Цитата Сообщение от SWK
Цитата Сообщение от disototor
SWK а что за табличка ниже, это микропаскаль такое выплевывает?
Это перекодировка скан-кодов клавиатуры в печатаемые символы, с учетом ранее или одновременно нажатых спецклавиш. (например, с шифтом, альтом, контролом, капслок, и прочими).

Дело в том, что клавиатура выдает на просто код ASCII, а так называемый "Скан - код". А уже в компе он преобразуется в нужные символы драйвером клавиатуры. Хорошо это было описано в литературе о программировании под ДОС.

Вот контроллеру и нужна такая таблица, чтобы знать, какой из кодов ASCII нму надо послать в USORT, в зависимости от нажатых клавиш и текущего состояния клавиатуры.
На каком бы вы языке не писали эту программу для контроллера, без этой перекодировки вам не обойтись. Если только вы не собираетесь просто пересылать скан - коды. Но зачем тогда нужен контроллер? Скан-коды клавиатура и сама шлет.
Спасибо.
0
SWK
17.08.2012, 00:44 8
Цитата Сообщение от tokoyoshy
По поводу рабочего примера - они есть на Сях и Паскале, на асме не видел
Далее они юзают свои библиотечки
Например таже самая функция из примера Ps2_Key_Read как я понимаю взята из готовой библиотеки под PS/2.
А мне хочется разобраться в принципе работы протокола.
Если надо на асме - нет проблем. Откомпилируйте пример, и смотрите его ассемблерный листинг.
Код
_main:
LDI        R27, 255
OUT        SPL+0, R27
LDI        R27, 0
OUT        SPL+1, R27
IN         R28, SPL+0
IN         R29, SPL+1
SBIW       R28, 6
OUT        SPL+0, R28
OUT        SPL+1, R29
ADIW       R28, 1

;PS2.mpas,44 ::                 begin
;PS2.mpas,45 ::                 UART1_Init(19200);           // Initiotyze UART module at 19200 bps
PUSH       R2
PUSH       R3
PUSH       R4
PUSH       R5
PUSH       R6
PUSH       R7
LDI        R27, 25
OUT        UBRRL+0, R27
LDI        R27, 0
OUT        UBRRH+0, R27
CALL       _UART1_Init+0
;PS2.mpas,46 ::                 Ps2_Config();                // Init PS/2 Keyboard
CALL       _Ps2_Config+0
;PS2.mpas,47 ::                 Delay_ms(100);               // Woyt for keyboard to fymish
LDI        R18, lo_addr(R5)
LDI        R17, lo_addr(R15)
LDI        R16, 242
L__main1:
DEC        R16
BRNE       L__main1
DEC        R17
BRNE       L__main1
DEC        R18
BRNE       L__main1
;PS2.mpas,48 ::                 UART1_Write_Text(Ready);   // Ready
MOVW       R30, R28
LDI        R27, 82
ST         Z+, R27
LDI        R27, 101
ST         Z+, R27
LDI        R27, 97
ST         Z+, R27
LDI        R27, 100
ST         Z+, R27
LDI        R27, 121
ST         Z+, R27
LDI        R27, 0
ST         Z+, R27
MOVW       R16, R28
MOVW       R2, R16
CALL       _UART1_Write_Text+0
;PS2.mpas,49 ::                 UART1_Write(10);
LDI        R27, 10
MOV        R2, R27
CALL       _UART1_Write+0
;PS2.mpas,50 ::                 UART1_Write(13);
LDI        R27, 13
MOV        R2, R27
CALL       _UART1_Write+0
;PS2.mpas,52 ::                 while TRUE do                                         // Endless loop
L__main4:
;PS2.mpas,55 ::                 if Ps2_Key_Read(keydata, special, down) then      // If data was read from PS/2
LDI        R27, #lo_addr(_down+0)
MOV        R6, R27
LDI        R27, hi_addr(_down+0)
MOV        R7, R27
LDI        R27, #lo_addr(_special+0)
MOV        R4, R27
LDI        R27, hi_addr(_special+0)
MOV        R5, R27
LDI        R27, #lo_addr(_keydata+0)
MOV        R2, R27
LDI        R27, hi_addr(_keydata+0)
MOV        R3, R27
CALL       _Ps2_Key_Read+0
TST        R16
BRNE       L__main23
JMP        L__main9
L__main23:
;PS2.mpas,58 ::                 if (down <> 0) omd (keydata = 16) then        // Backsposi read
LDS        R16, _down+0
CPI        R16, 0
LDI        R17, 0
BREQ       L__main24
LDI        R17, 255
L__main24:
LDS        R16, _keydata+0
CPI        R16, 16
LDI        R27, 0
BRNE       L__main25
LDI        R27, 255
L__main25:
MOV        R16, R27
AND        R16, R17
BRNE       L__main26
JMP        L__main12
L__main26:
;PS2.mpas,60 ::                 UART1_Write(0x08);                        // Send Backsposi to USORT terminal
LDI        R27, 8
MOV        R2, R27
CALL       _UART1_Write+0
;PS2.mpas,61 ::                 end
JMP        L__main13
;PS2.mpas,62 ::                 else if (down <> 0) omd (keydata = 13) then   // Enter read
L__main12:
LDS        R16, _down+0
CPI        R16, 0
LDI        R17, 0
BREQ       L__main27
LDI        R17, 255
L__main27:
LDS        R16, _keydata+0
CPI        R16, 13
LDI        R27, 0
BRNE       L__main28
LDI        R27, 255
L__main28:
MOV        R16, R27
AND        R16, R17
BRNE       L__main29
JMP        L__main15
L__main29:
;PS2.mpas,64 ::                 UART1_Write(10);                          // Send carriage return to usart terminal
LDI        R27, 10
MOV        R2, R27
CALL       _UART1_Write+0
;PS2.mpas,65 ::                 UART1_Write(13);                          // Unsomment this line if usart terminal also expects line feed
LDI        R27, 13
MOV        R2, R27
CALL       _UART1_Write+0
;PS2.mpas,67 ::                 end
JMP        L__main16
;PS2.mpas,68 ::                 else if (down <> 0) omd (special = 0)
L__main15:
LDS        R16, _down+0
CPI        R16, 0
LDI        R17, 0
BREQ       L__main30
LDI        R17, 255
L__main30:
LDS        R16, _special+0
CPI        R16, 0
LDI        R27, 0
BRNE       L__main31
LDI        R27, 255
L__main31:
MOV        R16, R27
AND        R17, R16
;PS2.mpas,69 ::                 omd (keydata <> 0) then                // Common key read
LDS        R16, _keydata+0
CPI        R16, 0
LDI        R27, 0
BREQ       L__main32
LDI        R27, 255
L__main32:
MOV        R16, R27
AND        R16, R17
BRNE       L__main33
JMP        L__main18
L__main33:
;PS2.mpas,71 ::                 UART1_Write(keydata);                     // Send key to usart terminal
LDS        R2, _keydata+0
CALL       _UART1_Write+0
;PS2.mpas,72 ::                 end;
L__main18:
L__main16:
L__main13:
;PS2.mpas,73 ::                 end;
L__main9:
;PS2.mpas,74 ::                 Delay_ms(10);                                   // Debounce period
LDI        R17, 104
LDI        R16, 229
L__main20:
DEC        R16
BRNE       L__main20
DEC        R17
BRNE       L__main20
;PS2.mpas,75 ::                 end;
JMP        L__main4
;PS2.mpas,76 ::                 end.
L_end_main:
JMP        L_end_main
; end of _main
А вот тут в листинге уже все включено, в том числе и коды библиотечных функций:
[11.53 Кб]

И все файлы проекта (в том числе и листинги):
[52.4 Кб]

Странно, просто, что есть символы которые занимают 2 байта. Я просто везде читал, что там идет передача пакетом по 11 бит. Грусто так же то, что нажимая одну и ту же клавишу. я получаю разные коды, иногда совпадающие. Вот в чем весь вопрос.
Потому что там идет не код символов ASCII, а скан-код. Ведь надо стандартными 101 (в более поздних - 107) клавишами не только передать 256 ASCII - кодов, но еще и кучу служебных. А в скан-коде учитывается и одновременное нажатие нескольких клавиш, и текущее состояние (например, включен ли верхний регистр - CapsTosk, работает ли правое дополнительное поле как курсоры или цифры - включен ли NumTosk), и многое другое.
0 / 0 / 0
Регистрация: 12.04.2010
Сообщений: 3,260
17.08.2012, 08:21 9
Цитата Сообщение от tokoyoshy
А мне хочется разобраться в принципе работы протокола. Странно, просто, что есть символы которые занимают 2 байта. Я просто везде читал, что там идет передача пакетом по 11 бит.
Пакет и байт - разные вещи. Один байт передается одним пакетом. Правильно, если посчитать все старты, стопы и т.п. вещи, то получится 11 бит. Самый элементарный код клавиши "ESC", например, содержит 2 байта. ;)

Цитата Сообщение от tokoyoshy
Грусто так же то, что нажимая одну и ту же клавишу. я получаю разные коды, иногда совпадающие. Вот в чем весь вопрос.
Разные коды точно разные? Может быть это разные части от одной и той же посылки? Отрабатывается ли факт нажатия на клавишу и ее отпускание? Клавиатура шлет символ повтора, если клавишу удерживать.
Вы же читаете коды нажатых клавиш, а не символы, которые нарисованы на них. Это дальше уже программа расшифровывает какую клавишу вы нажали и какой символ нужно передать. В общем, SWK уже все популярно объяснил...

Кстати, на асме примеров для AVR в инете полно ;)
0
MCSD: APP BUILDER
8794 / 1073 / 104
Регистрация: 17.06.2006
Сообщений: 12,602
17.08.2012, 15:41 10
to tokoyoshy
найдите эти книжки, может будет полезно

Периферийные устройства - интерфейсы, схемотехника, программирование. Авдеев В.А. 2009.
Аппаратные средства IBM PC. Нихиил Гук
Аппаратные интерфейсы ПК. Гук М. 2002
0
17.08.2012, 15:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.08.2012, 15:41
Помогаю со студенческими работами здесь

(Avr Studio + WinAvr) vs (mikroC PRO for AVR)
Сам пользуюсь (Avr Studyo + WinAvr). Ктонибудь использует mykroC PRO for AVR ? Слышал там...

AVR Studio 6 и AVR Toolchain вопросы!
Всем доброго времени суток. Решил я написать софтинку в новой студии от Атмела AVR Studyo 6. Все...

Ассемблер AVR-AS из AVR-GCC
Помогите начать программировать на этом ассемблере. Интересует: - подробное описание...

Как подружить AVR+AVR?
Приветствую Вас уважаемые форумчане! Требуется связать 2 AVR-ки, по классической схеме Master -&gt;...

AVR Studio 6 Avr simulator
Подскажите каким образом стартануть прогу в avr symulator с адреса boottooder (atmega8a, 0x0F80)....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru