реклама на сайте
подробности

 
 
> xMega128a1 + TFT LCD
azure
сообщение Feb 26 2014, 10:09
Сообщение #1





Группа: Участник
Сообщений: 12
Регистрация: 20-03-08
Пользователь №: 36 086



Добрый день. Осваиваю xMega и зациклился на контроллере DMA. Прошу помощи с кодом программы.
Стоит следующая задача: из внешней RAM вывести картинку на LCD TFT, аппаратным путем вывести квадрат или ноль по нужным координатам.
TFT - TM043NBH02 с интерфейсом 24bit RGB.
Какую задачу полагаю на DMA: 1) для нужной строки записываются данные из RAM в массив, после чего некоторые данные массива по необходимости заменяются; 2) DMA отправляет данные на порты МК подключенные к TFT с частотой равной DCLK.
Ниже привожу один из кодов на котором пока остановился:
CODE
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 32000000UL
#include <util/delay.h>
#include "avr_compiler.h"
#include "clksys_driver.h"
#include "TC_driver.h"
#include "pic.h"

#define PORT_R PORTK
#define PORT_G PORTJ
#define PORT_B PORTH

void Port_config(void);

volatile unsigned long data[480];

void InitDMA(void) // Настройка DMA
{
DMA.CTRL = DMA_ENABLE_bm; // Включение DMA
// Настройка на повторяющуюся передачу 2 байтными пакетами в одиночном режиме
DMA.CH0.CTRLA = DMA_CH_SINGLE_bm | DMA_CH_BURSTLEN1_bm | DMA_CH_REPEAT_bm;
// Установка инкрементации адресов после каждой передачи и перезагрузка после пакета
DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD1_bm | DMA_CH_DESTRELOAD1_bm | DMA_CH_SRCDIR0_bm | DMA_CH_DESTDIR0_bm;
// DMA.CH0.TRIGSRC = TC_CLKSEL_EVCH0_gc; // Запуск передачи от
DMA.CH0.TRFCNT=2; // Установка счетчика передачи в 2 байта

DMA.CH0.SRCADDR0 = (int)&data;
DMA.CH0.SRCADDR1 = (int)&data>>8;
DMA.CH0.SRCADDR2 = 0;
DMA.CH0.DESTADDR0 = (int)PORT_G.OUT;
DMA.CH0.DESTADDR1 = (int)PORT_G.OUT>>8;
DMA.CH0.DESTADDR2 = 0;

DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm; // разрешение работы канала 0 DMA

// DMA.CH0.CTRLA |= DMA_CH_TRFREQ_bm; // запуск DMA передачи
}

volatile unsigned int line=0;

//================================================================================
// Main
//================================================================================

int main(void)
{
_delay_ms(5);
Port_config();

CLKSYS_Enable( OSC_RC32MEN_bm ); // Разрешение работы от внутреннего генератора 32 МГц
do {} while ( CLKSYS_IsReady( OSC_RC32MRDY_bm ) == 0 ); // Ждем стабилизации частоты генератора
CLKSYS_AutoCalibration_Enable( OSC_RC32MCREF_bm, false ); // Калибровка внутреннего генератора 32 МГц от внтуреннего 2 МГц
CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_RC32M_gc ); // Выбор генератора 32 МГЦ как основного источника тактирования
CLKSYS_Disable( OSC_RC2MEN_bm | OSC_RC32KEN_bm ); // Disable the 2MHz and 32KHz internal RC oscillators

sei();

// Таймер DCLK : Порт D, ножка 0, ШИМ режим, период 4 такта, пауза 2 такта, тактирование от основной частоты с предделителем 1
PORTD.DIRSET = PIN0_bm;
PORTD.PIN0CTRL = PORT_INVEN_bm;
TCD0.CTRLB = TC0_CCAEN_bm | TC_WGMODE_SS_gc;
TCD0.PER = 4-1;
TCD0.CCA = 2;
TCD0.CTRLA = TC_CLKSEL_DIV1_gc;
EVSYS.CH0MUX = EVSYS_CHMUX_TCD0_OVF_gc; // Событие на 0 канале - переполнение таймера DCLK
//EVSYS.CH2MUX=EVSYS_CHMUX_TCD0_OVF_gc;
// Вызов подпрограммы прерывания по переполнению таймера DCLK (TCD0)
//TCD0.INTCTRLA = TC_OVFINTLVL_LO_gc;
//PMIC.CTRL |= PMIC_LOLVLEN_bm;

// Таймер HSYNC : Порт D, ножка 4, ШИМ режим, период 525 такта, паузка 41 такта, тактирование от события канала 0 (переполнение таймера DCLK)
PORTD.PIN4CTRL = PORT_INVEN_bm;
TCD1.PER = 525-1;
TCD1.CTRLB = TC1_CCAEN_bm | TC_WGMODE_SS_gc;
TCD1.CCA = 41;
TCD1.CTRLA = TC_CLKSEL_EVCH0_gc;
EVSYS.CH1MUX = EVSYS_CHMUX_TCD1_OVF_gc; // Событие на 1 канале - переполнение таймера HSYNC
// Вызов подпрограммы прерывания по переполнению таймера HSYNC (TCD1)
TCD1.INTCTRLA = TC_OVFINTLVL_LO_gc;
PMIC.CTRL |= PMIC_LOLVLEN_bm;

// Таймер VSYNC : Порт E, ножка 0, ШИМ режим, период 286 такта, паузка 10 тактов, тактирование от события канала 1 (переполнение таймера HSYNC)
PORTE.PIN0CTRL = PORT_INVEN_bm;
TCE0.PER = 286-1;
TCE0.CTRLB = TC0_CCAEN_bm | TC_WGMODE_SS_gc;
TCE0.CCA = 10;
TCE0.CTRLA = TC_CLKSEL_EVCH1_gc;

/*
// Таймер 4 - DMA
TCE1.PER = 4-1;
TCE1.CTRLA = 0;
//TCD0.CTRLA = TC_CLKSEL_DIV1_gc;
TCE1.INTCTRLA = TC_OVFINTLVL_LO_gc;
//EVSYS.CH0MUX = EVSYS_CHMUX_TCE1_OVF_gc;*/

PORTD.OUTCLR=PIN3_bm; // DE = 0

PORT_R.OUT=255;
PORT_G.OUT=0;
PORT_B.OUT=0;

InitDMA();

while (1)
{

}

return 0;
}

ISR(TCD0_OVF_vect)
{}

ISR(TCD1_OVF_vect)
{
// Для n-ной строки задается массив для вывода и запускается прордолжение тактирования LCD
TCD0.CTRLA = 0;
line++;
if(line>11)
{
if(line<284)
{
}
}
if(line==525) line=0;
TCD0.CTRLA = TC_CLKSEL_DIV1_gc;
}

void Port_config()
{
PORTA.DIR=0xff;
PORTA.OUT=0x00;

PORTB.DIR=0xff;
PORTB.OUT=0x00;

PORTC.DIR=0xff;
PORTC.OUT=0x00;

PORTD.DIR=0xff;
PORTD.OUT=0x00;

PORTE.DIR=0xff;
PORTE.OUT=0x00;

PORTF.DIR=0xff;
PORTF.OUT=0x00;

PORTH.DIR=0xff;
PORTH.OUT=0x00;

PORTJ.DIR=0xff;
PORTJ.OUT=0x00;

PORTK.DIR=0xff;
PORTK.OUT=0x00;

PORTQ.DIR=0xff;
PORTQ.OUT=0x00;

PORTR.DIR=0xff;
PORTR.OUT=0x00;
}


Сообщение отредактировал IgorKossak - Feb 26 2014, 19:31
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 12:18
Рейтинг@Mail.ru


Страница сгенерированна за 0.01369 секунд с 7
ELECTRONIX ©2004-2016