⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lpld_gpio_dma.c

📁 Kinetis_K60开源底层驱动开发包(20120328)
💻 C
字号:
/*
 * 测试硬件平台:  LPLD_K60 Card
 * 版权所有:      北京拉普兰德电子技术有限公司
 * 网络销售:      http://laplenden.taobao.com
 * 公司门户:      http://www.lpld.cn
 *
 * 说明:    本工程基于Kintis K60开源底层开发包开发,
 *          所有开源驱动代码均在"LPLD"文件夹下,调用说明见文档[#LPLD-003-N]
 *
 * 文件名:		LPLD_GPIO_DMA.c
 * 用途:		增强型DMA与GPIO模块综合例程,用于数字摄像头采集
 *                      OV系列数字摄像头均可使用
 *
 * LPLD_K60 Card 硬件配置说明:
 *                      摄像头位数据位 - PortD0~7
 *                      PCLK - PortC0
 *                      行中断 - PortB0
 *                      场中断 - PortB3
 *                      图像数据输出 - K60串口5,波特率115200,每幅图帧头发0x01
 *
 */

#include "common.h"
#include "HAL_eDMA.h"
#include "HAL_GPIO.h"
#include "uart.h"

#define H 200
#define V 150
#define PHOTO_SIZE H*V

void portb_isr(void);
void GPIO_Init(void);
void dma1_isr(void);

/********************************************************************/

LPLD_eDMA_Cfg_t User_Def_DMA_Init;  //声明DMA初始化结构体
uint8_t Pix_Data[PHOTO_SIZE];       //采集50行 200列的图像数据 
uint8_t V_Cnt;                      //行采集计数
uint8_t Field_Over;                 //场采集完成标志
uint8_t Is_SendPhoto;               //图像发送标志


void main (void)
{
  int i;
  DisableInterrupts;
  
  //变量初始化
  for(i=0;i<PHOTO_SIZE;i++)
  {
    Pix_Data[i]=0;  
  }
  V_Cnt=0;          //行计数
  Field_Over=1;     //场开始标志位
  Is_SendPhoto=1;   //从串口发送图像
  
  //IO口初始化
  GPIO_Init();
  
  //DMA初始化结构体赋值
  User_Def_DMA_Init.Channelx          =DMA_CH1;               //设置为通道1
  User_Def_DMA_Init.Peri_DmaReq       =PORTC_DMAREQ;          //IO C 产生DMA请求
  User_Def_DMA_Init.Minor_loop_Length =H;                     //主循环次数
  User_Def_DMA_Init.Source_Addr       =(uint32_t)&GPIOD_PDIR; //设置源地址
  User_Def_DMA_Init.Dest_Addr         =(uint32_t)Pix_Data;    //目的地址为Pix_Data的首地址
  User_Def_DMA_Init.Dma_irqc          =1;                     //采集结束触发中断
  User_Def_DMA_Init.isr_func          =dma1_isr;              //自定义通道1中断服务子程序
  //初始化DMA模块
  LPLD_DMA_Init(&User_Def_DMA_Init); 
 
  EnableInterrupts;
 
  enable_irq (88); //PORTB 中断 PB3产生场中断和PB0产生行中断
  
  while(1)             
  {
    if(Is_SendPhoto)
    {  
      //先发送一场图像的帧头0x01
      uart_putchar(UART5_BASE_PTR,0x01);
      for(i=0;i<PHOTO_SIZE;i++)
      {
        if(Pix_Data[i]==0x01)Pix_Data[i]++;
        uart_putchar(UART5_BASE_PTR,Pix_Data[i]);
      }
    } 
  }
  
}

/********************************************************************/

void GPIO_Init(void)
{
  LPLD_GPIO_Init(PORTD_BASE_PTR,0,0,2,0); //选择IO D作为数据口
  LPLD_GPIO_Init(PORTD_BASE_PTR,1,0,2,0); 
  LPLD_GPIO_Init(PORTD_BASE_PTR,2,0,2,0);
  LPLD_GPIO_Init(PORTD_BASE_PTR,3,0,2,0);
  LPLD_GPIO_Init(PORTD_BASE_PTR,4,0,2,0);
  LPLD_GPIO_Init(PORTD_BASE_PTR,5,0,2,0);
  LPLD_GPIO_Init(PORTD_BASE_PTR,6,0,2,0);
  LPLD_GPIO_Init(PORTD_BASE_PTR,7,0,2,0);
  
  LPLD_GPIO_Init(PORTC_BASE_PTR,0,0,2,1);       // 选择PTC0作为触发端
                                                // 配置成输入下拉电阻的模式
                                                // DMA上升沿触发
  LPLD_GPIO_Init(PORTB_BASE_PTR,0,0,2,9);       // 选择PTB0作为行中断
                                                // 配置成输入下拉电阻的模式
                                                // IO上升沿中断
  LPLD_GPIO_Init(PORTB_BASE_PTR,3,0,2,9);       // 选择PTB1作为场中断
                                                // 配置成输入下拉电阻的模式
                                                // IO上升沿中断
  LPLD_GPIO_SetIsr(PORTB_BASE_PTR, portb_isr);  //设置PortB口的自定义中断服务子程序
}                                           

/********************************************************************
函数名称:portb_isr
函数描述:IOB双边沿触发产生的中断请求 

 产中断产生采集信号开始信号
      ___
  ___|   |_________________________________________________________
          用于采集摄像头的行中断,HREF 信号如下
            ________________________
   ________|                        |_______________________________
           |->有效数据,启动DMA,    |->一行数据采集完毕,
函数输入量:无
函数输入量:无
********************************************************************/
void portb_isr(void)
{
  
  if((PORTB_ISFR & 0x00000001) && !Field_Over)
  { 
    LPLD_DMA_Start(1,1);         //使能通道1 DMA 请求
    V_Cnt++; 
  }
  else if(PORTB_ISFR & 0x00000008)
  {
    LPLD_DMA_Init(&User_Def_DMA_Init); //初始化DMA模块
    V_Cnt=0;                          //行采集计数清零
    Field_Over=0;                     //场采集完成清零
  }

}

void dma1_isr(void)
{
  
  if(V_Cnt==V) 
  {
    Field_Over=1; //场采集完成置位
  }
  
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -