Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Stm32f103 tv out

Вт фев 06, 2018 09:34:37

Доброго времени суток, нашел хорошую статью "Генератор видео на 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)
        {
 
        }
}


где закомментирован не смог перевести код, кто в этом шарит или сталкивался с этим помогите пожалуйста новичку.
В архиве материалы из статьи
Вложения
RGB_gen.zip
(482.58 KiB) Скачиваний: 191

Re: Stm32f103 tv out

Вт фев 06, 2018 15:48:39

Весь проект скинь интересно посмотреть.
Ответить