Как принять поток данных из массива (изображение) по USART?

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Как принять поток данных из массива (изображение) по USART?

Сообщение mr_smit »

С помощью CVAVR создал проект. Включил приём и передачу. ATMega8.

Изображение

Немного поигрался:

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

while (1)
      {
      putchar(getchar());

       } 
Отосланный символ приходит обратно.

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

while (1)
      {
      if (getchar() == 'h'){
       putsf("Hi, I am ATMega8");
       }
      if (getchar() != 'h') {
       putsf("unknown command");
       } 
      };
Тоже работает.

Но это только с "единичными" символами. Если отослать, например "qw", то МК молчит. Как принимать строки? массив?

Нужно отослать, например, такой массив:

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

flash const unsigned int array[16] = {
0x18A2, 0x1082, 0x1061, 0x841, 0x3124, 0x7288, 0x7247, 0x7288, \
0x7AC9, 0x82E9, 0x82C9, 0x7AA8, 0x7A87, 0x7226, 0x51E5, 0x6A06, \
};
чтобы МК его передал в дисплей S65. Как этот массив принять?

P.S. Причем я так понимаю надо сделать небольшой буфер, как он наполнится отправлять в дисплей. Но вот как получить этот массив???
Нельзя всё знать, достаточно понимать.
Реклама
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Сообщение urry »

так принимать или отпрвлять ??? я не понял

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

typedef union{
struct{
unsigned char lo;
unsigned char hi;
}st;
unsigned int all;
}un;
un un1;
for(i=0;i<16;i++)
{
un1.all=array[i];
putchar(un1.st.lo);
putchar(un1.st.hi);
}
Реклама
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Сообщение mr_smit »

Принять данные от ПК. Потом МК отправляет их в дисплей.

Изображение
Нельзя всё знать, достаточно понимать.
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Сообщение urry »

ну и где затык ?
На компе открываете Ваш файл как бинарник, грузите в массив.Бьете массив на пакеты, закрываете контрольной суммой каждый пакет.
Выгружаете пакет в ком-порт, мк его проверяет и пересылает в дисплей, дальше ждете подтверждение от мк, если у него что-то там не сложилось, повтор пакета, иначе - передача следующего.Байты считаем, закончились - конец обмена.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Сообщение mr_smit »

Как это в коде реализовать не знаю. getchar() принимает по одному символу. Например:

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

// возьмем например размер блока 24
unsigned int image[23];

// i - флаг начала передачи изображения (отправляет ПК)
if (getchar() == 'i'){
  while (getchar() != 'e') {        // конец блока (end)
  принимаем данные в массив
  Как???
  }

когда он заполнен отправляем в дисплей
(или если пришел флаг конца передачи)
} 
Нельзя всё знать, достаточно понимать.
Реклама
HekuToc
Прорезались зубы
Сообщения: 249
Зарегистрирован: Вт ноя 10, 2009 22:37:24
Откуда: Латвия, Рига

Сообщение HekuToc »

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

// возьмем например размер блока 24
unsigned int image[23];

// i - флаг начала передачи изображения (отправляет ПК)
char in;
in=getchar();
if (in == 'i'){
  while (in != 'e') {        // конец блока (end)
  in=getchar();
  image[x]=in; // Lower byte
  in=getchar();
  image[x]+=in*256;//high byte  
  x++;
  }
я интуитивно сделалбы так. Если не прав, поправьте.
Если не трудно, то отвечайте мне названиями буржуйских схем.
Реклама
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Сообщение mr_smit »

Не ругайтесь сильно, пытаюсь разобраться.

В каком формате в этом случае должны идти данные cо стороны ПК?

Например, массив цветов каждого пикселя картинки размером 5х1 (красный,черный,черный,белый,белый) в формате 5-6-5 (готовый для записи в дисплей) выглядит так:
Изображение

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

const unsigned int array[5] = {
0xF800, 0x0000, 0x0000, 0xFFFF, 0xFFFF
};
Чтобы его получить, в Delphi мы с каждым пикселем картинки проделываем следующее:

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

...
// pix - цвет пикселя
// s - строка (string) с цветом в формате hex

r1:=GetRValue(pix) shr 3;
g1:=GetGValue(pix) shr 2;
b1:=GetBValue(pix) shr 3;

pix:= (r1 shl 11) + (g1 shl 5) + b1; // получили цвет
 
// можем перевести его в hex формат
s:=IntToHex(pix,4);
Т.е. для каждой из 5 точек знаем её цвет: F800, 0000, 0000, FFFF, FFFF

И можем его передать. Ну к примеру возьмем блок из 3 цветов. Т.е. 3 цвета получили -> отправили в дисплей, получили оставшиеся 2 -> отправили с дисплей.

В Delphi использую компонент CPortLib.
Для записи в порт у него есть:

Write - Writes non-typed variable to output buffer.
WriteAsync - Writes non-typed variable to output buffer in asynchronous mode.

WriteStr - Writes string type variable to output buffer.
WriteStrAsync - Writes string type variable to output buffer in asnychronous mode.

Т.е. при нажатии кнопки мы можем написать что то типа:
ComPort1.Write(0-ой элем. массива цветов); // F800
ComPort1.Write(1-й элем. массива цветов); // 0000
ComPort1.Write(2-й элем. массива цветов); // 0000
ComPort1.Write(3-й элем. массива цветов); // FFFF
ComPort1.Write(4-й элем. массива цветов); // FFFF

Распознаются ли эти цвета кодом приведенным HekuToc?
Нельзя всё знать, достаточно понимать.
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Сообщение urry »

делфи я не знаю, как бы сделал на си - у Вас каждая точка выдается 2 байтами, выдача через ком порт - неважно, как - делфи, си - побайтовая.
Определяем тип переменной

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

typedef union{
struct{
unsigned red:5; // 5 бит
unsigned green:6;// 6 бит
unsigned blue:5; // 5 бит  
}st; // = 16 бит, 2 байта
unsigned char all[2]; // эти самые байты в массиве
}un;
Делаем массив точек, скажем их 256
un un_arr[256];
выдаем их побайтово
for(i=0;i<256;i++)
{
WriteByte(un_arr[i].all[0]);
WriteByte(un_arr[i].all[1]);
}
на стороне контроллера делаем такой же юнион, но на меньшее количество элементов (по размеру буфера)
По заполнению получаем цвета
green_var=un_arr[i].st.green;
и так далее
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Сообщение mr_smit »

urry писал(а):

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

unsigned char all[2]; // эти самые байты в массиве 
...
WriteByte(un_arr[i].all[0]);
WriteByte(un_arr[i].all[1]);
...
green_var=un_arr[i].st.green;
Не понял эту запись.
Нельзя всё знать, достаточно понимать.
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Сообщение urry »

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

Не понял эту запись. 
юнион - это союз двух переменных, которые занимают одно и то же место в оперативной памяти. Меняешь одну - сразу меняется другая.
Ок, пошли сначала.
Ком -порт выдает только инфу побайтно в любых раскладах, так ?
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Сообщение mr_smit »

Да. Сейчас у delphi программистов на форуме проконсультируюсь насчет правильной отправки.
Нельзя всё знать, достаточно понимать.
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Сообщение mr_smit »

Получается передавать цвет как строку:

Смотрю сниффером com порта.
Один пиксел, красный:
Изображение

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

ComPort1.WriteStr(IntToStr(pix));
Если отправить 3 цвета подряд, то получаем: 63488201631

63488 = F800 = 1111100000000000 = красный
2016 = 07E0 = 0000011111100000 = зеленый
31 = 001F = 0000000000011111 = синий

Эту строчку можно распознать на стороне МК?
Нельзя всё знать, достаточно понимать.
HekuToc
Прорезались зубы
Сообщения: 249
Зарегистрирован: Вт ноя 10, 2009 22:37:24
Откуда: Латвия, Рига

Сообщение HekuToc »

mr_smit, ты не мог бы поделится Delphi исходничком? а то вторй день копаю делфи не могу норм. либу найти.
Если не трудно, то отвечайте мне названиями буржуйских схем.
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Сообщение urry »

mr_smit писал(а):
63488 = F800 = 1111100000000000 = красный
2016 = 07E0 = 0000011111100000 = зеленый
31 = 001F = 0000000000011111 = синий

Эту строчку можно распознать на стороне МК?
ну я же писал...

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

char green.blue,red;
union
{
struct{
unsigned char blue:5;
unsigned char green:6;
unsigned char red:5;
}st;
unsigned char all[2];
}un1;
//--------------------------------
un1.all[0]=getchar(); 
un1.all[1]=getchar(); 
green=un1.st.green;
red=un1.st.red;
blue=un1.st.blue;
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Сообщение mr_smit »

mr_smit писал(а): В Delphi использую компонент CPortLib.
http://sourceforge.net/projects/comport/files/

urry, извини, всё равно не понимаю. Как мне потом пришедший цвет пикселя в дисплей отправить?

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

green=un1.st.green;
red=un1.st.red;
blue=un1.st.blue; 
Не понимаю как перейти к виду 0хА800 или 0хEA07 или 0хАВ01 и т.д. чтобы в дисплей отправить.
Нельзя всё знать, достаточно понимать.
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Сообщение urry »

был вопрос - как разделить, хоть непонятно зачем это деление в принципе - тот самый инт, что пришел с уарта, прямо отправляете в дисплей.
Вот выложена библиотека в соседней ветке
http://radiokot.ru/forum/viewtopic.php?t=17721&start=0
- видимо, я не понимаю вопроса :(
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Сообщение mr_smit »

Как отправить я знаю, я не понимаю ЧТО отправить???

Ну вот к примеру, заливаем дисплей одним цветом:

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

// заливка дисплея цветом color
void fill_screen(unsigned int color)
{
 
  CS= 0;  // select display
 
  lcd_reg(0x16);lcd_dat(0x8300);
  lcd_reg(0x17);lcd_dat(0xAF00);
  lcd_reg(0x21);lcd_dat(0x0000);
  lcd_reg(0x22);lcd_write8(0x76); 
 
  // start data transmission 
  for (i=0; i<DISP_H; i++)
  {
   for(j=0;j<DISP_W;j++)
   {
    lcd_write(color);
   }
  } 

  CS= 1;  // deselect display   
} 
т.е в цикле отправляем цвет, ну в общем понятно.

fill_screen (0х0000);

Как мне полученный цвет записать вместо 0х0000 ???
Нельзя всё знать, достаточно понимать.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18673
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

mr_smit писал(а):Как отправить я знаю, я не понимаю ЧТО отправить???

fill_screen (0х0000);

Как мне полученный цвет записать вместо 0х0000 ???
элементарно, ватсон! модифицируете ранее предложенный код так:

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

union { 
   struct{ 
      unsigned char blue:5; 
      unsigned char green:6; 
      unsigned char red:5; 
   }st; 
   unsigned char all[2]; 
   unsigned int color; // вот эта самая модификация
}un1; 
//-------------------------------- 
un1.all[0]=getchar(); // первый байт цвета принимаем 
un1.all[1]=getchar(); // второй байт цвета принимаем

fill_screen(un1.color); // отправляем на заливку цветом
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Сообщение mr_smit »

Итак, не работает. Точнее не так как надо.

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

...
// Declare your global variables here

union {
      struct{
      unsigned char blue:5;
      unsigned char green:6;
      unsigned char red:5;
      }st;
      unsigned char all[2];
      unsigned int color; // вот эта самая модификация
      }un1;

...
// заливка дисплея цветом color
void fill_screen (unsigned int color)
{
  int i;  
  for (i=0; i<132*176; i++)
  WRDATA(color);
}

void main(void)
{
...

LCD_init();
fill_screen(0xFFFF); 

// Global enable interrupts
#asm("sei")

while (1)
      {
      un1.all[0]=getchar(); // первый байт цвета принимаем
      un1.all[1]=getchar(); // второй байт цвета принимаем 
     
      fill_screen(un1.color); // отправляем на заливку цветом
      };
}
При отправке красного цвета, дисплей заливается сначала светло-синим, потом синим, т.е. как бы 2 раза. Снифер фиксирует 63488.

Вот прикладываю видео, смотрите, выложил на ютуб: http://www.youtube.com/watch?v=tRCStwB8EUY

Видео с комментариями.

Или можете скачать посмотреть, снимал на телефон (mp4):
http://ifolder.ru/16431552
http://narod.ru/disk/17946441000/15022010036.mp4.html
Нельзя всё знать, достаточно понимать.
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Сообщение urry »

Cуществует big-endian и litl-endian формат представления чисел - в числе инт 1 байт старший. а второй младший, или наоборот. Зависит от компилятора. Просто поменяйте байты местами, т.е

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

union {
      unsigned char all[2];
      unsigned int color; // вот эта самая модификация
      }un1; 

while (1)
      {
      un1.all[1]=getchar(); // первый байт цвета принимаем
      un1.all[0]=getchar(); // второй байт цвета принимаем 
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»