|
Таймер на атмега8
|
|
alexval2007 | Дата: Пятница, 20.08.2010, 23:43 | Сообщение # 1 |
 Электро воспламенитель
Группа: Администраторы
Сообщений: 659
Статус: Offline
| Простой таймер на микроконтроллере Atmega8 Статья написана по материалам сайта http://extremeelectronics.co.in/
Таймеры широко используются в промышленных и бытовых устройствах. Микроконтроллеры с легкостью могут быть использованы для создания универсальных и точных таймеров. В этой статье представлен простой таймер, который можно использовать для включения / выключения нагрузки после истечения указанного пользователем времени. Схема устройства:
В таймере используется микроконтроллер ATmega8 фирмы Atmel и стандартный LCD дисплей 16x2 на базе контролера HD44780 для визуализации управления. Пользователь может установить время с помощью 3-кнопочной клавиатуры. После того как таймер запустится оставшееся время отображается на экране. Контрастность дисплея регулируется резистором RV1. При включении таймера нагрузка находится в выключенном состоянии. После этого вы можете установить время с помощью кнопки "Больше". После этого перейти на "старт" с помощью кнопки "Выбор". Затем нажмите любую клавишу, чтобы запустить таймер. Теперь на экране обратный отсчет и нагрузка включена. Когда отсчет достигает 0 нагрузка отключается. Использование Таймера Управление таймером производиться посредством 3х кнопок и LCD дисплея. Назначение кнопок: 1. Кнопка Выбор - Нужна для подтверждения выбранного значения часов, минут и тп. 2. Кнопка Вверх/Инкремент - Увеличивает значение. Например, выбор "минуты" используя кнопку "Выбор" и нажимать Кнопка Вверх/Инкремент, чтобы увеличивать время. 3. Кнопка Вниз/Декремент - Имеют те же функции что кнопка выше только на оборот уменьшает значение времени.
При включении таймера на дисплее появляться надпись Добро пожаловать. Затем Вы можете установить время, использовавшее вышеуказанные кнопки. После это жмём кнопку "Выбор". Затем нажимаем любую кнопку, для запуска таймера. На дисплее отображаться установленное время и идет обратный отсчёт. Нагрузка включена до окончания отсчета, по достижению нуля нагрузка отключается. Тут показаны настройки таймера.
А тут процесс обратного отсчёта
****************************************************************************************** Код таймера ****************************************************************************************** /*************************************************************************** После истечения заданной выдержки времени таймер автоматически выключает нагрузку, которая была включена при старте таймера. В устройстве применен LCD дисплей 16x2 для пользовательского интерфейса. Для работы с ним применена специальная библиотека lcd.h она есть в архиве с проектом. Пользователь может установить время, при помощи трёх кнопок. После запуска Таймер считает в обратном порядке, время отображаетса на экране. Код написан и скомпилирован в avr-gcc + Studio AVR. ****************************************************************************/ //******************************************************************************************* #include <avr/io.h> #include <avr/interrupt.h> #include "lcd.h"
//Константы #define LOAD_DDR DDRC #define LOAD_PORT PORTC #define LOAD_POS PC0
//Глобальные переменные для системных часов. volatile unsigned int clock_millisecond=0; // Переменная мили секунд. volatile char clock_second=0; // Переменная секунд. volatile char clock_minute=0; // Переменная минут. volatile char clock_hour=0; // Переменная часов.
void Wait(uint8_t n){ uint8_t i,temp; temp=n*28; for(i=0;i<temp;i++) _delay_loop_2(0); } //*************************************************** void LoadOn(){ // Подпрограмма включения нагрузки. LOAD_PORT|=(1<<LOAD_POS); } //*************************************************** void LoadOff(){ // Подпрограмма выключения нагрузки. LOAD_PORT&=(~(1<<LOAD_POS)); } //******************************************************************************* // Основной программный цикл. //******************************************************************************* main(){ while(1){ LOAD_DDR|=(1<<LOAD_POS); LoadOff(); // Выключаем нагрузку PORTB|=((1<<PB2)|(1<<PB1)|(1<<PB0));//Включаем подтягивающие резисторы для клавиатуры. int8_t hr,min; //Target время. hr=min=0; InitLCD(0); // Инициализируем LCD LCDClear(); // Очищаем дисплей. TCCR1B=(1<<WGM12)|(1<<CS11)|(1<<CS10);//Настроим timer1 OCR1A=250; TIMSK|=(1<<OCIE1A);//Разрешаем внешнее прерывание по совпадению Compare A sei();// Разрешаем глобальные прерывания LCDClear(); // Очищаем дисплей. LCDWriteString(" Welcome "); // Выведем на LCD текст LCDWriteStringXY(0,1," Relay Timer ");// Выведем на LCD текст Wait(4); LCDClear(); // Очищаем дисплей. LCDWriteString("Set Time - 00:00"); // Выведем на LCD текст LCDWriteStringXY(0,1," Start ^");// Выведем на LCD текст
uint8_t selection=1; uint8_t old_pinb=PINB;
while(1){ while((PINB & 0b00000111) == (old_pinb & 0b00000111));
if(!(PINB & (1<<PINB2)) && (old_pinb & (1<<PB2))){ // Кнопка нажата //Ключ нажатой кнопки selection++; if(selection==3) selection =0; }
if(!(PINB & (1<<PINB1)) && (old_pinb & (1<<PB1))){ //Кнопка вверх нажата if(selection == 1){ //Часы выбраны увеличиваем на +1 hr++; if(hr == 100) hr =0; }
if(selection == 2){ //Минуты выбраныа увеличиваем на +1 min++; if(min == 60) min =0; }
if(selection == 0){ //Старт выбран break; } }
if(!(PINB & (1<<PINB0)) && (old_pinb & (1<<PB0))){ //Кнопка вниз нажата if(selection == 1){ //Часы выбраны уменьшаем на -1 hr--; if(hr == -1) hr =99; }
if(selection == 2){ //Минуты выбраны уменьшаем на -1 min--; if(min == -1) min =59; }
if(selection == 0){ //Старт выбран break; } } old_pinb=PINB;// сохраним текущее состояние кнопок в переменую old_pinb
//Обновим LCD LCDClear(); // Очищаем дисплей. LCDWriteString("Set Time - 00:00");// Выведем на LCD текст LCDWriteStringXY(0,1," Start ");// Выведем на LCD текст
//Часы LCDWriteIntXY(11,0,hr,2);// Выведем на LCD текст
//Минуты LCDWriteIntXY(14,0,min,2);// Выведем на LCD текст if(selection == 0) LCDWriteStringXY(0,1,">");// Выведем на LCD текст if(selection == 1) LCDWriteStringXY(11,1,"^");// Выведем на LCD текст if(selection == 2) LCDWriteStringXY(14,1,"^");// Выведем на LCD текст
_delay_loop_2(0); _delay_loop_2(0); _delay_loop_2(0); _delay_loop_2(0); _delay_loop_2(0); _delay_loop_2(0); _delay_loop_2(0); _delay_loop_2(0); }
LoadOn();// Включаим нагрузку. // Теперь запустим таймер clock_hour = hr; clock_minute = min; clock_second =0; LCDClear(); // Очищаем дисплей. LCDWriteString(" Power Off In ");// Выведем на LCD текст
while(1){ LCDWriteIntXY(4,1,clock_hour,2); // Выведем на LCD текст LCDWriteString(":"); // Выведем на LCD текст LCDWriteIntXY(7,1,clock_minute,2); // Выведем на LCD текст LCDWriteString(":"); // Выведем на LCD текст LCDWriteIntXY(10,1,clock_second,2);// Выведем на LCD текст
if((clock_hour == 0) && (clock_minute == 0) && (clock_second == 0)){ // Время вышло LoadOff(); // Выключаем нагрузку LCDClear(); // Очищаем дисплей. LCDWriteString("Load Turned Off");// Выведем на LCD текст
while(1){ LCDWriteStringXY(0,1,"*Press Any Key*");// Выведем на LCD текст Wait(1); LCDWriteStringXY(0,1," ");// Выведем на LCD текст Wait(1); if((~PINB) & 0b00000111) break; } break; } _delay_loop_2(0); _delay_loop_2(0); _delay_loop_2(0); _delay_loop_2(0); } } }
//Обработчик прерывания по совпадению канала А //Настраиваем таймер на 1 мс ISR(TIMER1_COMPA_vect){ clock_millisecond++; if(clock_millisecond==1000){ clock_second--; clock_millisecond=0; if(clock_second==-1){ clock_minute--; clock_second=59; if(clock_minute==-1){ clock_hour--; clock_minute=59; } } } }
****************************************************************************************** Ну а тут код библиотеки для работы с LCD ****************************************************************************************** #include <avr/io.h> #ifndef F_CPU #define F_CPU 16000000UL #endif #include <util/delay.h> #include "myutils.h" #ifndef _LCD_H #define _LCD_H /************************************************ Подключение к LCD *************************************************/ #define LCD_DATA D // Порт PD0-PD3 подключается к D4-D7 #define LCD_E D // Enable OR strobe signal #define LCD_E_POS PD4 //Position of enable in above port #define LCD_RS D #define LCD_RS_POS PD6 #define LCD_RW D #define LCD_RW_POS PD5
//************************************************ #define LS_BLINK 0B00000001 #define LS_ULINE 0B00000010
/*************************************************** Функции ****************************************************/ void InitLCD(uint8_t style); void LCDWriteString(const char *msg); void LCDWriteInt(int val,unsigned int field_length); void LCDGotoXY(uint8_t x,uint8_t y);
//Низкий уровень void LCDByte(uint8_t,uint8_t); #define LCDCmd© (LCDByte(c,0)) #define LCDData(d) (LCDByte(d,1))
void LCDBusyLoop(); /*************************************************** Макросы ***************************************************/ #define LCDClear() LCDCmd(0b00000001) #define LCDHome() LCDCmd(0b00000010); #define LCDWriteStringXY(x,y,msg) {\ LCDGotoXY(x,y);\ LCDWriteString(msg);\ }
#define LCDWriteIntXY(x,y,val,fl) {\ LCDGotoXY(x,y);\ LCDWriteInt(val,fl);\ }
#endif [/code]
************************************************ LCD.c ************************************************ #include <avr/io.h> #include <inttypes.h> #ifndef F_CPU #define F_CPU 16000000UL #endif #include <util/delay.h> #include "lcd.h" #define LCD_DATA_PORT PORT(LCD_DATA) #define LCD_E_PORT PORT(LCD_E) #define LCD_RS_PORT PORT(LCD_RS) #define LCD_RW_PORT PORT(LCD_RW) #define LCD_DATA_DDR DDR(LCD_DATA) #define LCD_E_DDR DDR(LCD_E) #define LCD_RS_DDR DDR(LCD_RS) #define LCD_RW_DDR DDR(LCD_RW) #define LCD_DATA_PIN PIN(LCD_DATA) #define SET_E() (LCD_E_PORT|=(1<<LCD_E_POS)) #define SET_RS() (LCD_RS_PORT|=(1<<LCD_RS_POS)) #define SET_RW() (LCD_RW_PORT|=(1<<LCD_RW_POS))
#define CLEAR_E() (LCD_E_PORT&=(~(1<<LCD_E_POS))) #define CLEAR_RS() (LCD_RS_PORT&=(~(1<<LCD_RS_POS))) #define CLEAR_RW() (LCD_RW_PORT&=(~(1<<LCD_RW_POS)))
void LCDByte(uint8_t c,uint8_t isdata){ //Sends a byte to the LCD in 4bit mode //cmd=0 for data //cmd=1 for command //NOTE: THIS FUNCTION RETURS ONLY WHEN LCD HAS PROCESSED THE COMMAND uint8_t hn,ln; //Nibbles uint8_t temp; hn=c>>4; ln=(c & 0x0F); if(isdata==0) CLEAR_RS(); else SET_RS(); _delay_us(0.500); //tAS SET_E();
//Send high nibble temp=(LCD_DATA_PORT & 0XF0)|(hn); LCD_DATA_PORT=temp; _delay_us(1); //tEH
//Now data lines are stable pull E low for transmission CLEAR_E(); _delay_us(1);
//Send the lower nibble SET_E(); temp=(LCD_DATA_PORT & 0XF0)|(ln); LCD_DATA_PORT=temp; _delay_us(1); //tEH
//SEND CLEAR_E(); _delay_us(1); //tEL LCDBusyLoop(); }
void LCDBusyLoop(){ //This function waits till lcd is BUSY uint8_t busy,status=0x00,temp; //Change Port to input type because we are reading data LCD_DATA_DDR&=0xF0;
//change LCD mode SET_RW(); //Read mode CLEAR_RS(); //Read status
//Let the RW/RS lines stabilize _delay_us(0.5); //tAS
do{ SET_E();
//Wait tDA for data to become available _delay_us(0.5);
status=LCD_DATA_PIN; status=status<<4;
_delay_us(0.5);
//Pull E low CLEAR_E(); _delay_us(1); //tEL
SET_E(); _delay_us(0.5);
temp=LCD_DATA_PIN; temp&=0x0F; status=status|temp; busy=status & 0b10000000;
_delay_us(0.5); CLEAR_E(); _delay_us(1); //tEL }while(busy);
CLEAR_RW(); //write mode //Change Port to output LCD_DATA_DDR|=0x0F;
}
void InitLCD(uint8_t style){ /*****************************************************************
This function Initializes the lcd module must be called before calling lcd related functions
Arguments: style = LS_BLINK,LS_ULINE(can be "OR"ed for combination) LS_BLINK :The cursor is blinking type LS_ULINE :Cursor is "underline" type else "block" type
*****************************************************************/
//After power on Wait for LCD to Initialize _delay_ms(30);
//Set IO Ports LCD_DATA_DDR|=(0x0F); LCD_E_DDR|=(1<<LCD_E_POS); LCD_RS_DDR|=(1<<LCD_RS_POS); LCD_RW_DDR|=(1<<LCD_RW_POS);
LCD_DATA_PORT&=0XF0; CLEAR_E(); CLEAR_RW(); CLEAR_RS();
//Set 4-bit mode _delay_us(0.3); //tAS
SET_E(); LCD_DATA_PORT|=(0b00000010); // To transfer 0b00100000 i was using LCD_DATA_PORT|=0b00100000 _delay_us(1); CLEAR_E(); _delay_us(1);
//Wait for LCD to execute the Functionset Command LCDBusyLoop(); //[B] Forgot this delay
//Now the LCD is in 4-bit mode LCDCmd(0b00001100|style); //Display On LCDCmd(0b00101000); //function set 4-bit,2 line 5x7 dot format } void LCDWriteString(const char *msg){ /***************************************************************** This function Writes a given string to lcd at the current cursor location. Arguments: msg: a null terminated string to print *****************************************************************/ while(*msg!='\0'){ LCDData(*msg); msg++; } }
void LCDWriteInt(int val,unsigned int field_length){ /*************************************************************** This function writes a integer type value to LCD module Arguments: 1)int val : Value to print 2)unsigned int field_length :total length of field in which the value is printed must be between 1-5 if it is -1 the field length is no of digits in the val ****************************************************************/
char str[5]={0,0,0,0,0}; int i=4,j=0; while(val) { str[i]=val%10; val=val/10; i--; } if(field_length==-1) while(str[j]==0) j++; else j=5-field_length;
if(val<0) LCDData('-'); for(i=j;i<5;i++) { LCDData(48+str[i]); } } void LCDGotoXY(uint8_t x,uint8_t y) { if(x<40) { if(y) x|=0b01000000; x|=0b10000000; LCDCmd(x); } }
[b]************************************************ И еще один подключаемый файл ************************************************
#ifndef MYUTILS_H #define MYUTILS_H
#define _CONCAT(a,b) a##b #define PORT(x) _CONCAT(PORT,x) #define PIN(x) _CONCAT(PIN,x) #define DDR(x) _CONCAT(DDR,x)
#endif
Весь проект целиком Скачать
|
|
| |
alexval2007 | Дата: Пятница, 20.08.2010, 23:54 | Сообщение # 2 |
 Электро воспламенитель
Группа: Администраторы
Сообщений: 659
Статус: Offline
| Теперь поговорим немного о русификации этого дисплея так как мы будим использовать алфавитно-цифровой ЖК-модуль WH1602D фирмы Winstar то он имеет две кодовых таблицы латиницу и кириллицу *************************************************** вариант номер раз *************************************************** #define LCD_E 0b00010000 #define LCD_RW 0b01000000 #define LCD_RS 0b00100000
void lcd_init(void) //инициализация дисплея { PORT_LCD=0b00000011; //8-бит NOP(); SetBit(PORT_LCD,LCD_E); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); Delay_ms(5);
PORT_LCD=0b00000011; //8-бит NOP(); SetBit(PORT_LCD,LCD_E); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); Delay_mks(110);
PORT_LCD=0b00000011; //8-бит NOP(); SetBit(PORT_LCD,LCD_E); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); Delay_mks(43);
PORT_LCD=0b00000010; //4-бит NOP(); SetBit(PORT_LCD,LCD_E); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); Delay_mks(43);
PORT_LCD=0b00000010; //4-бит NOP(); SetBit(PORT_LCD,LCD_E); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); Delay_mks(43);
PORT_LCD=0b00001100; //SET NOP(); SetBit(PORT_LCD,LCD_E); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); Delay_mks(43);
PORT_LCD=0; NOP(); SetBit(PORT_LCD,LCD_E); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); Delay_mks(43);
PORT_LCD=0b00001000; NOP(); SetBit(PORT_LCD,LCD_E); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); Delay_mks(43);
PORT_LCD=0; NOP(); SetBit(PORT_LCD,LCD_E); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); Delay_mks(43);
PORT_LCD=0b00000001; NOP(); SetBit(PORT_LCD,LCD_E); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); Delay_mks(43);
PORT_LCD=0; NOP(); SetBit(PORT_LCD,LCD_E); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); Delay_mks(43);
PORT_LCD=0b00000110; //Set NOP(); SetBit(PORT_LCD,LCD_E); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); Delay_ms(2); }
void WriteSym(char sym) //запись символа в активную область { char _temp; _temp=sym; asm("swap %sym"); sym &=0x0F; sym |=LCD_RS; sym |=LCD_E; NOP(); NOP(); PORT_LCD=sym; NOP(); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); NOP(); NOP(); NOP();
sym=_temp; sym &=0x0F; sym |=LCD_RS; sym |=LCD_E; NOP(); NOP(); PORT_LCD=sym; NOP(); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); NOP(); NOP(); NOP(); Delay_mks(43); }
void WriteDDR(char ddr) //выбор адреса { char _temp; _temp=ddr; asm("swap %ddr"); ddr&=0x0F; ddr|=LCD_E; ClrBit(ddr,LCD_RS); //ClrBit(ddr,LCD_RW); PORT_LCD=ddr; NOP(); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); NOP(); NOP(); NOP();
ddr=_temp; ddr&=0x0F; ddr|=LCD_E; ClrBit(ddr,LCD_RS); PORT_LCD=ddr; NOP(); NOP(); NOP(); NOP(); ClrBit(PORT_LCD,LCD_E); Delay_mks(43); }
void lcd_puts(char stp[],int delay) // вывод строки на дисплей с задержкой { int n=0; for(n;n<strlen(stp);n++) { if(n>=16) return; if(stp[n]!=0xFF) { WriteSym(stp[n]); Delay_ms(delay); } } }
void lcd_rus(char stp[]) //вывод строки по-русски { int n=0;
for(n;n<strlen(stp);n++) { if(n>=16) return; Delay_mks(100); switch(stp[n]) { case 192: WriteSym(65); break;
case 'а': WriteSym('a'); break;
case 'Б': WriteSym(160); break;
case 'б': WriteSym(178); break;
case 'В': WriteSym('B'); break;
case 'в': WriteSym(179); break;
case 'Г': WriteSym(161); break;
case 'г': WriteSym(180); break;
case 'Д': WriteSym(224); break;
case 'д': WriteSym(227); break;
case 'Е': WriteSym('E'); break;
case 'е': WriteSym('e'); break;
case 'Ё': WriteSym(162); break;
case 'ё': WriteSym(181); break;
case 'Ж': WriteSym(163); break;
case 'ж': WriteSym(182); break;
case 'З': WriteSym(164); break;
case 'з': WriteSym(183); break;
case 'И': WriteSym(165); break;
case 'и': WriteSym(184); break;
case 'Й': WriteSym(166); break;
case 'й': WriteSym(185); break;
case 'К': WriteSym('K'); break;
case 'к': WriteSym('k'); break;
case 'Л': WriteSym(167); break;
case 'л': WriteSym(187); break;
case 'М': WriteSym('M'); break;
case 'м': WriteSym(188); break;
case 'Н': WriteSym('H'); break;
case 'н': WriteSym(189); break;
case 'О': WriteSym('O'); break;
case 'о': WriteSym('o'); break;
case 'П': WriteSym(168); break;
case 'п': WriteSym(190); break;
case 'Р': WriteSym('P'); break;
case 'р': WriteSym('p'); break;
case 'С': WriteSym('C'); break;
case 'с': WriteSym('c'); break;
case 'Т': WriteSym('T'); break;
case 'т': WriteSym(191); break;
case 'У': WriteSym(169); break;
case 'у': WriteSym(121); break;
case 'Ф': WriteSym(0xAA); break;
case 'ф': WriteSym(0xE4); break;
case 'Х': WriteSym(88); break;
case 'х': WriteSym(120); break;
case 'Ц': WriteSym(225); break;
case 'ц': WriteSym(229); break;
case 'Ч': WriteSym(171); break;
case 'ч': WriteSym(192); break;
case 'Ш': WriteSym(172); break;
case 'ш': WriteSym(193); break;
case 'Щ': WriteSym(226); break;
case 'щ': WriteSym(230); break;
case 'Ъ': WriteSym(173); break;
case 'ъ': WriteSym(194); break;
case 'Ы': WriteSym(174); break;
case 'ы': WriteSym(195); break;
case 'Ь': WriteSym(98); break;
case 'ь': WriteSym(196); break;
case 'Э': WriteSym(175); break;
case 'э': WriteSym(197); break;
case 'Ю': WriteSym(176); break;
case 'ю': WriteSym(198); break;
case 'Я': WriteSym(177); break;
case 'я': WriteSym(199); break;
default : WriteSym(stp[n]); break; } } }
void Write_CGRAM(void) { WriteDDR(0x40); //WriteSym(0); WriteSym(0); WriteSym(0b00000100); WriteSym(0b00000010); WriteSym(0b11111111); WriteSym(0b00000010); WriteSym(0b00000100); WriteSym(0); WriteSym(0); Delay_ms(2); WriteDDR(0x48); WriteSym(0b00000110); WriteSym(0b00001001); WriteSym(0b00001001); WriteSym(0b00000110); WriteSym(0); WriteSym(0); WriteSym(0); WriteSym(0); }
*********************************************************** Вариант номер 2 *********************************************************** char *str; // буферная строковая перменная для вывода
//массив во флэш-памяти для русских символов flash char Decode2Rus[255-192+1]= { 0x41,0xA0,0x42,0xA1,0xE0,0x45,0xA3,0xA4, 0xA5,0xA6,0x4B,0xA7,0x4D,0x48,0x4F,0xA8, 0x50,0x43,0x54,0xA9,0xAA,0x58,0xE1,0xAB, 0xAC,0xE2,0 xAD,0xAE,0xAD,0xAF,0xB0,0xB1, 0x61,0xB2,0xB3,0xB4,0xE3,0x65,0xB6,0xB7, 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0x6F,0xBE, 0x70,0x63,0xBF,0x79,0xE 4, 0x78,0xE5,0xC0, 0xC1,0xE6,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7 };
//функция вывода на LCD русско-символьной строки void putsf(flash unsigned char *string) { char c; //символ из строки while (c=*string++){ if(c>=192) lcd_putchar(Decode2Rus[c-192]); else lcd_putchar©; } }
выводить на лсд будешь вот так: putsf("я Кот Матроскин!"); [/code]
|
|
| |
|
|
|