Dictionary en-ru на микроконтроллере с 512 kb. Controller AVR Atmega 8515 но подойдет практически любой из симейства Atmega. Atmega8, Atmega16, Atmega32,...
Микроконтроллер имеет 4 (A,B,C,D) порта по 8 входов/выходов и 1 порт E 3 Входа/Выхода

Реально нам потребуется: 7-keypad, 4-MMC, 8+5 Display, 2-Uart. Причем Uart как таковой нужен только для отладки. Если использовать только keypad COM Port не требуется. Можно уложится в трехпортовый контроллер! 8x3. 24 входа/выхода. Если я правильно сосчитал;-)



Для клавиатуры используется 7 выводов порта C. Порт может быть выбран произвольно, главное правильно сконфигурировать выводы. Программа написана с расчетом на использование 16 кнопок, но реально используется только 12. Работает опрос кнопок следующим образом. Прерывание от таймера происходит каждый 1024 такт процессора. FCPU/1024. Вызывается ISR (TIMER0_OVF_vect)

TCCR0 |= (1<<CS02)|(1<<CS00);
TIMSK |= (1<<TOIE0); // setup timer 0 to interrupt on overflow 
TCNT0 = 0;

Затем на ряд из клавиш (1,4,7,*) подается 0. На остальные ряды 1.

PORTC = ~(0x10 << i);

Также 1 подается на входы( младшие 4-е разряда) что бы подтянуть внутренним сопротивлением эти входы к 1.

Затем проверяем вход колонок. Какая из них прижата к 0.

if (bit_is_clear(PINC, j))

затем пауза, для проверки дребезга контактов и повторный запрос вывода порта.

Таким же образом опрашивается все ряды из клавиш (2,5,8,0) и (3,6,9,#)

Отдельно стоит отметить, что входные порты находятся в состоянии PullUp.

Вход PullUp — вход с подтяжкой.

При DDRxy=0 и PORTxy=1 замыкается ключ подтяжки и к линии подключается резистор в 100кОм, что моментально приводит неподключенную никуда линию в состояние лог1. Цель подтяжки очевидна — недопустить хаотичного изменения состояния на входе под действием наводок. Но если на входе появится логический ноль (замыкание линии на землю кнопкой или другим микроконтроллером/микросхемой), то слабый 100кОмный резистор не сможет удерживать напряжение на линии на уровне лог1 и на входе будет нуль. Хорошая статья с картинками по теме есть на AVR. Учебный курс. Устройство и работа портов ввода-вывода Вот одна из них;-)



Для обмена с COM port используется выводы PD0(RXD), PD1(TDX). Выбирается меньшая погрешность скорости соединения с COM Port компьютера.



Например при частоте FCPU 4Mhz UBRR=12 U2X=1 получаем скорость 38400 при погрешности 0.2%. Рекомендуемое отклонение <5%.



Для получения FCPU 4Mhz FUSE Bits конфигурируются следующим образом. В PonyProg2000 "снимаются" две галочки справа.(Инверсия - выбраный бит 0, не выбраный 1)



UCSRB = (1<<RXEN)|(1<<TXEN);
unsigned short bauddiv = ((F_CPU+(UART_BAUD_RATE*8L))/(UART_BAUD_RATE*16L)-1);
UBRRL = bauddiv;
UCSRA = (1<<U2X);

bauddiv - вычесленное значение в зависимости от FCPU. Используется для того что бы не править код при изменении частоты микроконтроллера. Только не забывайте изменять F_CPU в Makefile если меняете частоту. Если потребуется жесткая оптимизация по размеру кода, конечно замените на константы.

Словарь предварительно обрабатывается. Длина ключевых слов делается 64 Byte см. dict_key_64.txt. Перевода 128 Byte см. dict_art_128.txt. Взяты свободно распространяемый словарь Сократ. Основная проблема была в том, что контроллер имеет только 512 Byte памяти, а читать (и писать) с MMC требуется блоками фиксированной длинны 512 byte. Пришлось выкручиваться и работать окнами.

  for(j=0, buff_idx=0; j<MMC_BLOCK_SIZE; j++)
	{
		if( in_block_offs <= j && (in_block_offs + DATA_BLOCK_SIZE) > j )
		{
			buff[buff_idx] = spi_receive();
			buff_idx++;
		}
		else
			spi_receive();
	}

Поэтому есть ничего не выполняющие вызовы spi_receive();

Отдельно был написан загрузчик файлов словаря на MMC. Использовалось прерывание от UART порта и механизм буферизирования. Без него не удавалось правильно положить файлы на MMC, поскольку сама запись данных на MMC занимает какое то время. Было просто не успеть забрать байт из порта, после записи блока

volatile unsigned char r_index=0, s_index=0;

UART_INTERRUPT_HANDLER(SIG_UART_RECV)
{
	buffer[r_index] = UDR;
	if( ++r_index >= DATA_BLOCK_SIZE )
	{
		r_index = 0;
	}
}
...
while( 1 )
	{
		if( r_index != s_index )
		{
			spi_transmit(buffer[s_index]);
			s_index++;
			if( s_index >= DATA_BLOCK_SIZE )
			{
				s_index = 0;
				break;
			}
		}
	}

Не забывайте про volatile. Иначе компилятор, с ключом оптимизации -s просто не включит ваши переменные!

Сохраненный словарь на диске выглядит следующим образом



Ниже идут словарные статьи с переводом



#define SOCRAT_DICT_KEYWORD_BLOCK_OFFS		1L
#define SOCRAT_DICT_KEYWORD_BLOCK_SIZE		7042L
#define SOCRAT_DICT_ARTICLE_BLOCK_OFFS		7101L
#define SOCRAT_DICT_ARTICLE_BLOCK_SIZE		14084L

Все смещения в блоках по 512 байт


В качестве дисплея используется WG12864 на KS0108 Chip. К сожалению на моей модели не было возможности включить подсветку. Поскольку для подсветки требовалось напряжение 110 V 400 Hz. Но имеются модели со светолиодной подсветкой

Схема выводов и конфигурирование выводов приведены ниже.



// Ports
#define LCD_CMD_PORT		PORTD		// Command Output Register
#define LCD_CMD_DIR			DDRD		// Data Direction Register for Command Port

#define LCD_DATA_IN			PINA		// Data Input Register
#define LCD_DATA_OUT		PORTA		// Data Output Register
#define LCD_DATA_DIR		DDRA		// Data Direction Register for Data Port

// Command Port Bits
#define D_I					0x07		// D/I Bit Number
#define R_W					0x06		// R/W Bit Number
#define EN					0x05		// EN Bit Number
#define CSEL1				0x04		// CS1 Bit Number
#define CSEL2				0x03		// CS2 Bit Number

В проекте использована библиотека от Fabian Maximilian Thiele. Она позволяет рисовать точки, линии и выводить текст. В интернете есть много решений подобного рода Например:
KS0108 Graphics LCD library
Controlling graphical 128x64 LCD based on KS0108


По работе с MMC можно прочитать здесь SD/MMC карта памяти и микроконтроллер AVR (часть 1) код для работы с MMC был взят с этого сайта.

Ниже приведено конфигурирование выводов порта микроконтроллера для работы с MMC

/*
#define DI   0
#define DO   1
#define CLK  2 
#define CS   3
*/
#define DI   3
#define DO   0
#define CLK  2 
#define CS   1

Во время пайки были перепутаны выводы DI, DO, CS. Что бы не перепаивать, выводы просто переконфигурированы. (См. закоментированый код выше.)



Схема программатора. Подключается к LPT порту.


Дополнительные утилиты:

Конвертор словаря Сократ Алгоритм поиска в словаре VC6

Документация на компоненты:

WG12864A-WGE-T Atmega8515

Прошивка словаря и загрузчика:

AvrDiction AvrDictLoader

Motherboard


Keyboard


Display

Core

Mix


Hosted by uCoz