Русский текст на дисплее с контроллером HD44780 и японским знакогенератором

logo.png
// Cham map 0x80 - 0xFF, with filler
uint8_t cmap[] = {
  0x04, 0x0a, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x00, // russian A
  0x1f, 0x10, 0x10, 0x1e, 0x11, 0x11, 0x1e, 0x00, // russian Be
  0x1e, 0x11, 0x11, 0x1e, 0x11, 0x11, 0x1e, 0x0,  // russian Ve
  0x1f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, // russian Ge
  0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x1f, 0x11, 0x00, // russian De
  0x1f, 0x10, 0x10, 0x1e, 0x10, 0x10, 0x1f, 0x00, // russian E
  0x15, 0x15, 0x15, 0x0e, 0x15, 0x15, 0x15, 0x00, // russian Zhe
  0x0e, 0x11, 0x01, 0x06, 0x01, 0x11, 0x0e, 0x00, // russian Ze
  0x11, 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x00, // russian I
  0x0e, 0x00, 0x11, 0x13, 0x15, 0x19, 0x11, 0x00, // russian Ij
  0x11, 0x12, 0x14, 0x18, 0x14, 0x12, 0x11, 0x00, // russian Ka
  0x07, 0x09, 0x09, 0x09, 0x09, 0x09, 0x11, 0x00, // russian L
  0x11, 0x11, 0x1b, 0x15, 0x15, 0x11, 0x11, 0x00, // russian M
  0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x00, // russian N
  0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0x00, // russian O
  0x1f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, // russian Pe
  0x1e, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x10, 0x00, // russian Re
  0x0e, 0x11, 0x10, 0x10, 0x10, 0x11, 0x0e, 0x00, // russian Se
  0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, // russian Te
  0x11, 0x11, 0x11, 0x0f, 0x01, 0x11, 0x0e, 0x00, // russian U
  0x0e, 0x15, 0x15, 0x15, 0x0e, 0x04, 0x04, 0x00, // russian Fe
  0x11, 0x0a, 0x04, 0x04, 0x0a, 0x0a, 0x11, 0x00, // russian He
  0x12, 0x12, 0x12, 0x12, 0x12, 0x1f, 0x01, 0x00, // russian Ce
  0x11, 0x11, 0x11, 0x0f, 0x01, 0x01, 0x01, 0x00, // russian Che
  0x11, 0x15, 0x15, 0x15, 0x15, 0x15, 0x1f, 0x00, // russian She
  0x11, 0x15, 0x15, 0x15, 0x15, 0x1f, 0x01, 0x00, // russian Sche
  0x18, 0x08, 0x08, 0x0e, 0x09, 0x09, 0x0e, 0x00, // russian Tverduy znak
  0x11, 0x11, 0x19, 0x15, 0x15, 0x15, 0x19, 0x00, // russian bI
  0x10, 0x10, 0x1e, 0x11, 0x11, 0x11, 0x1e, 0x00, // russian Myagkiy znak
  0x1e, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1e, 0x00, // russian Ee
  0x17, 0x15, 0x15, 0x1d, 0x15, 0x15, 0x17, 0x00, // russian You
  0x0f, 0x11, 0x11, 0x0f, 0x05, 0x09, 0x11, 0x00, // russian Ya
  //
  0x00, 0x00, 0x0e, 0x01, 0x0f, 0x11, 0x0f, 0x00, // russian small A
  0x01, 0x0e, 0x10, 0x1e, 0x11, 0x11, 0x0e, 0x00,
  0x00, 0x00, 0x1e, 0x11, 0x1e, 0x11, 0x1e, 0x00,
  0x00, 0x00, 0x1e, 0x10, 0x10, 0x10, 0x10, 0x00,
  0x00, 0x00, 0x0e, 0x0a, 0x0a, 0x1f, 0x11, 0x00,
  0x00, 0x00, 0x0e, 0x11, 0x1e, 0x10, 0x0e, 0x00,
  0x00, 0x00, 0x15, 0x15, 0x0e, 0x15, 0x15, 0x00,
  0x00, 0x00, 0x1e, 0x01, 0x0e, 0x01, 0x1e, 0x00,
  0x00, 0x00, 0x11, 0x13, 0x15, 0x19, 0x11, 0x00,
  0x0e, 0x00, 0x11, 0x13, 0x15, 0x19, 0x11, 0x00,
  0x00, 0x00, 0x09, 0x0a, 0x0c, 0x0a, 0x09, 0x00,
  0x00, 0x00, 0x07, 0x09, 0x09, 0x09, 0x11, 0x00,
  0x00, 0x00, 0x11, 0x1b, 0x15, 0x11, 0x11, 0x00,
  0x00, 0x00, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x00,
  0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, 0x00,
  0x00, 0x00, 0x1f, 0x11, 0x11, 0x11, 0x11, 0x00, // russian small Pe
  //
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  //
  0x00, 0x00, 0x1e, 0x11, 0x11, 0x1e, 0x10, 0x00, // russian small Re
  0x00, 0x00, 0x0e, 0x11, 0x10, 0x11, 0x0e, 0x00,
  0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x00,
  0x00, 0x00, 0x11, 0x11, 0x0f, 0x01, 0x0e, 0x00,
  0x00, 0x00, 0x1f, 0x15, 0x15, 0x1f, 0x04, 0x00,
  0x00, 0x00, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x00,
  0x00, 0x00, 0x12, 0x12, 0x12, 0x1f, 0x01, 0x00,
  0x00, 0x00, 0x11, 0x11, 0x0f, 0x01, 0x01, 0x00,
  0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x1f, 0x00,
  0x00, 0x00, 0x15, 0x15, 0x15, 0x1f, 0x01, 0x00,
  0x00, 0x00, 0x18, 0x0e, 0x09, 0x09, 0x0e, 0x00,
  0x00, 0x00, 0x11, 0x11, 0x1d, 0x15, 0x1d, 0x00,
  0x00, 0x00, 0x10, 0x1e, 0x11, 0x11, 0x1e, 0x00,
  0x00, 0x00, 0x1e, 0x01, 0x0f, 0x01, 0x1e, 0x00,
  0x00, 0x00, 0x17, 0x15, 0x1d, 0x15, 0x17, 0x00,
  0x00, 0x00, 0x0d, 0x13, 0x0f, 0x05, 0x09, 0x00, // russian small Ya
  0x0a, 0x00, 0x1f, 0x10, 0x1e, 0x10, 0x1f, 0x00, // russian Yo
  0x0a, 0x00, 0x0e, 0x11, 0x1e, 0x10, 0x0f, 0x00, // russian small Yo
  //
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00, // filler
  0x00, 0x04, 0x0a, 0x15, 0x0a, 0x04, 0x00, 0x00  // filler
};



static uint8_t lcd_draw_part = 0;
static uint8_t lcd_ch;
static uint8_t lcd_draw_string[16] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
                                       0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87 };



void TIM4_IRQHandler() 
{
  if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
  {
    TIM_ClearITPendingBit(TIM4, TIM_IT_Update);

    // стираем то что светили ранее, part = 0 - 0..7, part = 1 - 8..15
    LCD_gotoxy(0, (lcd_draw_part ? 0 : 8));   
    LCD_write_data(0x20);
    LCD_write_data(0x20);
    LCD_write_data(0x20);
    LCD_write_data(0x20);
    LCD_write_data(0x20);
    LCD_write_data(0x20);
    LCD_write_data(0x20);
    LCD_write_data(0x20);
  
    // загружаем в CGRAM до 8 символов
    for(uint8_t i = 0; i < 8; i++)
    {
      lcd_ch = lcd_draw_string[i + (lcd_draw_part ? 8 : 0)];
      if(lcd_ch > 127)
        LCD_load_symbol(i, cmap + 8 * (lcd_ch & 0x7f) );
    }
    // рисуем
    LCD_gotoxy(0, (lcd_draw_part ? 8 : 0));
    for(uint8_t i = 0; i < 8; i++)
    {
      lcd_ch = lcd_draw_string[i + (lcd_draw_part ? 8 : 0)];
     if(lcd_ch < 128)
        LCD_write_data(lcd_ch);
      else
        LCD_write_data(i);
    }
    
    lcd_draw_part ^= 0x01;
  }
}

void LCD_start_fps()
{
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
  TIM_TimeBaseInitTypeDef timerInitStructure;
  timerInitStructure.TIM_Prescaler = 48-1;
  timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
  timerInitStructure.TIM_Period = 20000;                      //  20ms/isr
  timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  timerInitStructure.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInit(TIM4, &timerInitStructure);
  TIM_Cmd(TIM4, ENABLE);
  TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
  
  NVIC_InitTypeDef nvicStructure;
  nvicStructure.NVIC_IRQChannel = TIM4_IRQn;
  nvicStructure.NVIC_IRQChannelPreemptionPriority = 0;
  nvicStructure.NVIC_IRQChannelSubPriority = 2;
  nvicStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&nvicStructure);
}


© Geektimes