Ярлыки

_GetPixelIndex (1) _SetPixelIndex (1) 3-phase (1) 800x480 (1) АЦП (1) генератор (1) синхронный усилитель (2) структура (1) учебный курс (1) шаговый двигатель (1) ШИМ (2) accert (1) AD7608 (1) AD8429 (1) ADC (5) amplifer (1) arccos (1) arcsin (1) arctang (2) arctg (3) ARM (2) arm_sqrt_q15 (2) assembler (6) ASSERT (1) atan (2) bit (1) Bitband (1) boot (3) bootlloader (1) BUTTON (1) C (5) C# (1) CAN (2) CC2530 (5) CMSIS (4) command (1) Cordic (1) Core746I (1) CubeMX (4) DBGMCU (2) debug (2) debug.ini (1) delegate (1) Digital Potentiometers (1) DigitalPOT (1) Discovery (1) DMA (9) DMA2D (1) DSP (1) DSP library (1) DWT (1) EFM32 (5) EmWin (9) EXTI (1) FATFS (1) FMC (2) FreeRTOS (2) gl868-dual cmux (1) GPIO (4) GUI (2) GUIBuilder (1) GUIDRV_CompactColor_16 (1) HAL (3) HappyGecko (1) Hard Fault (2) heap (1) I2C (1) ID (1) ILI9320 (1) ILI9325 (1) Initialisation (1) InitLTDC (1) Instrumentithion (1) Interrupt (4) ITR (1) JTAG (1) Keil (5) LCDConf (2) lock-in (1) LTCD (1) LTDC (3) main (1) memory (1) MINI_STM32 Revision 01 (1) nBoot0 (1) NVIC (1) OnePulse (2) OSAL (4) pack (1) phase (1) printf (3) Pulse (1) PWM (12) RCC (2) RCR (1) Register (1) RESET (2) RS232 (3) RSS (1) RTC (3) RTOS-RTX (1) RTT (1) RTX-RTOS (1) SDCard (1) SDRAM (6) Segger (2) SPI (3) sqrt (3) SSD1298 (1) SSD1963 (1) Standart Peripherial Library (3) STANDBAY (1) startup (1) STemWin (8) stepper motor (1) STlink (2) STM32 (17) STM32429ZI (1) STM32Cube (1) STM32DBG.IN (1) STM32F (28) STM32F0 (4) STM32F1 (13) STM32F4 (10) STM32F4 Discovery (1) STM32F407ZG (1) STM32F429 (2) STM32F746 (1) STOP (1) string (1) struct (1) SWD (1) SWD JTAG (1) Synhronization (1) system_stm32f4xx.c (1) SystemInit (1) SysTick (1) task (4) telit (1) TIM (27) typedef (1) UART (1) USART (9) viewer (2) WM_PAINT (1) Z-stack (5) ZigBee (5)

суббота, 29 ноября 2014 г.

STM32 SERIAL COMMUNICATION





void usartSetup (void) {
  // make sure the relevant pins are appropriately set up.
  RCC_APB2ENR |= RCC_APB2ENR_IOPAEN;              // enable clock for GPIOA
  GPIOA_CRH   |= (0x0BUL  < < 4);                  // Tx (PA9) alt. out push-pull
  GPIOA_CRH   |= (0x04UL  << 8);                  // Rx (PA10) in floating
  RCC_APB2ENR |= RCC_APB2ENR_USART1EN;            // enable clock for USART1
  USART1_BRR  = 64000000L/115200L;                // set baudrate
  USART1_CR1 |= (USART1_CR1_RE | USART1_CR1_TE);  // RX, TX enable
  USART1_CR1 |= USART1_CR1_UE;                    // USART enable
  }

int SendChar (int ch)  {
  while (!(USART1_SR & USART1_SR_TXE));
  USART1_DR = (ch & 0xFF);
  return (ch);
}

int GetChar (void)  {
  while (!(USART1_SR & USART1_SR_RXNE));
  return ((int)(USART1_DR & 0xFF));


void UART_init(void)
{
// USART3 init
        RCC->APB1ENR |= RCC_APB1ENR_USART3EN; // такты на USART3

        GPIOB->CRH &= (~(GPIO_CRH_CNF10_0)); //Настройка порта передатчика
        GPIOB->CRH |= (GPIO_CRH_MODE10 | GPIO_CRH_CNF10_1); // AF Push-Pull out (TX)
//      GPIOB->CRH &= (~(GPIO_CRH_CNF11)); // Настройка порта приемника
//      GPIOB->CRH &= (~(GPIO_CRH_MODE11));
//      GPIOB->CRH |= (GPIO_CRH_CNF11_1); 
//      GPIOB->BSRR |= GPIO_ODR_ODR11;  // Input Pull-up  (RX)
        
        USART3->CR1 |= USART_CR1_UE; // Разрешить USART3
        USART3->BRR = 0x0271; // 57600 baud
        USART3->CR1 |= USART_CR1_TE; //Разрешить передатчик
}
Передача байта:


        while ((USART3->SR & USART_SR_TXE) != USART_SR_TXE);
        USART3->DR = 'D';


void setup()

{

     RCC_APB2ENRbits.IOPAEN = 1;            //Enable GPIOA

     RCC_APB2ENRbits.USART1EN = 1;       //Enable USART1

     GPIOA_CRH = 0x4A0;                                //Set PA9 and PA10 as AFIO pins

     USART1_BRR = 0×341;                               //Set value for required baud rate

     USART1_CR1bits.UE = 1;                          //Set USART1

     USART1_CR1bits.RE = 1;                           //Set USART1 RX to receive incoming data

     USART1_CR1bits.TE = 1;                           //Set USART1 TX to send data

}

 unsigned char USART1_receive()                      

{

     while(USART1_SRbits.RXNE == 0);                       //wait until data is available for reading

     return (0xFF & USART1_DR);                                  //return read data

}



void USART1_send(unsigned char value)

{

     USART1_DR = value;                                                  //transfer data to DR register

     while(USART1_SRbits.TXE == 0);                          //wait until data transmission is complete

}    

SysTick

Для обработчика системного исключения таймера SysTick заголовок функции-обработчика будет выглядеть так:

void SysTick_Handler(void)

Для обеспечения корректной работы обработчика необходимо , как минимум, назначить системному исключению приоритет и сбросить его в неактивное состояние после обработки (т.е., всё так же, как и у обычного прерывания). Но приоритеты системных исключений назначаются не в регистрах NVIC, а в регистрах системного блока управления (System control block), которые называются SHPR1 — SHPR3 (для разнообразия, они нумеруются, начиная с 1, а не с 0, т.е. регистра SHPR0 не существует). Приоритет системного исключения SysTick задаётся в регистре SHPR3, в битах [31:24]. Адрес регистра SHPR3 равен 0xE000ED20, и мы можем записать:

unsigned long  * pSHPR3 = (unsigned long *)0xE000ED20;
 
* pSHPR3 = SYS_TICK_PRIORITY &lt;&lt; 24;

Сброс прерывания SysTick в неактивное состояние осуществляется с помощью регистра ICSR того же системного блока управления.

Обработчик системного исключения SysTick выглядит так:

void SysTick_Handler(void)
{
//тело обработчика
//сброс прерывания
ICSR_bit.PENDSTCLR = 1;
}

И, в заключение, ещё одна особенность, на этот раз связанная с обработкой прерывания Repetitive Interrupt Handler. У этого прерывания сброс в неактивное состояние нужно выполнять так:

RICTRL_bit.RITINT = 1;

Здесь RICTRL — регистр управления самого таймера RIT. Сброс прерывания в контроллере NVIC выполнится при этом автоматически.



В Cortex-M перечень (имен)функций обработчиков прерывания можно найти в startup.S. Эти функции имеют атрибут weak - "слабый", и вместо тел функций обработчиков проложены заглушки. Для задействования своего обработчика достаточно написать в любом *.c файле, включенном в проект, своей функции с тем же именем - компилятор зацепит её - она без атрибута weak. В Cortex-M завсегда есть в ядре SysTick таймер. Для его использования нужно выполнить SysTick_Config() и написать свой обработчик SysTick_Handler.


unsigned long SysTickCounter;
void SysTick_Handler(void){
  SysTickCounter++;
  // здесь, например, вставляем свои таймерные прибамбахи типо индикации
}
unsigned long clock(void){
  return SysTickCounter;
}
unsigned long clock_Elapsed(unsigned long start){
  return clock() - start; //вычитание беззнаковых - если clock() < start, результат в эквиваленте даст clock() + ~0UL -
start, т.е. start - clock()
}
int main(void){
    SystemCoreClockUpdate();//в STM32 при работе от кварца значение SystemCoreClock пересчитывается из константы HSE_Value
    SysTick_Config(SystemCoreClock/1000);//1 ms; для 100 мкс SystemCoreClock/10000, для 10 мс - SystemCoreClock/100

    ...
    unsigned long ts;
    do{
        ts = clock();
        LED_toggle();//тут придётся потрудиться:) написать мигалку
        while(clock_Elapsed(ts) < 100){//delay 100 ms
          ;//здесь тоже можно заняться чем-то полезным
        }
    }while(1);
   
}



вторник, 25 ноября 2014 г.

Synchronous Detectors Facilitate Precision, Low-Level Measurements (Повышение точности измерения слабых сигналов с помощью синхронного детектирования)

  Применение синхронных детекторов позволяет измерять очень слабые сигналы на фоне высокого уровня шумов, смешанных с сигналом. Данная методика широко применяется например при измерении очень малых сопротивления, оптических исследованиях спектров отражения или поглощения.
  Во многих системах происходит увеличение шумовых помех в области низких частот. Например операционные усилители имеют в области низких частот 1/f шум, а при оптических измерениях похожий эффект дает паразитная подсветка .
  Перенос измерений из диапазона частот с большими низкочастотными шума увеличивает отношение сигнал-шум, что позволяет измерить более слабые сигналы. Например, модуляция источника света частотой в несколько килогерц позволяет измерять отраженный свет, который без нее полностью теряется на уровне шумов. Рисунок 1 иллюстрирует, как модуляция обеспечивает восстановление сигнала, который изначально был ниже уровня шумов.


Рис.1 Модуляция сигнала перемещает его подальше от источников шума.

  Существуют различные методы модуляции измеряемого сигнала. Самый простой способ - это его периодическое прерывание. Это хорошо работает для управления питанием светодиодами, или тензометрических мостов, и другие виды возбуждения. С лампами накаливания в спектроскопии или других источников возбуждения, которые не могут быть легко включается и выключается, модуляция может быть достигнуто прерывание света  механическим затвором.
  Узкий полосовой фильтр позволяет восстановить исходный сигнал, но проектирование и создание необходимого фильтра из дискретных компонентов непростая задача. Синхронный детектор (lock-in amplifier) позволяет восстановить постоянную составляющюю измеряемого модулированного сигнала, убрав помехи с частотой отличной от частоты модуляции.
  Рисунок 2 иллюстирует метод синхронного усиления..Источник света, освещающий образец, модулируется частотой 1 кГц. Фотодиод детектирует отраженное от поверхности модулированное излучение. Падающий и отраженный сигналы синусоидальной формы определенную частоту и фазу, но амплитуда отраженного сигнала зависит от оптических свойств измеряемой поверхности.


Рис. 2 . Принцип работы синхронного усилителя.

  В результате умножения двух синусоид (опорного и измеряемого сигналов)  с одинаковой частотой получаем постоянную составляющюю и сигнал удвоенной частоты по отношению к опорной частоте.


  Отрицательный знак говорит о сдвиге фазы на 180 градусов. Фильтр низких чатот на выходе выделяет постоянную составляющюю исходного сигнала. При использовании синхронного усиления на выходе умножителя появляются так же шумовые помехи от различных паразитных источников помех (например от вездесущей "наводки" в 50 Гц). 


Рис. 3. Пики от паразитных помех 50 Гц и 2,5  кГц при модулирующем сигнале 1 кГц.

  Чтобы убрать шумовые и паразитные помехи в сигнале на частотах, близким к нулю необходимо, необходимо выбирать частоту модуляции, которая не имеет рядом источников сильных помех. Если это невозможно, то приходится применять фильтры низких частот с крутой передаточной характеристикой и низкой частотой среза, которые имеют большле постоянные времени.
  Для упрощения вместо синусоидального модулирующего сигнала используют прямоугольный, который без проблем генерируется микроконтроллером, управляющим электронным ключем. Рисунок 4 иллюстрирует синхронный усилитель с прямоугольными импульсами модуляции.


Рис. 4. Синхронный усилитель с прямоугольными модулирующими импульсами.

  Модулирующий сигнал поступает одновременно на датчик и на аналоговый ключ ADG619. При положительном модулирующем сигнале коэффициент передачи усилителя  +1, а при отрицательном  -1. Это математически - перемножение модулирующего сигнала и сигнала от датчика. Выходной RC-фильтр убирает модулирующюю частоту (а заодно и шумовые) и на его выходе получим постоянный сигнах величиной в половину амплитуды от пика ло пика измеряемого  модулированного сигнела датчика. Хотя схема довольно проста, правильный подбор ОУ имеет важное значение. Входной каскад по переменному току удаляет большую часть входныхо низкочастотных шумов,  но не будет удалять шум 1 / F и погрешность смещения от последнего усилителя.ADA4077-1. Это прецезионный усилитель (250 нВ от 0,1 Гц до 10 Гц с дрейфом смещения 0,55 мкВ / ° C).
  Синхронный усилитель с прямоугольными модулирующими сигналами довольно прост в исполнении, но подавление шумов в нем хуже, чем в синхронных усилителях, использующих модуляцию синусоидальным сигналом. Рисунок 5 показывает частотный спектр модулирующего и измеряемого сигналов. Этот спектр представлен в виде нечетных гармоник.


Рис. 5. Результат умножения (С) входного (А) и модулирующего (В) сигналов.

  В результате перемножения двух прямоугольных сигналов одинаковой частоты получаем постоянную составляющую, величина которой равна сумме амплитуд всех гармонических составляющих спектра. Нежелательные нечетные гармоник, амплитуда которых падает при увеличении частоты не будут отфильтрованы. Поэтому очень важно выбрать частоту модуляции не совпадаюцюю с частотами или их гармониками любых источников помех.Например выбрав частоту модулячции 1,0375 кГц мы избавимся от сетевых помех с частотами 50 или 60 Гц, а при выборе частоты модуляции 1 кГц будет возникать помеха от  20-й гармоники сетевой частоты 50 Гц. 

  Устойство, показанное на рисунке 4 состоит из операционного усилителя, аналогового коммутатора, импульсы коммутации подаются от микроконтроллера. В качестве альтернативы 
ему можно использовать интегральный синхронный демодулятор, изображенный ниже. 


Рис. 6. Блок-диаграмма ADA2200.

  ADA2200 состоит из входного буферного усилителя, фильтра НЧ,фильтра с бесконечной импульсной характеристикой (БИХ-фильтр), умножителя и блока сдвига фазы опорного сигнала на 90 градусов который позволяет измерить или скомпенсировать сдвиг фаз между измеряемым и опорным сигналом. Для реализации синхронного детектора на ADA2200 необходим генератор тактовой частоты котоая в 64 раза больше частоты модулирующего сигнала, как показано на рисунке 7.


Рис. 7. Синхронный детектор на основе ADA2200.

  Конфигурация цифрового полосового фильтра выбирается таким образом, чтобы устранить необходимость использования двух сигалов - измеряемого и модулирующего. На выходе семплированного сигнала присутствуют составляющие с частотой дискретизации и кратными гармониками, которые после высокочастотной RC фильтрации гасятся и выходной  Σ-∆ АЦП измеряет только постоянную составляющюю демодулированного сигнала. 
  Рисунок 8 иллюстрирует как можно улучшить синхронный детектор с прямоугольными импульсами модуляции. 


Рис. 8. Использование синусоидального модулирующего сигнала для уменьшения
шумов при демодуляции.

   Используя для модуляции прямоугольный сигнал мы будем использовать для перемножения с измеряемым сигналом не прямоугольный, а синусоидальный сигнал с той же частотой.  В этом случае постоянная составляющяя будет равна амплитуде сигнала с частотой модуляции, а появляющиеся гармоники можно убрать НЧ фильтром. 
  Еще одной из проблем являетя сдвиге фаз между модулирующим  и измеряемым сигналом. Он может возникать в цепях аналоговой обработки (усиления, фильтрации) измеряемого сигнала. Это приводит к уменьшению измеряемого сигнала. В синхронном детекторе единственный метод борьбы с этим фазовая компенсация модулирующего сигнала. Это достаточно сложная задача, так как вводимая фазовая задержка долнжа быть регулируемой и подстраиваемой. Простой альтернативой является добавление второго этапа, на котором измеряемый сигнал перемножается с модулирующим сигналом сдвинутым на 90 градусов. В результате мы получаем на выходе фазонезависимый сигнал как показано на рисунке 9.


Рис. 9. Использование квадратурной составляющей модулирующего сигнала для
определения амплитуды и фазы.

   На выыходе двух перемножителей после НЧ фильтров получаем фазовую (I) и квадратурную (Q) компоненты входного сигнала.Откуда легко определить амплитуду измеряемого сигнала и заодно фазовый сдвиг между модулирующим и измеряемым сигналом.  В рассмотренных выше синхронных детекторах модулирующий сигнал используется для воздействия на измеряемый образец. Например на рисунке 10 показана схема измерения оптических свойств образца. Для модуляции излученя широкополосной лампы накаливания используется механический диск в качестве модулитора излучения. Он же исполузуется для генерации прямоугольных импульсов в оптопаре, используемых в качестве модулирующих импульсов в синхронном детекторе. Далее вместо того, чтобы использовать прямоугольный модулирующий сигнал от оптопары непосредственно, он подается на систему ФАПЧ (PLL), которая генерирует модулирующий сигнал синусоидальной формы с той же частотой и фазой. Отметим, что генерируемая синусоида должна иметь как можно меньший уровень искажений.


Рис. 10. Использование ФАПЧ для генерации модулирующих сигналов.


  


среда, 19 ноября 2014 г.

TIM (таймеры STM32F)

В STM32F по умолчанию периферия продолжает "тикать" в реальном времени, пока происходит останов под отладчиком или пошаговые прохождения по программе. Чтобы остановить периферию (в твоем случае - Таймер), необходимо установить при инициализации системы нужный бит в узле отладки, что можно сделать либо библиотечной функцией:


DBGMCU_Config (DBGMCU_TIM3_STOP, ENABLE);  // stop timer3 while debugging

либо на "регистровом" уровне программирования:


DBGMCU->CR |= DBGMCU_TIM3_STOP;

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

воскресенье, 28 сентября 2014 г.

arctg

Разложение в ряд Маклорена:

y = arctg(x) = x - x^3/3 + x^5/5 - ...               |x| < 1

arctg(1/x) = 1/x - (1/2)x+ (1/5)x5 - .

tan(x) = x/(1-x^2/(3-x^2/(5-x^2/(7-x^2/...))))

Пусть max - больший катет, а min - меньший. Тогда длина гипотенузы приблизительно равна
max + min*min/(2*max)
Её максимальная относительная ошибка равна: 1 - sqrt(2)/1.5 ~ 0.057
А если взять формулу:
max + 0.43*min*min/max, то максимальная относительная ошибка будет ~ 0.01
Если же хочется сделать вычисления проще, то можно взять формулу:
max + 0.41*min, но ошибка будет 0.075
Коэффициенты  подобраны экспериментально с точность 0.01. Можно подобрать точнее.

Еще один пример ряда для x < 1;



Еще одна эмпирически подобранная формула:


//formula  y = -0.30097 + 0.61955*x - 0.001659*x*x
//x :number from 0..100%
//y : angle from 0..45° as approximation of the atan function.
int32_t arctang(int32_t Re, int32_t Im)
{
int32_t a,b,proc,arctg;
proc=a*100.0/b;
//proc_int=a*100/b;
arctg=(-300970 + 619550*proc - 1659*proc*proc)/1000000;
return arctg;

}

Для вычисления арктангенса можно использовать следующий алгоритм:
Вначале проверить знак x, изменить знак, сделав аргумент неотрицательным. Затем если x>1, обратить его: x1=1/x. Затем сокращаем область определения, используя формулу:

atan(x)=pi/6+atan((x*sqrt(3)-1)/(x+sqrt(3))).

Здесь sqrt(3) квадратный корень из 3. При этом необходимо запомнить число шагов (возможно, ноль). После этого, арктангенс на интервале [0,pi/12] аппроксимируется формулой (для single precision, в случае double формула должна быть улучшена!):

atan(x) = x*(0.55913709/(1.4087812+x2) +0.60310579-0.05160454*x2)

Затем к полученному результату добавляется столько pi/6, сколько было шагов сокращения области определения. Затем, в случае обращения, аргумента, результат вычитается из pi/2. Затем, если была смена знака, у результата меняем знак. Для повышенной точности, формулу на участке [0,pi/12] следует брать в виде:

atan(x) = x*(m0+n0*(x*x)+k0/(m1+n1*(x*x)+k1/(m2+n2*(x*x)+k2/(...)))),

то есть в том же виде цепной дроби, как и для single precision, только с некоторыми другими значениями m0,n0,k0;m1,n1,k1;... 

#define M_PI ((float)3.141592653589793)
#define M_PI12 (M_PI/12.F)
#define M_PI6 (M_PI/6.F)
#define M_PI2 (M_PI/2.F)
/* square root of 3 */
#define SQRT3 ((float)1.732050807569)

float Arctan(float x) {
  int sta=0,sp=0;
  float x2,a;
  /* check up the sign change */
  if(x<0.F) {x=-x;sta|=1;}
  /* check up the invertation */
  if(x>1.F) {x=1.F/x;sta|=2;}
  /* process shrinking the domain until x<PI/12 */
  while(x>M_PI12) {
    sp++; a=x+SQRT3; a=1.F/a; x*=SQRT3; x-=1.F; x*=a;
  }
  /* calculation core */
  x2=x*x; a=x2+1.4087812F; a=0.55913709F/a; a+=0.60310579F;
  a-=0.05160454F*x2; a*=x;
  /* process until sp=0 */
  while(sp>0) {a+=M_PI6;sp--;}
  /* invertation took place */
  if(sta&2) a=M_PI2-a;
  /* sign change took place */
  if(sta&1) a=-a;
  return(a);
}

воскресенье, 21 сентября 2014 г.

суббота, 13 сентября 2014 г.

MINI_STM32 Revision 01


для записи в шину контроллера дисплея дергаются порты:
Set_nWr;
Set_Rs; 
GPIOC->ODR = (GPIOC->ODR&0xff00)|(data&0x00ff);
GPIOB->ODR = (GPIOB->ODR&0x00ff)|(data&0xff00);
Clr_nWr;
Set_nWr;
Set_Cs;

a через FSMC одна команда:
*(__IO uint16_t *) (Bank1_LCD_D)= data;

STemWin для STM32F10x и ILI9320, ILI9325

STemWin поставляется с примерами для различных макетных плат ST, но без драйверов для дисплеев. В её состав входит только шаблон драйвера GUIDRV_Template.c в самом конце которого находится структура API

const GUI_DEVICE_API GUIDRV_Template_API = {
  //
  // Data
  //
  DEVICE_CLASS_DRIVER,
  //
  // Drawing functions
  //
  _DrawBitmap,
  _DrawHLine,
  _DrawVLine,
  _FillRect,
  _GetPixelIndex,
  _SetPixelIndex,
  _XorPixel,
  //
  // Set origin
  //
  _SetOrg,
  //
  // Request information
  //
  _GetDevFunc,
  _GetDevProp,
  _GetDevData,
  _GetRect,
};

Из документации можно выяснить, что из всех функций нам необходимо адаптировать под наш дисплей только  _GetPixelIndex и  _SetPixelIndex. В функцию _SetPixelIndex нам необходимо вставить процедуру установки пиксель для нашего дисплея в месте которое нам предусмотрительно оставлено

    GUI_USE_PARA(pDevice);
    GUI_USE_PARA(x);
    GUI_USE_PARA(y);
    GUI_USE_PARA(PixelIndex);
    {
      //
      // Write into hardware ... Adapt to your system
      //
      // TBD by customer...
      //
    }

  //if ( (x>240)||(y>320) ) return;
  //LCD_WR_CMD(0,0x02,x);
  //LCD_WR_CMD(1,0x03,y);  
  
  LCD_WR_CMD(32, y);
  LCD_WR_CMD(33, 319-x);
  //*(__IO uint16_t *) (Bank1_LCD_C)= 34;
  LCD_WR_REG(34);

  //LCD_WR_CMD(0,0x02,y);
  //LCD_WR_CMD(1,0x03,319-x);  
  //LCD_WR_REG(0x0E); 
  LCD_WR_Data(point);  

Для _GetPixelIndex необходимо вставить

  u16 temp;
  ili9320_SetCursor(x,y);
  LCD_WR_REG(34);
  //temp = ili9320_ReadData(); //dummy
  //temp = ili9320_ReadData();

  //  return (ili9320_BGR2RGB(ili9320_ReadData()));
  return (ili9320_ReadData());

Для того, чтобы emWin использовала этот модифицированный драйвер необходимо в файле  LCDConf.c  в процедуре LCD_X_Config вставить

//
// Physical display size
//
#define XSIZE_PHYS  240
#define YSIZE_PHYS  400
....
void LCD_X_Config(void)
{
    ....
    pDevice = GUI_DEVICE_CreateAndLink(GUIDRV_Template_API, GUICC_565, 0, 0);
    ....
}
....
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData)
{
    ....
    switch (Cmd)
    {
        case LCD_X_INITCONTROLLER:
        {
            lcdInit();
            return 0;
        }
        ....
    }
    ....
}




четверг, 4 сентября 2014 г.

emWin Display Driver GUIDRV_CompactColor_16


    Данный драйвер поддерживает следующие типы дисплеев

  • Ampire FSA506
  • Epson S1D13742, S1D13743, S1D19122
  • FocalTech FT1509Himax HX8301, HX8312A, HX8325A, HX8340, HX8347, HX8352,HX8352B, HX8353
  • Hitachi HD66766, HD66772, HD66789
  • Ilitek ILI9161, ILI9220, ILI9221, ILI9320, ILI9325, ILI9326, ILI9328, ILI9342
  • LG Electronics LGDP4531, LGDP4551
  • MagnaChip D54E4PA7551
  • Novatek NT39122, NT7573
  • OriseTech SPFD5408, SPFD54124C, SPFD5414D, SPFD5420A
  • Renesas R61505, R61509, R61516, R61526, R61580, R63401
  • Samsung S6D0110A, S6D0117, S6D0128, S6D0129, S6D04H0
  • Sharp LCY-A06003, LR38825
  • Sitronix ST7628, ST7637, ST7687, ST7712, ST7715, ST7735, ST7787, ST7789
  • Solomon SSD1284, SSD1289, SSD1298, SSD1355, SSD1961, SSD1963, SSD2119
  • Toshiba JBT6K71
    Поддерживаемая глубина цвета - 16 бит.
    Драйвер поддерживает 8-ми и 16-ти битный параллельный интерфейс, а также SPI для 3-х линий управления. По умолчанию настроен на параллельный 8-ми битовый интерфейс.

To be able to use this driver the following macro definition needs to be added to the configuration file 

Для использования данного драйвера необходимо добавить макроопределение в файл LCDConf.h:



#define LCD_USE_COMPACT_COLOR_16

    После этого макроопределения в конфигурационном файле LCDConf_CompactColor_16.h добавляется строка:

GUI_DEVICE_CreateAndLink(GUIDRV_COMPACT_COLOR_16, GUICC_565, 0, 0);


    Драйвер может использоваться с дисплейным кешем в RAM или без него. Общее количество памяти для кэша

LCD_XSIZE * LCD_YSIZE * 2 bytes    (для дисплеев 320Х240Х2=153600)

        Конфигурационные макроопределения

    To select the desired controller the macro LCD_CONTROLLER should be used in the configuration file LCDConf_CompactColor_16.h. The following table shows the values to be used to select the appropriate controller:
    В файле  LCDConf_CompactColor_16.h задается макроопределение LCD_CONTROLLER определяющее тип контроллера


    Конфигурация дисплея задается макроопределениями

LCD_MIRROR_X Activate to mirror X-axis.
LCD_MIRROR_Y Activate to mirror Y-axis.
LCD_SWAP_XY Activate to swap X- and Y-axis.

    Конфигурация оборудования

LCD_NUM_DUMMY_READSNumber of required dummy reads if a read operation should be executed. The default value is 2. If using a serial interface the display controllers HD66766 and HD66772 need 5 dummy reads. Sharp LR38825 needs 3 dummy reads with a 8-bit bus.
LCD_REG01This macro is only required if a Himax HX8312A is used. Unfortunately the register 0x01 (Control register 1) contains orientation specific settings as well as common settings. So this macro should contain the contents of this register.
LCD_SERIAL_IDWith a serial 3 wire interface this macro defines the ID signal of the device ID code. It should be 0 (default) or 1. Please note: This macro is only used with the 3 wire protocol for Hitachi HD66772, Samsung S6D0117, Himax HX8301 and Ilitek ILI9220.
LCD_USE_SERIAL_3PINThis configuration macro has been implemented to support the 3 wire serial interface of the following controllers: Hitachi HD66772, Samsung S6D0117, Himax HX8301, Ilitek ILI9220. Should be set to 1 if the 3 wire serial interface is used. Default is 0.
Please note: Do not use this macro with other display controllers!
LCD_USE_PARALLEL_16Should be set to 1 if the 16 bit parallel interface is used. Default is 0.
LCD_WRITE_BUFFER_SIZEDefines the size of the write buffer. Using a write buffer increases the performance of the driver. If multiple pixels should be written with the same color, the driver first fills the buffer and then writes the contents of the buffer with one execution of the macro LCD_WRITEM_A1, instead of multiple macro executions. The default buffer size is 500 bytes.
LCD_WRITE_A0Write a byte to display controller with RS-line low.
LCD_WRITE_A1Write a byte to display controller with RS-line high.
LCD_READM_A1Read multiple bytes (8 bit parallel interface) or multiple words (16 bit parallel interface) from display controller with RS-line high.
LCD_WRITEM_A1Write multiple bytes (8 bit parallel interface) or multiple words (16 bit parallel interface) to display controller with RS-line high.
LCD_WRITEM_A0Write multiple bytes (8 bit parallel interface) or multiple words (16 bit parallel interface) to display controller with RS-line low.

    Пример кофигурации

LCDConf.h - добавить строку

#define LCD_USE_COMPACT_COLOR_16


LCDConf_CompactColor_16.h - добавить

//
// General configuration of LCD
//
#define LCD_CONTROLLER      66709 // Renesas R61516
#define LCD_BITSPERPIXEL       16
#define LCD_SWAP_RB             1
#define LCD_USE_PARALLEL_16     1
#define LCD_MIRROR_Y            1
//
// Indirect interface configuration
//
void LCD_X_Write01_16 (unsigned short c);
void LCD_X_Write00_16 (unsigned short c);
void LCD_X_WriteM01_16(unsigned short * pData, int NumWords);
void LCD_X_WriteM00_16(unsigned short * pData, int NumWords);
void LCD_X_ReadM01_16 (unsigned short * pData, int NumWords);

#define LCD_WRITE_A1 (Word) LCD_X_Write01_16(Word)
#define LCD_WRITE_A0 (Word) LCD_X_Write00_16(Word)
#define LCD_WRITEM_A1(Word, NumWords) LCD_X_WriteM01_16(Word, NumWords)
#define LCD_WRITEM_A0(Word, NumWords) LCD_X_WriteM00_16(Word, NumWords)
#define LCD_READM_A1 (Word, NumWords) LCD_X_ReadM01_16 (Word, NumWords)

LCDConf.c

void LCD_X_Config(void) {
  //
  // Set display driver and color conversion
  //
  GUI_DEVICE_CreateAndLink(GUIDRV_COMPACT_COLOR_16, // Display driver
                           GUICC_M565,              // Color conversion
                           0, 0);
  //
  // Display driver configuration
  //
  LCD_SetSizeEx(0, 240, 320);                       // Physical display size in pixels
}






понедельник, 1 сентября 2014 г.

emWin Display Drivers

    Драйвер дисплея поддерживает определенные типы контроллеров дисплея. Этот драйвер можно сконфигурировать изменив конфигурационные файлы не изменяя сам драйвер. Эти конфигурационные файлы включают всю необходимую информацию для драйвера, включая алгоритм обращения к контроллеру дисплея и способ его подключения.
    Начиная с версии emWin V5 интерфейс драйвера изменен. Старые драйвера, разработанные для версии ewWin V4 и более ранних больше не поддерживаются. Изменения в интерфейсе драйвера связаны с необходимостью поддержки RTOS.
    Все файлы относящиеся к определенному драйверу именуются однотипно. Например файлы


GUIDRV_IST3088.c

GUIDRV_IST3088.h

GUIDRV_IST3088_4.c

GUIDRV_IST3088_Private.h
GUIDRV_IST3088_X_4.c
относятся к группе файлов для драйвера GUIDRV_IST3088.
    Ниже приводится фрагмент таблицы драйверов для работы без RTOS.
    Полную таблицу можно найти на сайте Segger .

    Сущестуют два основных типа интерфейсов подключения CPU к дисплею

  • прямой интерфейс
  • не прямой интерфейс
    При прямом интерфейсе адресное пространство CPU непосредственно отображается на адресное пространство дисплея.


    При не прямом интерфейсе, который чаще всего применяется для небольших дисплеев возможно несколько вариантов. При использовании параллельной шины данных используется только один разряд шины данных и 8 или 16 разрядов шины данных с 2-мя или 3-мя шинами управления.




    Если контроллер подключен напрямую к адресной шине CPU макрос конфигурации очень простой и состоит из одной строки. При не прямом подключении макрос усложняется до 5-10 строк, эмулирующих шинный интерфейс. Сигнал А0 иногда обозначается как C/D (Command/Data), D/I (Data/Instruction) или RS (Register select). 
    Примеры описания подключения можно найти в папке SampleLCD_X:

LCD_X_6800.c, 6800 parallel interface.
LCD_X_8080.c, 8080 parallel interface.

    Более простой метод подключения 4-х проводной интерфейс SPI


    Пример описания подключения из вышеуказанной папки

LCD_X_SERIAL.c, serial interface

    Еще более простой метод 3-х проводной интерфейс SPI. В этом случае нет специальной шины для выбора режима передачи данные / команда. И для этого используют другие методы, например старший байт используют как признак передачи команды.


    Пример описания подключения

LCD_X_Serial_3Pin.c, 3 pin serial interface
LCD_X_Serial_3Wire.c, 3 pin serial interface

    Ну и напоследок самый простой интерфейс I2C из 2-х шин.


    Пример файла описания подключения

LCD_X_I2CBUS.c, I2C bus interface