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

 
 
> STM32F103C8T - перезапуск таймера от внешнего сигнала
varvar
сообщение Mar 27 2016, 09:04
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 93
Регистрация: 5-01-05
Из: Оулу
Пользователь №: 1 811



Пытаюсь перенести на STM32 свой старый проект на MSP430. И второй день туплю с применением таймера.
Делаю OSD. Алгоритм простой - на ногу 10 (PA0) подключен HSYNC. От него должен запустится таймер (TIM2) и запустить через какое-то время DMA и вызвать прерывание. Хотелось бы все сделать с минимумом кода, момент запуска DMA должен быть точно привязан к HSYNC, иначе изображение будет дергаться.
Задом чуствую, как-то надо использовать one pulse mode, но не выходит каменный цветок sad.gif
Прошу помощи более опытных товарищей - с STM32 я только начал играться. Ткните носом в пример кода инициализации таймера sm.gif

Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
varvar
сообщение Apr 2 2016, 13:54
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 93
Регистрация: 5-01-05
Из: Оулу
Пользователь №: 1 811



Цитата(Tarbal @ Apr 1 2016, 18:15) *
Ну что у вас? Получилось?

да, получилось. Картинка, как влитая. Ноги, правда, пришлось другие использовать.
Программа не особо чищена, но все работает. Нужна инициализация, дальше все прерывания делают. Буфера на страницу нет - слишком мало оперативки у процессора, только 20к. Изображение формируется "на лету", белое и черное.
CODE
#define FirstLine 30
#define LastLine 255
#define VIDEO_DELAY 820
#define VIDEO_EXRA_DELAY 400
//#define VIDEO_EXRA_DELAY 1000


uint16_t TestFlag=0x3333;
uint16_t LineCnt=0;
uint16_t LinePointer=0;
uint16_t Vsync_delay;

union buff_t
{
uint16_t wData[26];
uint8_t bData[52];
};


buff_t WhiteBuffer1;
buff_t WhiteBuffer2;
buff_t BlackBuffer1;
buff_t BlackBuffer2;

void OSD_init(void)
{


GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
SPI_InitTypeDef SPI_InitStructure;
DMA_InitTypeDef DMA_InitStructure;


for (int i=0; i<26; i++)
{
WhiteBuffer1.wData[i]= ~0x4040;
BlackBuffer1.wData[i]= ~0x0004;

// WhiteBuffer1[i]= ((i+1)<<8) +i +1;
// BlackBuffer1[i]= ((i+1)<<8) +i +1;

WhiteBuffer2.wData[i]= ~0x0040;
BlackBuffer2.wData[i]= ~0x0404;
}


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // Enable GPIO Peripheral clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // for Interrupt
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // timer
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // SPI1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // Enable DMA1 clock




// Configure test pin in output push/pull mode
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

// ****************************************************
// Vsync pin
// ****************************************************
// pin as input
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// interrupt from Vsync
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI_ClearITPendingBit(EXTI_Line3);// Clear EXTI Line Pending Bit
// Connect EXTI
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);
// Configure EXTI1 to generate an interrupt on falling edge
EXTI_InitStructure.EXTI_Line = EXTI_Line3;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);

// ****************************************************
// Hsync timer
// ****************************************************
// pin as input
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//
TIM_TimeBaseStructure.TIM_Period = VIDEO_DELAY + VIDEO_EXRA_DELAY;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// TIM2 PWM2 Mode configuration: Channel1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
TIM_OCInitStructure.TIM_Pulse = VIDEO_DELAY;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
//
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0;
TIM_ICInit(TIM2, &TIM_ICInitStructure);
//
TIM_SelectOnePulseMode(TIM2, TIM_OPMode_Single);
TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Trigger);
//
NVIC_EnableIRQ(TIM2_IRQn);

// ****************************************************
// SPI as black and white video
// ****************************************************
// SPI1 slave (black) PA6-MISO PA5-SCK
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx ;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
SPI_InitStructure.SPI_CRCPolynomial = 10; // !!! mandatory!!!
SPI_Init(SPI1, &SPI_InitStructure);
// SPI2 master (white) PB15-MISO PB13-SCK
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx ;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_CRCPolynomial = 10; // !!! mandatory!!!
SPI_Init(SPI2, &SPI_InitStructure);
//
// ****************************************************
// DMA
// ****************************************************
// Configure DMA1 - Channel5== (memory -> SPI)

DMA_DeInit(DMA1_Channel3); //Set DMA registers to default values
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR; //Address of peripheral the DMA must map to
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)BlackBuffer1.wData; //Variable from which data will be transmitted
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 26; //Buffer size
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure); //Initialize the DMA
//
// master SPI black
DMA_DeInit(DMA1_Channel5); //Set DMA registers to default values
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI2->DR; //Address of peripheral the DMA must map to
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)WhiteBuffer1.wData; //Variable from which data will be transmitted
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 26; //Buffer size
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5, &DMA_InitStructure); //Initialize the DMA

DMA_Cmd(DMA1_Channel3, ENABLE); // slave TX
//
//DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);


NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);



// ****************************************************
// enables
// ****************************************************
SPI1->CR2 |= 0x02; // TX DMA Enable
SPI2->CR2 |= 0x02;

}


// Vsync interrupt
extern "C" void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3) != RESET)
{
EXTI_ClearITPendingBit(EXTI_Line3);
if (Vsync_delay > 0)
{
if (--Vsync_delay==0)
{
SPI2->CR1 |= 0x0040; // master SPI enable
SPI1->CR1 |= 0x0040; // slave SPI enable
TIM2->DIER |= TIM_DIER_CC1IE | TIM_DIER_CC1DE; // Capture/Compare 1 DMA request and interrupt enable
TIM2->CR1 |= 0x0001; // enabled
}
}
LineCnt=0;
LinePointer=0;
}
}


// Hsync interrupt
// master 5ch DMA SPI2
extern "C" void TIM2_IRQHandler(void)
{
TIM2->SR &= ~TIM_IT_CC1; // Clear CC1IF
if ((LineCnt > FirstLine) && (LineCnt < LastLine))
{
TIM2->CR1 &= ~0x0001; // timer disabled

//GPIOA->ODR |= 0x04;

TIM2->DIER &= ~TIM_DIER_CC1DE; // DMA TIM disabled
SPI2->CR2 |= 0x02; // DMA master enabled

DMA1_Channel5->CCR |= DMA_CCR5_EN | DMA_CCR5_TCIE; // enable DMA & int
LinePointer++;
}
if (LineCnt == FirstLine)
{
DMA1_Channel5->CCR |= DMA_CCR5_EN | DMA_CCR5_TCIE; // enable DMA & int
DMA1_Channel3->CCR |= DMA_CCR3_EN;
}
LineCnt++;
}

// master DMA IRQ
extern "C" void DMA1_Channel5_IRQHandler(void)
//void DMA1_Channel5_IRQHandler(void)
{
DMA1->IFCR = DMA_IFCR_CGIF5; // clear int flag

DMA1_Channel5->CCR &= ~(DMA_CCR5_EN | DMA_CCR5_TCIE); // disable DMA & interrupt
DMA1_Channel3->CCR &= ~DMA_CCR3_EN;

SPI2->CR2 &= ~0x02; // DMA master disabled
SPI1->SR &= ~SPI_I2S_FLAG_TXE; // Clear slane SPI TX INT
SPI1->CR2 |= 0x80; // slave SPI interrupt enable
}

// slave SPI IRQ
extern "C" void SPI1_IRQHandler(void)
{
SPI1->SR &= ~SPI_I2S_FLAG_TXE; // Clear SPI2 TX INT
SPI1->CR2 &= ~0x80; // SPI1 interrupt disable

//GPIOA->ODR &= ~0x04;


TIM2->SR &= ~ TIM_SR_CC1OF; // compare flag
TIM2->EGR &= ~ TIM_EGR_CC1G; // capture/compare 1 generation
TIM2->DIER |= TIM_DIER_CC1DE; // DMA TIM enabled
SPI2->CR2 &= ~0x02; // DMA SPI1 disabled

if (LineCnt != LastLine)
{
if(LineCnt & 0x01)
{
DMA1_Channel5->CMAR = (uint32_t)WhiteBuffer1.wData;
DMA1_Channel3->CMAR = (uint32_t)BlackBuffer1.wData;
}
else
{
DMA1_Channel5->CMAR = (uint32_t)WhiteBuffer2.wData;
DMA1_Channel3->CMAR = (uint32_t)BlackBuffer2.wData;
}
DMA1_Channel5->CCR |= DMA_CCR5_EN; // enable DMA
DMA1_Channel3->CCR |= DMA_CCR3_EN;
flag |= 0x01;
}
else flag |= 0x02;
TIM2->CR1 |= 0x0001; // timer enabled

}


Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- varvar   STM32F103C8T - перезапуск таймера от внешнего сигнала   Mar 27 2016, 09:04
- - kolobok0   Цитата(varvar @ Mar 27 2016, 12:04) ...Тк...   Mar 27 2016, 10:56
- - scifi   Можно и по старинке - почитать мануал, понять, как...   Mar 27 2016, 10:58
- - varvar   Спасибо на добром слове, вот такая заготовка зараб...   Mar 27 2016, 11:51
|- - AleksBak   Цитата(varvar @ Mar 27 2016, 15:51) ...Ну...   Mar 28 2016, 06:07
- - varvar   scmRTOS чудесно работает с CMSIS, а куб генерирует...   Mar 28 2016, 08:19
|- - AleksBak   Цитата(varvar @ Mar 28 2016, 12:19) scmRT...   Mar 28 2016, 09:30
- - varvar   Цитата(AleksBak @ Mar 28 2016, 12:30) А г...   Mar 28 2016, 09:51
|- - AleksBak   Цитата(varvar @ Mar 28 2016, 13:51) На со...   Mar 28 2016, 11:07
|- - jcxz   Цитата(varvar @ Mar 28 2016, 15:51) На со...   Mar 28 2016, 16:35
- - Tarbal   Цитата(varvar @ Mar 27 2016, 13:04) Пытаю...   Mar 28 2016, 14:05
- - varvar   Цитата(Tarbal @ Mar 28 2016, 17:05) Я бы ...   Mar 28 2016, 15:27
|- - Tarbal   Цитата(varvar @ Mar 28 2016, 19:27) Приме...   Mar 28 2016, 18:38
|- - jcxz   Цитата(Tarbal @ Mar 29 2016, 00:38) Я с к...   Mar 28 2016, 23:53
- - varvar   Цитата(jcxz @ Mar 28 2016, 19:35) Всё в с...   Mar 28 2016, 16:48
|- - jcxz   Цитата(varvar @ Mar 28 2016, 22:48) И все...   Mar 28 2016, 16:58
- - Tarbal   Та мода, что вы описали есть в STM32F429. В описан...   Mar 29 2016, 02:40
- - Tarbal   Ну что у вас? Получилось?   Apr 1 2016, 15:15
- - Tarbal   Ну и хорошо   Apr 3 2016, 17:21
- - Огурцов   почему бы не использовать spi в режиме slave, дёрг...   Apr 3 2016, 18:09
- - varvar   Цитата(Огурцов @ Apr 3 2016, 21:09) почем...   Apr 4 2016, 08:34


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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 22:28
Рейтинг@Mail.ru


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