PIC16F676 и LCD-экран 1602 и русский шрифт

Category: PIC mcpu
Posted on: 15.05.2022 в 07:37 - 1 комментарий - Visited 5444 times

Продолжаем обсуждение возможностей контроллера PIC16F676. Теперь будем его использовать для работы со стандартным экраном 1602. И так, сначала схема:

Мы помним, что наш контроллер — это маленький компьютер, так что не удивительно, что для работы с ЖК-экраном для него нужен драйвер. Драйвером выступает уже готовый C-файл, который нужно будет просто подключить к нашему «main.c». Драйвер для ЖК-экрана 1602 можно скачать здесь.

/*
 * File:   main.c
 * Author: Pti_the_Leader
 *
 * Created on 30 ?????? 2019 ?., 17:54
 */
 
 
// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF      // RA3/MCLR pin function select (RA3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
 
// #pragma config statements should precede project file includes.
#define _XTAL_FREQ 4000000
// Определяем к какой ножке подключен вывод экранчика, необходимо для драйвера
#define RS RA0
#define EN RA1
#define D4 RC0
#define D5 RC1
#define D6 RC2
#define D7 RC3
#define light RA4
 
#include <xc.h>
#include "lcd.c" // Подключаем драйвер ЖК-экрана
 
void main(void) {
    TRISA = 0b00000000; // Все ножки порта A - выходы
    TRISC = 0b00000000; // Все ножки порта C - выходы
    ANSEL = 0b00000000; // Отключаем АЦП
    CMCON = 0x07; // Отключаем компараторы
    PORTA = 0; // Сброс порта A
    PORTC = 0; // Сброс порта C
 
    Lcd_Start();
    light = 1; 
    while(1) {
        Lcd_Clear();
        Lcd_Set_Cursor(1,1);
        Lcd_Print_String("  Hello, Word!  ");
        Lcd_Set_Cursor(2,1);
        Lcd_Print_String("PIC16F676 Rules!");
        __delay_ms(2000);
    }
    return;    
}

Выглядит всё очень замечательно. Экранчик — это тоже устройство, которым управляет наш контроллер. И всё бы было хорошо, если бы не одно но. В свободной продаже нет экранчиков, в которых был бы русский шрифт, да, в природе они существуют, однако ценник на них заоблачный. Для решения этой проблемы у нас есть возможность создавать до восьми пользовательских символов, ну и использовать похожие английские буквы. Давайте попробуем написать «Мама мыла раму».

Пользовательские символы

Как видим, в драйвере есть необходимый набор для отправки команд в экранчик. Собственно всё, что нам нужно, это знать команды, как записывать и выводить пользовательские символы. Знакомест на экранчике представляет собой набор точек, 5 по горизонтали и 8 по вертикали. Последовательно посылая в область памяти наборы бит мы можем нарисовать любой символ.

Давайте теперь посчитаем, какие дополнительные буквы нам будут нужны в нашей фразе «Мама мыла раму». Самая первая буква — это маленькая «м», в английском языке нет её похожего аналога. Во втором слове встречается ещё одна буква — маленькая «ы» и сразу же за ней — «л». Все остальные буквы есть в английском алфавите, нам нужно будет создать только 3 буквы.

Для удобства можно взять тетрадный листик и закрашивать квадратики, создавая образ нужной буквы. Пустые клеточки — это нули, закрашенные — это единицы. Теперь перенесём наши буквы в программу:

unsigned char rus_m[8] = {
  0b00000,
  0b00000,
  0b10001,
  0b11011,
  0b10101,
  0b10001,
  0b10001,
  0b00000
};//м
unsigned char rus_y[8] = {
  0b00000,
  0b00000,
  0b10001,
  0b10001,
  0b11101,
  0b10011,
  0b11101,
  0b00000
};//ы
unsigned char rus_l[8] = {
  0b00000,
  0b00000,
  0b00111,
  0b01001,
  0b01001,
  0b01001,
  0b10001,
  0b00000
};//л

Даже по очертаниям видно, как будет примерно выглядеть наша буква. Теперь осталось дело за малым, всё помещаем в один файл и если что не понятно, читаем комментарии:

/*
 * File:   main.c
 * Author: Pti_the_Leader
 *
 * Created on 30 ?????? 2019 ?., 17:54
 */
 
 
// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF      // RA3/MCLR pin function select (RA3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
 
// #pragma config statements should precede project file includes.
#define _XTAL_FREQ 4000000
#define RS RA0
#define EN RA1
#define D4 RC0
#define D5 RC1
#define D6 RC2
#define D7 RC3
#define light RA4
 
#include <xc.h>
#include "lcd.c"
 
unsigned char rus_m[8] = {
  0b00000,
  0b00000,
  0b10001,
  0b11011,
  0b10101,
  0b10001,
  0b10001,
  0b00000
};//м
unsigned char rus_y[8] = {
  0b00000,
  0b00000,
  0b10001,
  0b10001,
  0b11101,
  0b10011,
  0b11101,
  0b00000
};//ы
unsigned char rus_l[8] = {
  0b00000,
  0b00000,
  0b00111,
  0b01001,
  0b01001,
  0b01001,
  0b10001,
  0b00000
};//л
 
void main(void) {
    TRISA = 0b00000000; // Все ножки порта A - выходы
    TRISC = 0b00000000; // Все ножки порта C - выходы
    ANSEL = 0b00000000; // Отключаем АЦП
    CMCON = 0x07; // Отключаем компараторы
    PORTA = 0; // Сброс порта A
    PORTC = 0; // Сброс порта C
 
    unsigned int a;
    Lcd_Start();
    light = 1;
 
 
    //*** Загрузка дополнительных символов в CGRAM ***//////
    char i;
    Lcd_Cmd(0x04);
    Lcd_Cmd(0x00);   // Установлен начальный адрес для загрузки пользовательских символов
    for (i = 0; i < 8 ; i++) Lcd_Print_Char(rus_m[i]); //Адрес 0 русская м
    for (i = 0; i < 8 ; i++) Lcd_Print_Char(rus_y[i]); //Адрес 1 русская ы
    for (i = 0; i < 8 ; i++) Lcd_Print_Char(rus_l[i]); //Адрес 2 русская л
    Lcd_Cmd(0);
    Lcd_Cmd(2);      // Возврат домой
    //*** Загрузка завершена ***//////
 
 
    while(1) {
        Lcd_Clear();
 
        Lcd_Set_Cursor(1,1);
        Lcd_Print_String(" Mama myla pamy "); // Наша начальная фраза, в которой будем заменять буквы
 
        Lcd_Set_Cursor(1,4); // Установим курсов в первой строке на 4 символ, это маленькая буква "m" в слове "Mama"
        Lcd_Print_Char(0); // Заменим его на русскую "м", которая у нас расположена в пользовательских символах по адресу 0
 
        Lcd_Set_Cursor(1,7); // Теперь это "m" в слове "myla"
        Lcd_Print_Char(0); // Заменяем на русскую "м"
 
        Lcd_Set_Cursor(1,8); // следующая "y" в слове "myla"
        Lcd_Print_Char(1); // Заменяем на русскую "ы" и так далее....
 
        Lcd_Set_Cursor(1,9);
        Lcd_Print_Char(2);
 
        Lcd_Set_Cursor(1,14);
        Lcd_Print_Char(0);
 
        Lcd_Set_Cursor(2,1);
        Lcd_Print_String("PIC16F676 Rules!");
        __delay_ms(2000);
    }
    return;    
}

Результат выполнения:

Дополнительные символы

В экранчике ещё зашиты некоторые символы, которые могут быть полезны. к примеру «Альфа». Вызвать его можно согласно карте в бинарном виде, то есть со столбца берём первые 4 цифры и заменяем в начале строки. то есть Альфу можно вызвать набрав «Lcd_Print_Char(0b11100000);». К примеру «Омегу» можно вывести, если ввести «Lcd_Print_Char(0b11110100);»

1 комментарий on “PIC16F676 и LCD-экран 1602 и русский шрифт”

1
Alex

«Открыть общий доступ к диску в Windows 10»
Здравствуйте, спасибо Вам за решение в этой вот старенькой статье. Действительно, помогло только оно! Под ней комментарии не работают почему-то. Пишу тут. Интересно стало, как это сделать более грамотно через Политики, вы не нашли этот способ в итоге?

17.07.2022 on 22:40

Добавить комментарий

Включите изображения, чтобы увидеть вопрос *