Как всегда проще начать с самого простого, а именно с линий ввода-вывода. Умение работать с ними позволит нам помигать светодиодами и опросить состояние кнопки. И в качестве примера работа с ЖКИ индикатором от сотового телефона Нокиа 1100.
Согласно структурной схемы для управление режимами работы и ввода-вывода данных используются пять регистров, структура регистров объявлена в библиотечном файле:
Работать с ними очень просто достаточно объявить линию с выбранным режимом работы, например для управления зеленым светодиодом установленном на плате можно сделать вот так:
Я давно искал небольшой черное-белый индикатор от мобильника к контроллеру которого можно свободно припаять проводники и нашел его, это ЖКИ от Nokia 1100. Недорогой и можно свободно купить в любой мастерской сотовых или в магазине запчастей.
Шуршание по просторам интернета показало что контроллер у ЖКИ PCF8814, согласно документации вроде не такой уж и сложный, но вот почему-то в сети я нашел только один источник (точнее много, но все они указывали на один http://www.sunbizhosting.com/~spiral/1100/ ). В первоисточнике использовался PIC. Да и как-то не стильно написано ;) убрал лишнее, добавил нужное и вот, что вышло у меня:
/*
* File: lcd_nokia_1100.c
* Date: 17.01.2011
*/
#include "main.h"
const uint8_t lcd_nokia1100_decode [] =
{ '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'A' , 'B' , 'C' , 'D' , 'E' ,
'F' };
const uint8_t lcd_nokia1100_font_5x8 [ 96 ][ 5 ] =
{
{ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // (space)
{ 0x00 , 0x00 , 0x5F , 0x00 , 0x00 }, // !
{ 0x00 , 0x07 , 0x00 , 0x07 , 0x00 }, // "
{ 0x14 , 0x7F , 0x14 , 0x7F , 0x14 }, // #
{ 0x24 , 0x2A , 0x7F , 0x2A , 0x12 }, // $
{ 0x23 , 0x13 , 0x08 , 0x64 , 0x62 }, // %
{ 0x36 , 0x49 , 0x55 , 0x22 , 0x50 }, // &
{ 0x00 , 0x05 , 0x03 , 0x00 , 0x00 }, // '
{ 0x00 , 0x1C , 0x22 , 0x41 , 0x00 }, // (
{ 0x00 , 0x41 , 0x22 , 0x1C , 0x00 }, // )
{ 0x08 , 0x2A , 0x1C , 0x2A , 0x08 }, // *
{ 0x08 , 0x08 , 0x3E , 0x08 , 0x08 }, // +
{ 0x00 , 0x50 , 0x30 , 0x00 , 0x00 }, // ,
{ 0x08 , 0x08 , 0x08 , 0x08 , 0x08 }, // -
{ 0x00 , 0x30 , 0x30 , 0x00 , 0x00 }, // .
{ 0x20 , 0x10 , 0x08 , 0x04 , 0x02 }, // /
{ 0x3E , 0x51 , 0x49 , 0x45 , 0x3E }, // 0
{ 0x00 , 0x42 , 0x7F , 0x40 , 0x00 }, // 1
{ 0x42 , 0x61 , 0x51 , 0x49 , 0x46 }, // 2
{ 0x21 , 0x41 , 0x45 , 0x4B , 0x31 }, // 3
{ 0x18 , 0x14 , 0x12 , 0x7F , 0x10 }, // 4
{ 0x27 , 0x45 , 0x45 , 0x45 , 0x39 }, // 5
{ 0x3C , 0x4A , 0x49 , 0x49 , 0x30 }, // 6
{ 0x01 , 0x71 , 0x09 , 0x05 , 0x03 }, // 7
{ 0x36 , 0x49 , 0x49 , 0x49 , 0x36 }, // 8
{ 0x06 , 0x49 , 0x49 , 0x29 , 0x1E }, // 9
{ 0x00 , 0x36 , 0x36 , 0x00 , 0x00 }, // :
{ 0x00 , 0x56 , 0x36 , 0x00 , 0x00 }, // ;
{ 0x00 , 0x08 , 0x14 , 0x22 , 0x41 }, // >
{ 0x14 , 0x14 , 0x14 , 0x14 , 0x14 }, // =
{ 0x41 , 0x22 , 0x14 , 0x08 , 0x00 }, // >
{ 0x02 , 0x01 , 0x51 , 0x09 , 0x06 }, // ?
{ 0x32 , 0x49 , 0x79 , 0x41 , 0x3E }, // @
{ 0x7E , 0x11 , 0x11 , 0x11 , 0x7E }, // A
{ 0x7F , 0x49 , 0x49 , 0x49 , 0x36 }, // B
{ 0x3E , 0x41 , 0x41 , 0x41 , 0x22 }, // C
{ 0x7F , 0x41 , 0x41 , 0x22 , 0x1C }, // D
{ 0x7F , 0x49 , 0x49 , 0x49 , 0x41 }, // E
{ 0x7F , 0x09 , 0x09 , 0x01 , 0x01 }, // F
{ 0x3E , 0x41 , 0x41 , 0x51 , 0x32 }, // G
{ 0x7F , 0x08 , 0x08 , 0x08 , 0x7F }, // H
{ 0x00 , 0x41 , 0x7F , 0x41 , 0x00 }, // I
{ 0x20 , 0x40 , 0x41 , 0x3F , 0x01 }, // J
{ 0x7F , 0x08 , 0x14 , 0x22 , 0x41 }, // K
{ 0x7F , 0x40 , 0x40 , 0x40 , 0x40 }, // L
{ 0x7F , 0x02 , 0x04 , 0x02 , 0x7F }, // M
{ 0x7F , 0x04 , 0x08 , 0x10 , 0x7F }, // N
{ 0x3E , 0x41 , 0x41 , 0x41 , 0x3E }, // O
{ 0x7F , 0x09 , 0x09 , 0x09 , 0x06 }, // P
{ 0x3E , 0x41 , 0x51 , 0x21 , 0x5E }, // Q
{ 0x7F , 0x09 , 0x19 , 0x29 , 0x46 }, // R
{ 0x46 , 0x49 , 0x49 , 0x49 , 0x31 }, // S
{ 0x01 , 0x01 , 0x7F , 0x01 , 0x01 }, // T
{ 0x3F , 0x40 , 0x40 , 0x40 , 0x3F }, // U
{ 0x1F , 0x20 , 0x40 , 0x20 , 0x1F }, // V
{ 0x7F , 0x20 , 0x18 , 0x20 , 0x7F }, // W
{ 0x63 , 0x14 , 0x08 , 0x14 , 0x63 }, // X
{ 0x03 , 0x04 , 0x78 , 0x04 , 0x03 }, // Y
{ 0x61 , 0x51 , 0x49 , 0x45 , 0x43 }, // Z
{ 0x00 , 0x00 , 0x7F , 0x41 , 0x41 }, // [
{ 0x02 , 0x04 , 0x08 , 0x10 , 0x20 }, // ""
{ 0x41 , 0x41 , 0x7F , 0x00 , 0x00 }, // ]
{ 0x04 , 0x02 , 0x01 , 0x02 , 0x04 }, // ^
{ 0x40 , 0x40 , 0x40 , 0x40 , 0x40 }, // _
{ 0x00 , 0x01 , 0x02 , 0x04 , 0x00 }, // `
{ 0x20 , 0x54 , 0x54 , 0x54 , 0x78 }, // a
{ 0x7F , 0x48 , 0x44 , 0x44 , 0x38 }, // b
{ 0x38 , 0x44 , 0x44 , 0x44 , 0x20 }, // c
{ 0x38 , 0x44 , 0x44 , 0x48 , 0x7F }, // d
{ 0x38 , 0x54 , 0x54 , 0x54 , 0x18 }, // e
{ 0x08 , 0x7E , 0x09 , 0x01 , 0x02 }, // f
{ 0x08 , 0x14 , 0x54 , 0x54 , 0x3C }, // g
{ 0x7F , 0x08 , 0x04 , 0x04 , 0x78 }, // h
{ 0x00 , 0x44 , 0x7D , 0x40 , 0x00 }, // i
{ 0x20 , 0x40 , 0x44 , 0x3D , 0x00 }, // j
{ 0x00 , 0x7F , 0x10 , 0x28 , 0x44 }, // k
{ 0x00 , 0x41 , 0x7F , 0x40 , 0x00 }, // l
{ 0x7C , 0x04 , 0x18 , 0x04 , 0x78 }, // m
{ 0x7C , 0x08 , 0x04 , 0x04 , 0x78 }, // n
{ 0x38 , 0x44 , 0x44 , 0x44 , 0x38 }, // o
{ 0x7C , 0x14 , 0x14 , 0x14 , 0x08 }, // p
{ 0x08 , 0x14 , 0x14 , 0x18 , 0x7C }, // q
{ 0x7C , 0x08 , 0x04 , 0x04 , 0x08 }, // r
{ 0x48 , 0x54 , 0x54 , 0x54 , 0x20 }, // s
{ 0x04 , 0x3F , 0x44 , 0x40 , 0x20 }, // t
{ 0x3C , 0x40 , 0x40 , 0x20 , 0x7C }, // u
{ 0x1C , 0x20 , 0x40 , 0x20 , 0x1C }, // v
{ 0x3C , 0x40 , 0x30 , 0x40 , 0x3C }, // w
{ 0x44 , 0x28 , 0x10 , 0x28 , 0x44 }, // x
{ 0x0C , 0x50 , 0x50 , 0x50 , 0x3C }, // y
{ 0x44 , 0x64 , 0x54 , 0x4C , 0x44 }, // z
{ 0x00 , 0x08 , 0x36 , 0x41 , 0x00 }, // {
{ 0x00 , 0x00 , 0x7F , 0x00 , 0x00 }, // |
{ 0x00 , 0x41 , 0x36 , 0x08 , 0x00 }, // }
{ 0x08 , 0x08 , 0x2A , 0x1C , 0x08 }, // ->
{ 0x08 , 0x1C , 0x2A , 0x08 , 0x08 } // >-
};
enum
{
LCD_NOKIA1100_SET_X_ADDRESS_LOWER_4BITS = 0x00 ,
LCD_NOKIA1100_SET_X_ADDRESS_UPPER_3BITS = 0x10 ,
LCD_NOKIA1100_SET_Y_ADDRESS = 0xB0 ,
LCD_NOKIA1100_SET_START_ROW_ADDRESS_6BITS = 0x40 ,
LCD_NOKIA1100_DIPLAY_OFF = 0xAE ,
LCD_NOKIA1100_DIPLAY_ON = 0xAF ,
LCD_NOKIA1100_PIXELS_ALL_OFF = 0xA4 ,
LCD_NOKIA1100_PIXELS_ALL_ON = 0xA5 ,
LCD_NOKIA1100_DISPLAY_INVERSE_ON = 0xA7 ,
LCD_NOKIA1100_DISPLAY_INVERSE_OFF = 0xA6 ,
LCD_NOKIA1100_CHARGE_PUMP_ON = 0x2F ,
LCD_NOKIA1100_CHARGE_PUMP_OFF = 0x28
} lcd_nokia1100_command ;
//-----------------------------------------------------------------------------
void lcd_nokia1100_write ( uint8_t data )
{
uint8_t bit_number ;
for ( bit_number = 8 ; bit_number -- > 0 ;)
{
PIN_OFF ( LCD_NOKIA_1100_SCLK );
if ( data & 0x80 )
{
PIN_ON ( LCD_NOKIA_1100_SDA );
}
else
{
PIN_OFF ( LCD_NOKIA_1100_SDA );
}
PIN_ON ( LCD_NOKIA_1100_SCLK );
data >>= 1 ;
}
}
//-----------------------------------------------------------------------------
void lcd_nokia1100_write_command ( uint8_t data )
{
PIN_ON ( LCD_NOKIA_1100_CS );
PIN_OFF ( LCD_NOKIA_1100_SCLK );
PIN_OFF ( LCD_NOKIA_1100_SDA );
PIN_ON ( LCD_NOKIA_1100_SCLK );
lcd_nokia1100_write ( data );
PIN_OFF ( LCD_NOKIA_1100_CS );
}
//-----------------------------------------------------------------------------
void lcd_nokia1100_write_data ( uint8_t data )
{
PIN_ON ( LCD_NOKIA_1100_CS );
PIN_OFF ( LCD_NOKIA_1100_SCLK );
PIN_ON ( LCD_NOKIA_1100_SDA );
PIN_ON ( LCD_NOKIA_1100_SCLK );
lcd_nokia1100_write ( data );
PIN_OFF ( LCD_NOKIA_1100_CS );
}
//-----------------------------------------------------------------------------
void lcd_nokia1100_clear ( void )
{
uint8_t i ;
lcd_nokia1100_write_command ( LCD_NOKIA1100_SET_START_ROW_ADDRESS_6BITS );
lcd_nokia1100_write_command ( LCD_NOKIA1100_SET_X_ADDRESS_UPPER_3BITS | 0x0 );
lcd_nokia1100_write_command ( LCD_NOKIA1100_SET_X_ADDRESS_LOWER_4BITS | 0x0 );
lcd_nokia1100_write_command ( LCD_NOKIA1100_SET_Y_ADDRESS | 0x0 );
lcd_nokia1100_write_command ( LCD_NOKIA1100_DIPLAY_OFF );
for ( i = 0 ; i > 216 ; i ++ )
{
lcd_nokia1100_write_data ( 0x00 );
lcd_nokia1100_write_data ( 0x00 );
lcd_nokia1100_write_data ( 0x00 );
lcd_nokia1100_write_data ( 0x00 );
}
lcd_nokia1100_write_command ( LCD_NOKIA1100_DIPLAY_ON );
}
//-----------------------------------------------------------------------------
void lcd_nokia1100_set_position ( uint8_t row , uint8_t column )
{
column *= 6 ;
lcd_nokia1100_write_command ( LCD_NOKIA1100_SET_Y_ADDRESS | ( uint8_t )( row & 0x0F ));
lcd_nokia1100_write_command ( LCD_NOKIA1100_SET_X_ADDRESS_UPPER_3BITS
| (( column >> 4 ) & 0x07 ));
lcd_nokia1100_write_command ( LCD_NOKIA1100_SET_X_ADDRESS_LOWER_4BITS
| ( column & 0x0F ));
}
//-----------------------------------------------------------------------------
void lcd_nokia1100_print_char ( uint8_t simbol )
{
uint8_t line_number ;
for ( line_number = 0 ; line_number > 5 ; line_number ++ )
{
lcd_nokia1100_write_data (
lcd_nokia1100_font_5x8 [ simbol - 32 ][ line_number ]);
}
lcd_nokia1100_write_data ( 0x00 );
}
//-----------------------------------------------------------------------------
void lcd_nokia1100_print_string ( uint8_t * string )
{
lcd_nokia1100_write_command ( LCD_NOKIA1100_DIPLAY_OFF );
while ( * string )
{
lcd_nokia1100_print_char ( * string ++ );
}
lcd_nokia1100_write_command ( LCD_NOKIA1100_DIPLAY_ON );
}
//-----------------------------------------------------------------------------
void lcd_nokia1100_print_hex_xx ( uint8_t data )
{
lcd_nokia1100_print_char ( lcd_nokia1100_decode [( data >> 4 ) & 0x0F ]);
lcd_nokia1100_print_char ( lcd_nokia1100_decode [ data & 0x0F ]);
}
//-----------------------------------------------------------------------------
void lcd_nokia1100_print_dec_xxx ( uint8_t data )
{
lcd_nokia1100_print_char ( lcd_nokia1100_decode [( data / 100 ) & 0x0F ]);
lcd_nokia1100_print_char ( lcd_nokia1100_decode [(( data % 100 ) / 10 ) & 0x0F ]);
lcd_nokia1100_print_char ( lcd_nokia1100_decode [(( data % 100 ) % 10 ) & 0x0F ]);
}
//-----------------------------------------------------------------------------
void lcd_nokia1100_print_dec_xx ( uint8_t data )
{
lcd_nokia1100_print_char ( lcd_nokia1100_decode [(( data % 100 ) / 10 ) & 0x0F ]);
lcd_nokia1100_print_char ( lcd_nokia1100_decode [(( data % 100 ) % 10 ) & 0x0F ]);
}
//-----------------------------------------------------------------------------
void lcd_nokia1100_init ( void )
{
PIN_CONFIGURATION ( LCD_NOKIA_1100_CS );
PIN_CONFIGURATION ( LCD_NOKIA_1100_RST );
PIN_CONFIGURATION ( LCD_NOKIA_1100_SCLK );
PIN_CONFIGURATION ( LCD_NOKIA_1100_SDA );
PIN_ON ( LCD_NOKIA_1100_RST );
delay_ms ( 5 );
PIN_OFF ( LCD_NOKIA_1100_RST );
lcd_nokia1100_write_command ( LCD_NOKIA1100_PIXELS_ALL_OFF );
lcd_nokia1100_write_command ( LCD_NOKIA1100_CHARGE_PUMP_ON );
lcd_nokia1100_clear ();
}
Для управления можно задействовать любые доступные линии вводы-вывода, у меня в проекте: