Страница 1 из 1

Дисплей LS020 + STM32, отказывается работать

Добавлено: Ср май 01, 2013 13:47:51
КАШАК
Доброго времени суток :)

Пытаюсь запустить дисплей на контроллере LS020 с STM32VL Discovery. Инициализация проходит, заливка работает, но вывести какую-либо графику не получается. Все время начинается вывод с краю дисплея и все время какая-то абракадабра. Инициализация вот такая:
Спойлер

Код: Выделить всё

void SPIsend(int Data)
{
   SPI1->DR = Data;
   while(!((SPI1->SR)&SPI_SR_TXE));
}

void lcd_init_c(void)
{
const unsigned int  INIT1[2] ={0xFDFD,0xFDFD};
const unsigned int  INIT2[10] ={0xEF00,0xEE04,0x1B04,0xFEFE,0xFEFE,0xEF90,0x4A04,0x7F3F,0xEE04,0x4306};
const unsigned int  INIT3[20]={0xEF90,0x0983,0x0800,0x0BAF,0x0A00,0x0500,0x0600,0x0700,0xEF00,0xEE0C,
                        0xEF90,0x0080,0xEFB0,0x4902,0xEF00,0x7F01,0xE181,0xE202,0xE276,0xE183};
const unsigned int  INIT4[3] ={0x8001,0xEF90,0x0000};

 unsigned char cnt;

   RSHi;
   CSHi;
   delay_ms(10);

   RSTLow;
        RSLow;
   delay_ms(15);
   RSTHi;
   CSHi;
   delay_ms(15);
   RSHi;
   delay_ms(15);
   CSLow;
   delay_ms(15);

for (cnt=0; cnt<2; cnt++)
   SPIsend(INIT1[cnt]);
delay_ms(50);

for (cnt=0; cnt<10; cnt++)
   SPIsend(INIT2[cnt]);
delay_ms(7);

for (cnt=0; cnt<20; cnt++)
   SPIsend(INIT3[cnt]);
delay_ms(50);

for (cnt=0; cnt<3; cnt++)
   SPIsend(INIT4[cnt]);
delay_ms(3);

   CSHi;
}


Заливка
Спойлер

Код: Выделить всё

uint8_t lcd_cmd(uint16_t data)
{
  RSHi;
  CSLow;

  SPI1->DR = data;
  while (!((SPI1->SR)&SPI_SR_RXNE));

  RSLow;
  CSHi;

  return(SPI1->DR);
}

void fill_screen(uint16_t color)
{
  uint16_t i;
 
  lcd_cmd(0xEF90);
  lcd_cmd(0x0500);
  lcd_cmd(0x0600);
  lcd_cmd(0x0700);
 
  for (i = 0; i < DISP_W*DISP_H; i++)
     SPIsend(color);
}


А вот так пытаюсь вывести пиксель:
Спойлер

Код: Выделить всё

void put_pixel(int x, int y,long int color)
 {
     RSHi;
     CSLow;

     SPIsend(0xEF90);
     SPIsend(0x0504);
     SPIsend((0x06<<8)+y);
     SPIsend((0x07<<8)+x);

     RSLow;
     CSHi;

     lcd_dat(color);
 }


В итоге начинается вывод точек из угла дисплея и постепенно заполняются горизонтальные строки. SPI настроен вот так:
Спойлер

Код: Выделить всё

void SPIinit (void)
{
   SPI1->CR1 |= SPI_CR1_MSTR;      

   SPI1->CR1 |= SPI_CR1_DFF;         

   SPI1->CR1 |= SPI_CR1_SSI | SPI_CR1_SSM;

   SPI1->CR1 |= SPI_CR1_SPE;       
}


Что я делаю неправильно?

P.S.
На AVR дисплей работал нормально.

Re: Дисплей LS020 + STM32, отказывается работать

Добавлено: Ср май 01, 2013 19:01:43
jordan
в AVR spi наверное программно был организован? я помню у меня тоже была подобная ерунда, я сейчас не за своим компьютером, код не могу посмотреть, но помню что у меня тоже на avr работало нормально а на stm32 были проблемы...

Поставте в lcd_cmd перед ретерном небольшую задержку, буквально в 100-200 тактов, если у вас stm32VL это наверное stm32 discoverу, там у вас наверное частота генератор 24MHz? настройте spi что б его частота была не больше 8Mhz, это на верняка у меня с этим дисплеем spi работал на 10 легко, а на 12MHz уже по мойму выделывался, короче 8 мегагерц будет наверняка...

я не могу сейчас полностью проверить код, но помню что без задержки в командах к дисплею на больших скоростях он работать нормально отказывался!

Re: Дисплей LS020 + STM32, отказывается работать

Добавлено: Ср май 01, 2013 19:46:20
КАШАК
Поставил предделитель частоты 4, добавил задержки. Но ничего не изменилось, только заливка медленнее стала...

P.S.
На AVR SPI аппаратный был.

Re: Дисплей LS020 + STM32, отказывается работать

Добавлено: Ср май 01, 2013 21:43:23
jordan
а заливка правильным цветом идет? таким же как и на avr

и вообще я не понимаю если на avr аппаратный был то скорости примерно такая же была, - портируйте код на stm без изменений, ну изменение только в периферии...

и посмотрите у вас где филскрин там 4 команды на выставление окна заливки!!! - все правельно!!! а на выбор пикселя эти команды где???
вы вместо команды там отсылаете данные!!! это наверное и ошибка !!!

Re: Дисплей LS020 + STM32, отказывается работать

Добавлено: Чт май 02, 2013 01:22:56
КАШАК
Цвет выводит правильный. Ну значит так. Оказывается, дисплей вообще не реагирует на отправку команд lcd_cmd(); Например, если из функции fill_screen(); убрать

Код: Выделить всё

  lcd_cmd(0xEF90);
  lcd_cmd(0x0500);
  lcd_cmd(0x0600);
  lcd_cmd(0x0700);


то ничего не меняется, заливка все так же работает. Соответственно не срабатывают команды выбора окна, поэтому и не работает все остальное. Перешел на 8-битный режим, полностью скопировал код с рабочей библиотеки для AVR, включая инициализацию, но эффект нулевой. Вот эта функция вывода прямоугольника тоже не работает, хотя на AVR все нормально:

Код: Выделить всё

void lcd_set_window(char x1, char y1, char x2, char y2)
{
   lcd_cmd16(0xEF90);
   lcd_cmd16(0x0500); // Set Direction
   lcd_cmd16(0x0A00+x1);
   lcd_cmd16(0x0B00+x2);
   lcd_cmd16(0x0800+y1);
   lcd_cmd16(0x0900+y2);
}

void lcd_rectangle(char x1, char y1, char x2, char y2, uint16_t color)
{
  char x, y;

  lcd_set_window(x1, y1, x2, y2);

  for (y=y1; y<=y2; y++)
    for (x=x1; x<=x2; x++)
       lcd_dat16(color);
}


Видимо, функция отправки команд неработоспособна:

Код: Выделить всё

uint8_t lcd_cmd(uint16_t data)
{
  RSHi;
  CSLow;

  SPI1->DR = data;
  while (!((SPI1->SR)&SPI_SR_RXNE));
 
  CSHi;

  for(data = 0; data<150; data++);

  return(SPI1->DR);
}


Что в ней не так? Для AVR была вот такая:

Код: Выделить всё

void ls020_wrcmd8(char cmd)
{
  PORTB |= (1<<RS); //Set RS
  PORTB &= ~(1<<CS); // select LCD
  SPCR = (1<<MSTR)|(1<<SPE);
  SPDR = cmd;
  while ( !(SPSR & (1 << SPIF)));
  PORTB |= (1<<CS); // deselect LCD
}



P.S.
Во всех проектах для ARM есть команда 0xEF90 перед заливкой, рисованием и т.п., а в AVR ее нет. Что она должна делать?

Re: Дисплей LS020 + STM32, отказывается работать

Добавлено: Чт май 02, 2013 06:26:39
radiokot__
Ну видимо если 8 бит SPI то 8бит data и надо отправлять.
А у вас
uint8_t lcd_cmd(uint16_t data).
Соответственно дальше смотреть где косяки.

Re: Дисплей LS020 + STM32, отказывается работать

Добавлено: Чт май 02, 2013 10:23:09
jordan

Код: Выделить всё

void LS020_CMD(unsigned short int comand)
{
   while (!(SPI1->SR & SPI_SR_TXE)); 
                                     
   CS_LOW                           
   RS_HIGH                           
   
   SPI1->DR  = comand;               
   while (!(SPI1->SR & SPI_SR_TXE)); 
   
   for(unsigned int i=0; i<100; i++);
   CS_HIGH                           
   
}


я вот так на stm32f100discovery, если на stm32 вы пользуетесь не библиотечными функциями, то там легко запутаться в регистрах
set bit и reset bit, возьмите светодиодик и поверте работают ли фактически линии RS, ChipSelect и spi проверить не помешало б, spi проверяется просто, соединяете miso и mosi и в дебагере смотрите приходит ли на вход то что вы отправляете...

Re: Дисплей LS020 + STM32, отказывается работать

Добавлено: Чт май 02, 2013 13:56:00
КАШАК
В общем все оказалось предельно просто. Плата STM32 VL Discovery у меня воткнута вот в такую плату:
Изображение

Для подключения периферии выведены PLS линейки. И на выводе PA3 был непропай, а как раз к нему была подключена линия CS. Непропай устранил и дисплей заработал нормально в 16-битном режиме. Даже на максимальной частоте SPI :) Теперь выводится и текст и графические примитивы.
Теперь другой вопрос, как вывести рисунок? Вроде алгоритм должен быть простым:
1) Перегнать картинку в массив цветов пикселей на ПК.
2) Вывести массив на экран попиксельно.

Но размер такого массива будет огромным, 176*132 = 23232 элемента :shock: Может есть какие-то другие способы?

Re: Дисплей LS020 + STM32, отказывается работать

Добавлено: Чт май 02, 2013 14:42:46
jordan
для вывода картинки, вам понадобится формат bmp, это и есть bit map, то есть каждому пикселю отвечает 3 байта R G B... точнее почитайте bmp файла http://c-site.h1.ru/infa/bmp_struct.htm и все станет понятно

есть конечно библиотеки для декодирования jpeg и jpg но они очень громоздки и для начала нужно научится работать с bmp