本K233是K210+nt35310液晶显示屏+OV5640摄像头组成
首先需要设置芯片CPU和DVP(数字摄像头接口)的时钟频率。
设置PLL CPU 时钟频率,PLL(Phase Locked Loop)是锁相回路或锁相环,用来统一整合时脉讯号,使高频器件正常工作,查看开发者编程指导书设置PLL频率。
sysctl_pll_set_freq函数,输入为PLL编号和要设置的频率。PLL编号有三个
SYSCTL_PLL0
SYSCTL_PLL1
SYSCTL_PLL2
宏定义三个频率
#define PLL0_OUTPUT_FREQ 1000000000UL
#define PLL1_OUTPUT_FREQ 300000000UL
#define PLL2_OUTPUT_FREQ 45158400UL
设置三个PLL的频率,并使能时钟
sysctl_pll_set_freq(SYSCTL_PLL0, PLL0_OUTPUT_FREQ);
sysctl_pll_set_freq(SYSCTL_PLL1, PLL1_OUTPUT_FREQ);
sysctl_pll_set_freq(SYSCTL_PLL2, PLL2_OUTPUT_FREQ);
sysctl_clock_enable(SYSCTL_CLOCK_AI);
uarths_init();//
io_mux_init();
io_set_power();
plic_init();
UARTHS是高速通用异步收发传输器,因为uarths 时钟源为PLL0,
在设置PLL0 后需要重新调用该函数设置波特率,否则会打印乱码。
DVP 是摄像头接口模块,支持把摄像头输入图像数据转发给AI 模块或者内存。
/* DVP init */
printf("DVP init\n");
dvp_init(16);//初始化DVP,设置sccb寄存器长度为16
dvp_enable_burst();//使能突发传输模式
dvp_set_output_enable(0, 1);//使能输出模式,并设置图像输出至内存
dvp_set_output_enable(1, 1);//使能输出模式,并设置图像输出至AI
dvp_set_image_format(DVP_CFG_RGB_FORMAT);//设置图像接收模式为RGB
dvp_set_image_size(320, 240);//设置DVP 图像采集尺寸为320*240
ov5640_init();//初始化摄像头
uint8_t g_ai_bufT[240 * 320 *3] __attribute__((aligned(128)));
uint32_t g_lcd_gram0[38400] __attribute__((aligned(64)));
uint32_t g_lcd_gram1[38400] __attribute__((aligned(64)));
dvp_set_ai_addr((uint32_t)g_ai_buf, (uint32_t)(g_ai_buf + 320 * 240), (uint32_t)(g_ai_buf + 320 * 240 * 2));
//设置AI 存放图像的地址,供AI 模块进行算法处理。
//分别是红色分量地址、绿色分量地址、蓝色分量地址
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();
//禁用自动接收图像模式
设置摄像头的中断,IRQN_DVP_INTERRUPT是数字摄像头(DVP)中断号,
/* 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);
plic_irq_register注册外部中断函数,on_irq_dvp是中断回调函数。
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;
}
最后一定要使能系统中断:
sysctl_enable_irq();
初始化LCD液晶显示屏,并显示黑底白字:facedetect
/* LCD init */
printf("LCD init\n");
lcd_init();
lcd_clear(BLACK);
lcd_draw_string(136, 70, "facedetect", WHITE);