Форум РадиоКот https://radiokot.ru/forum/ |
|
Stm32f103 tv out https://radiokot.ru/forum/viewtopic.php?f=59&t=152357 |
Страница 1 из 1 |
Автор: | loker995 [ Вт фев 06, 2018 09:34:37 ] | ||
Заголовок сообщения: | Stm32f103 tv out | ||
Доброго времени суток, нашел хорошую статью "Генератор видео на STM32F407: рецепт быстрого приготовления" там камень stm32f4 discovery и написан в другом ide, я передела на IDE Keil uVision4 (а камень stm32f103) СпойлерКод: #include "stm32f10x.h" #include "stm32f10x_tim.h" #include "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" #include "stm32f10x_dma.h" #include "stm32f10x_tim.h" #include <stdint.h> #include <string.h> #include <stdio.h> #include <stdbool.h> #include <stdlib.h> #define SCREEN_X_SIZE (430) #define SCREEN_Y_SIZE (242) #define FRAME_LINES (262) #define VSYNC_LEN (3) #define DEFAULT_HSYNC_LEN (381) #define DEFAULT_LINE_DELAY (762) #define DEFAULT_FIRST_VISIBLE_LINE (20) #define DEFAULT_LAST_VISIBLE_LINE (DEFAULT_FIRST_VISIBLE_LINE + 242) #define DEFAULT_PIXEL_FREQ (20) #define DEFAULT_PIXEL_PHASE (10) //uint32_t video_state; uint32_t ptr; //uint32_t *pFrameBuff = (uint32_t *)0x20000000; uint32_t frame_cnt; typedef enum { video_off = 0, video_on = 1 } video_mode_t; typedef struct { uint8_t pix[SCREEN_Y_SIZE][SCREEN_X_SIZE+2]; } frameBuffer_t; //typedef struct //{ video_mode_t video_mode; uint32_t frame_cnt,line_cnt, first_visible_line, last_visible_line, hsync_len; uint32_t vsync_len, line_delay,pix_freq, pix_phase, pix_line_len; //} video_state_t; extern frameBuffer_t *pFrameBuff; void video_gen_init(void); void video_gen_on(void); void video_gen_off(void); void set_first_visible_line(uint32_t line); void set_last_visible_line(uint32_t line); void set_line_delay(uint32_t delay); void set_line_len(uint32_t line_len); void set_dma_freq(uint32_t dma_period); void set_dma_phase(uint32_t phase); void init_all (void) { GPIO_InitTypeDef gpio; DMA_InitTypeDef dma; TIM_TimeBaseInitTypeDef tim; TIM_OCInitTypeDef tim_oc; //memset(pFrameBuff, 0x00, sizeof(frameBuffer_t) ); first_visible_line = DEFAULT_FIRST_VISIBLE_LINE; last_visible_line = DEFAULT_LAST_VISIBLE_LINE; hsync_len = DEFAULT_HSYNC_LEN; vsync_len = VSYNC_LEN; line_delay = DEFAULT_LINE_DELAY; pix_freq = DEFAULT_PIXEL_FREQ; pix_phase = DEFAULT_PIXEL_PHASE; pix_line_len = SCREEN_X_SIZE; line_cnt = frame_cnt = 0; /************************************** GPIO *************************************/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); gpio.GPIO_Mode = GPIO_Mode_Out_PP; gpio.GPIO_Speed = GPIO_Speed_50MHz; gpio.GPIO_Pin = GPIO_Pin_0 + GPIO_Pin_1 + GPIO_Pin_2 + GPIO_Pin_3 + GPIO_Pin_4 + GPIO_Pin_5 + GPIO_Pin_6 + GPIO_Pin_7; GPIO_Init(GPIOD, &gpio); gpio.GPIO_Pin = GPIO_Pin_4; GPIO_Init(GPIOB, &gpio); /*********************************************************************************/ /************************************* DMA ***************************************/ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); DMA_DeInit(DMA1_Channel6); dma.DMA_PeripheralBaseAddr = (uint32_t)(&GPIOD->ODR); dma.DMA_MemoryBaseAddr = (uint32_t)pFrameBuff; dma.DMA_DIR = DMA_DIR_PeripheralDST; dma.DMA_BufferSize = SCREEN_X_SIZE; dma.DMA_PeripheralInc = DMA_MemoryInc_Disable; dma.DMA_MemoryInc = DMA_MemoryInc_Enable; dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; dma.DMA_Mode = DMA_Mode_Normal; dma.DMA_Priority = DMA_Priority_VeryHigh; //dma.DMA_FIFOMode = DMA_FIFOMode_Disable; //dma.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; //dma.DMA_MemoryBurst = DMA_MemoryBurst_Single; //dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA1_Channel6, &dma); DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE); NVIC_EnableIRQ(DMA1_Channel6_IRQn); /*********************************************************************************/ /************************************ TIM1 ***************************************/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); tim.TIM_Period = pix_freq - 1; tim.TIM_Prescaler = 0; tim.TIM_ClockDivision = 0; tim.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &tim); /*********************************************************************************/ /************************************ TIM_OC ***************************************/ tim_oc.TIM_OutputNState = TIM_OutputNState_Enable; tim_oc.TIM_OCPolarity = TIM_OCPolarity_Low; tim_oc.TIM_OCNPolarity = TIM_OCNPolarity_Low; tim_oc.TIM_OCIdleState = TIM_OCIdleState_Set; tim_oc.TIM_OCNIdleState = TIM_OCIdleState_Reset; tim_oc.TIM_OCMode = TIM_OCMode_PWM2; tim_oc.TIM_OutputState = TIM_OutputState_Enable; tim_oc.TIM_OCMode = TIM_OCMode_PWM1; tim_oc.TIM_OutputState = TIM_OutputState_Enable; tim_oc.TIM_Pulse = pix_phase; TIM_OC1Init(TIM1, &tim_oc); /*********************************************************************************/ /********************************** GPIO_8 ***************************************/ gpio.GPIO_Pin = GPIO_Pin_8; gpio.GPIO_Speed = GPIO_Speed_50MHz; gpio.GPIO_Mode = GPIO_Mode_AF_PP; //gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &gpio); //GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1); TIM_CtrlPWMOutputs(TIM1, ENABLE); TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM1, TIM_TS_ITR1); TIM_DMACmd(TIM1, TIM_DMA_CC1, ENABLE); /*********************************************************************************/ /********************************** TIM2 ***************************************/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); tim.TIM_Period = 5148-1; tim.TIM_Prescaler = 0; tim.TIM_ClockDivision = 0; tim.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &tim); tim_oc.TIM_OutputNState = TIM_OutputNState_Enable; tim_oc.TIM_OCPolarity = TIM_OCPolarity_Low; tim_oc.TIM_OCNPolarity = TIM_OCNPolarity_Low; tim_oc.TIM_OCIdleState = TIM_OCIdleState_Set; tim_oc.TIM_OCNIdleState = TIM_OCIdleState_Reset; tim_oc.TIM_OCMode = TIM_OCMode_PWM2; tim_oc.TIM_OutputState = TIM_OutputState_Enable; tim_oc.TIM_OCMode = TIM_OCMode_PWM2; tim_oc.TIM_Pulse = line_delay; TIM_OC2Init(TIM2, &tim_oc); tim_oc.TIM_OCMode = TIM_OCMode_PWM1; tim_oc.TIM_Pulse = hsync_len; TIM_OC3Init(TIM2, &tim_oc); gpio.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2; gpio.GPIO_Speed = GPIO_Speed_50MHz; gpio.GPIO_Mode = GPIO_Mode_AF_PP; //gpio.GPIO_OType = GPIO_OType_PP; //gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &gpio); //GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2); //GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2); TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_OC2Ref); TIM_ITConfig(TIM2, TIM_IT_CC3, ENABLE); NVIC_SetPriority(TIM2_IRQn, 1); NVIC_EnableIRQ(TIM2_IRQn); //DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM2_STOP; } void DMA2_Stream1_IRQHandler(void) { //if (DMA_GetITStatus(DMA1_Channel6, DMA1_IT_TCIF1) != RESET) //{ // DMA_ClearITPendingBit(DMA1_Channel6, DMA1_IT_TCIF1); GPIOD->ODR &= ~0xFF; // } } void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET) { TIM1->EGR |= 0x01; TIM2->SR = (uint16_t)~TIM_IT_CC3; // TIM_ClearITPendingBit(TIM2, TIM_IT_CC3); line_cnt++; if (line_cnt >= FRAME_LINES) { line_cnt = 0; frame_cnt++; TIM2->CCER |= TIM_CCER_CC3P; GPIOB->BSRR = GPIO_Pin_4; } else if (line_cnt == (FRAME_LINES - vsync_len)) { TIM2->CCER &= ~TIM_CCER_CC3P; GPIOB->BSRR = GPIO_Pin_4; } if (line_cnt >= last_visible_line) { //GPIOD->ODR &= ~0xFF; //tut iznachal'no komment byl } else if (line_cnt >= first_visible_line) { //DMA1_Channel6->CR &= ~((uint32_t)DAC_CR_EN1); //DMA1_Channel6->NDTR = pix_line_len; //DMA1_Channel6->M0AR = (uint32_t)pFrameBuff->pix[line_cnt - first_visible_line]; //DMA2->LIFCR = DMA1_Channel6_IT_MASK; // i tut //DMA_ClearFlag(); // i tut //DMA1_Channel6->CR |= (uint32_t)DMA_SxCR_EN; } } } void video_gen_on(void) { TIM_Cmd(TIM2, ENABLE); TIM_Cmd(TIM1, ENABLE); } void video_gen_off(void) { TIM_Cmd(TIM2, DISABLE); TIM_Cmd(TIM1, DISABLE); } void set_first_visible_line(uint32_t line) { if ((line < 10) || (line > 50)) return; first_visible_line = line; } void set_last_visible_line(uint32_t line) { if ((line < 100) || (line >= FRAME_LINES)) return; last_visible_line = line; } void set_line_delay(uint32_t delay) { if ((delay < 1) || (delay > 500)) return; line_delay = delay; TIM2->CCR2 = line_delay; } void set_line_len(uint32_t line_len) { if ((line_len < 1) || (line_len > SCREEN_X_SIZE)) return; pix_line_len = line_len; } void set_dma_freq(uint32_t dma_period) { if ((dma_period < 1) || (dma_period > 50)) return; pix_freq = dma_period; TIM1->ARR = pix_freq - 1; } void set_dma_phase(uint32_t phase) { if ((phase < 1) || (phase > 50)) return; pix_phase = phase; TIM1->CCR1 = pix_phase; } int main() { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); init_all(); video_gen_on(); /*ptr = (uint32_t )pFrameBuff; for (int i = 0; i < sizeof(frameBuffer_t)/4; i++) { ptr = 0xFF00FF00; } for (uint32_t line = 0; line < SCREEN_Y_SIZE; ++line) { //pFrameBuff -> pix[line][0] = 0; //pFrameBuff -> pix[line][SCREEN_X_SIZE-1] = 0; }*/ while(1) { } } где закомментирован не смог перевести код, кто в этом шарит или сталкивался с этим помогите пожалуйста новичку. В архиве материалы из статьи
|
Автор: | 240265 [ Вт фев 06, 2018 15:48:39 ] |
Заголовок сообщения: | Re: Stm32f103 tv out |
Весь проект скинь интересно посмотреть. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |