Maix Bit(K210) 裸机开发教程(八)实现简易照相机

13 篇文章 22 订阅
9 篇文章 11 订阅


  使用Maix Bit的摄像头、SD卡、文件系统和LCD实现一个简易的照相机。使用BOOT按键进行拍照,之后将照片存储在SD卡上面。

SPI and DMAC usage:
SPI0 - LCD
SPI1 - SD card
SPI2 - unused
SPI3 - Flash
DMAC Channel 0 - LCD
DMAC Channel 1 - SD card

1、代码获取

在我前面一篇博客里面简述了代码如何下载以及使用。https://blog.csdn.net/weixin_45488643/article/details/109990336如有需要自行查看。
  在这里插入图片描述

2、代码修改

首先自己先创建一个新的工程文件,然后将dvp2sdcard文件夹下面的代码复制到自己创建的文件夹下面:
  在这里插入图片描述
安装依赖库文件:
在这里插入图片描述
比较重要的一点,开启控制:
打开board_config.h 我自己使用的是Maix bit 开发板,所以选择如下配置文件,根据需要选择自己的开发板硬件配置。
在这里插入图片描述

3、API简介

  LCD、SD和文件系统的常用API前面的博客已经介绍过了,如有兴趣,自行查看。

3.1 图片转化保存

int rgb565tobmp(uint8_t *buf,int width,int height, const char *filename)

*buf 保存的数据; width、height图片大小;*filename图片保存路径

3.2 内存释放

void iomem_free(void *paddr)

*paddr 空间地址

4 、代码修改

在这里插入图片描述
使用标志来保存数据。

static uint32_t NUM = 0; 
char buf[80];

目前可以保存9999张照片,保存更多自行修改。
在这里插入图片描述

4.1 主函数代码

#include <stdio.h>
#include <string.h>

#include "board_config.h"
#include "dvp.h"
#include "ff.h"
#include "fpioa.h"
#include "gpiohs.h"
#include "iomem.h"
#include "lcd.h"
#include "nt35310.h"
#include "ov2640.h"
#include "ov5640.h"
#include "plic.h"
#include "rgb2bmp.h"
#include "sdcard.h"
#include "sysctl.h"
#include "uarths.h"

/* SPI and DMAC usage
 *
 * SPI0 - LCD
 * SPI1 - SD card
 * SPI2 - unused
 * SPI3 - Flash
 *
 * DMAC Channel 0 - LCD
 * DMAC Channel 1 - SD card
 *
 */

#define KEY_GPIONUM 0

uint32_t *g_lcd_gram0;
uint32_t *g_lcd_gram1;

volatile uint8_t g_dvp_finish_flag;
volatile uint8_t g_ram_mux;
volatile uint8_t g_save_flag;

void irq_key(void *gp) { g_save_flag = 1; }

static int on_irq_dvp(void *ctx) {
  if (dvp_get_interrupt(DVP_STS_FRAME_FINISH)) {
    /* switch gram */
    dvp_set_display_addr(g_ram_mux ? (uint32_t)g_lcd_gram0
                                   : (uint32_t)g_lcd_gram1);

    dvp_clear_interrupt(DVP_STS_FRAME_FINISH);
    g_dvp_finish_flag = 1;
  } else {
    if (g_dvp_finish_flag == 0) dvp_start_convert();
    dvp_clear_interrupt(DVP_STS_FRAME_START);
  }

  return 0;
}

static void io_mux_init(void) {
#if BOARD_LICHEEDAN
  /* SD card */
  fpioa_set_function(27, FUNC_SPI1_SCLK);
  fpioa_set_function(28, FUNC_SPI1_D0);
  fpioa_set_function(26, FUNC_SPI1_D1);
  fpioa_set_function(29, FUNC_GPIOHS7);

  /* Init DVP IO map and function settings */
  fpioa_set_function(42, FUNC_CMOS_RST);
  fpioa_set_function(44, FUNC_CMOS_PWDN);
  fpioa_set_function(46, FUNC_CMOS_XCLK);
  fpioa_set_function(43, FUNC_CMOS_VSYNC);
  fpioa_set_function(45, FUNC_CMOS_HREF);
  fpioa_set_function(47, FUNC_CMOS_PCLK);
  fpioa_set_function(41, FUNC_SCCB_SCLK);
  fpioa_set_function(40, FUNC_SCCB_SDA);

  /* Init SPI IO map and function settings */
  fpioa_set_function(38, FUNC_GPIOHS0 + DCX_GPIONUM);
  fpioa_set_function(36, FUNC_SPI0_SS3);
  fpioa_set_function(39, FUNC_SPI0_SCLK);
  fpioa_set_function(37, FUNC_GPIOHS0 + RST_GPIONUM);

  sysctl_set_spi0_dvp_data(1);

  fpioa_set_function(16, FUNC_GPIOHS0 + KEY_GPIONUM);
#else
  /* SD card */
  fpioa_set_function(29, FUNC_SPI1_SCLK);
  fpioa_set_function(30, FUNC_SPI1_D0);
  fpioa_set_function(31, FUNC_SPI1_D1);
  fpioa_set_function(32, FUNC_GPIOHS7);

  /* Init DVP IO map and function settings */
  fpioa_set_function(11, FUNC_CMOS_RST);
  fpioa_set_function(13, FUNC_CMOS_PWDN);
  fpioa_set_function(14, FUNC_CMOS_XCLK);
  fpioa_set_function(12, FUNC_CMOS_VSYNC);
  fpioa_set_function(17, FUNC_CMOS_HREF);
  fpioa_set_function(15, FUNC_CMOS_PCLK);
  fpioa_set_function(10, FUNC_SCCB_SCLK);
  fpioa_set_function(9, FUNC_SCCB_SDA);

  /* Init SPI IO map and function settings */
  fpioa_set_function(8, FUNC_GPIOHS0 + DCX_GPIONUM);
  fpioa_set_function(6, FUNC_SPI0_SS3);
  fpioa_set_function(7, FUNC_SPI0_SCLK);

  sysctl_set_spi0_dvp_data(1);

  fpioa_set_function(26, FUNC_GPIOHS0 + KEY_GPIONUM);

#endif
}

static void io_set_power(void) {
#if BOARD_LICHEEDAN
  /* Set dvp and spi pin to 1.8V */
  sysctl_set_power_mode(SYSCTL_POWER_BANK6, SYSCTL_POWER_V18);
  sysctl_set_power_mode(SYSCTL_POWER_BANK7, SYSCTL_POWER_V18);

#else
  /* Set dvp and spi pin to 1.8V */
  sysctl_set_power_mode(SYSCTL_POWER_BANK1, SYSCTL_POWER_V18);
  sysctl_set_power_mode(SYSCTL_POWER_BANK2, SYSCTL_POWER_V18);
#endif
}

int main(void) {
  FATFS sdcard_fs;
  static uint32_t NUM = 0;
  char buf[80];
  /* Set CPU and dvp clk */
  sysctl_pll_set_freq(SYSCTL_PLL0, 800000000UL);

  uarths_init();

  io_mux_init();
  io_set_power();
  plic_init();

  gpiohs_set_drive_mode(KEY_GPIONUM, GPIO_DM_INPUT);
  gpiohs_set_pin_edge(KEY_GPIONUM, GPIO_PE_FALLING);
  gpiohs_set_irq(KEY_GPIONUM, 2, irq_key);

  /* LCD init */
  printf("LCD init\n");
  lcd_init();
#if BOARD_LICHEEDAN
#if OV5640
  lcd_set_direction(DIR_YX_LRDU);
#else
  lcd_set_direction(DIR_YX_RLDU);  // DIR_YX_RLDU  DIR_YX_LRDU
#endif
#else
#if OV5640
  lcd_set_direction(DIR_YX_LRUD);
#else
  lcd_set_direction(DIR_YX_LRUD);
#endif
#endif

  lcd_clear(BLACK);

  g_lcd_gram0 = (uint32_t *)iomem_malloc(320 * 240 * 2);
  g_lcd_gram1 = (uint32_t *)iomem_malloc(320 * 240 * 2);
  /* DVP init */
  printf("DVP init\n");
#if OV5640
  dvp_init(16);
  dvp_set_xclk_rate(50000000);
  dvp_enable_burst();
  dvp_set_output_enable(0, 0);
  dvp_set_output_enable(1, 1);
  dvp_set_image_format(DVP_CFG_RGB_FORMAT);
  dvp_set_image_size(320, 240);
  ov5640_init();
#else
  dvp_init(8);
  dvp_set_xclk_rate(24000000);
  dvp_enable_burst();
  dvp_set_output_enable(0, 0);
  dvp_set_output_enable(1, 1);
  dvp_set_image_format(DVP_CFG_RGB_FORMAT);
  dvp_set_image_size(320, 240);
  ov2640_init();
#endif

  dvp_set_display_addr((uint32_t)g_lcd_gram0);
  dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 0);
  dvp_disable_auto();

  /* DVP interrupt config */
  printf("DVP interrupt config\n");
  plic_set_priority(IRQN_DVP_INTERRUPT, 1);
  plic_irq_register(IRQN_DVP_INTERRUPT, on_irq_dvp, NULL);
  plic_irq_enable(IRQN_DVP_INTERRUPT);

  /* enable global interrupt */
  sysctl_enable_irq();

  /* SD card init */
  if (sd_init()) {
    printf("Fail to init SD card\n");
    return -1;
  }

  /* mount file system to SD card */
  if (f_mount(&sdcard_fs, _T("0:"), 1)) {
    printf("Fail to mount file system\n");
    return -1;
  }

  /* system start */
  printf("system start\n");
  g_ram_mux = 0;
  g_dvp_finish_flag = 0;
  dvp_clear_interrupt(DVP_STS_FRAME_START | DVP_STS_FRAME_FINISH);
  dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 1);

  while (1) {
    /* ai cal finish*/
    while (g_dvp_finish_flag == 0)
      ;
    g_ram_mux ^= 0x01;
    g_dvp_finish_flag = 0;

    if (g_save_flag) {
      sprintf(buf, "%dphoto.bmp", NUM++);
      rgb565tobmp((uint8_t *)(g_ram_mux ? g_lcd_gram0 : g_lcd_gram1), 320, 240,
                  _T(buf));  //文件保存名字
      g_save_flag = 0;
      if (NUM == 9999) {
        NUM = 0;
      }
    }
    /* display pic*/
    lcd_draw_picture(0, 0, 320, 240, g_ram_mux ? g_lcd_gram0 : g_lcd_gram1);
  }
  iomem_free(g_lcd_gram0); //释放内存
  iomem_free(g_lcd_gram1);
  return 0;
}

5 、照片展示

在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值