K210的硬件引脚和软件功能使用的是FPIOA映射关系
fpioa_set_function(硬件外设的连接引脚(那48个), FUNC_LED0:FUNC_GPIO0+软件gpio口);
fpioa_function_t在SDK里 FUNC_GPIO0之类的管脚的功能定义
LED 灯是低电平点亮的
//绑定GPIO 引脚
void hardware_init(void)
{
fpioa_set_function(PIN_LED_0, FUNC_LED0);
fpioa_set_function(PIN_LED_1, FUNC_LED1);
}
//头文件
/*****************************HEAR-FILE************************************/
#include "fpioa.h"
/*****************************HARDWARE-PIN*********************************/
// 硬件IO口,与原理图对应
#define PIN_LED_0 (0)
#define PIN_LED_1 (17)
/*****************************SOFTWARE-GPIO********************************/
// 软件GPIO口,与程序对应
#define LED0_GPIONUM (0)
#define LED1_GPIONUM (1)
/*****************************FUNC-GPIO************************************/
// GPIO口的功能,绑定到硬件IO口
#define FUNC_LED0 (FUNC_GPIO0 + LED0_GPIONUM)
#define FUNC_LED1 (FUNC_GPIO0 + LED1_GPIONUM)
8个通用GPIO
使用一个中断源可设置边沿触发和电平触发
每个IO口可以分配到FPIOA上的48个管脚之一
FPIOA (现场可编程IO阵列)允许用户将255 个内部功能映射到芯片外围的48个自由IO上
用户接口:
• gpio_init:GPIO口初始化
• gpio_set_drive_mode:设置GPIO口输入或输出模式
• gpio_set_pin:设置GPIO引脚电平高/低
• gpio_get_pin:读取GPIO引脚电平
- 定义GPIO的值
typedef enum_gpio_pin_value
{
GPIO_PV_HIGH,
GPIO_PV_LOW
}gpio_pin_value_pin ;
cmake … -DPROJ=gpio_led -G “MinGW Makefiles”
这里会出现问题的原因:等于前后不能有空格,文件名不要有前后空格
make
双核对等,每个核心具备独立的FPU(浮点运算单元)
系统默认使用核心 0 ,如果需要使用核心 1 需要手动开启核心 1 的服务。
板级对应的头文件 bsp.h
bsp.h头文件是与平台相关的通用函数,核之间锁的相关操作。
提供获取当前运行程序的CPU核编号的接口以及启动第二个核的入口。
为用户提供以下接口:
• register_core1:向核心1注册函数,并启动核心1
• current_coreid:获取当前CPU的核心编号(0/1)
• read_cycle:获取CPU开机至今的时钟数。可以用使用这个函数精准的确定程序运行时钟。可以配合sysctl_clock_get_freq(SYSCTL_CLOCK_CPU)计算运行的时间。
• spinlock_lock:自旋锁,不可嵌套,不建议在中断使用,中断中可以使用spinlock_trylock。
• spinlock_unlock:自旋锁解锁。
• spinlock_trylock:获取自旋锁,成功获取锁会返回0,失败返回-1。
• corelock_lock:获取核间锁,核之间互斥的锁,同核内该锁会嵌套,只有异核之间会阻塞。不建议在中断使用该函数,中断中可以使用corelock_trylock。
• corelock_trylock:获取核间锁,同核时锁会嵌套,异核时非阻塞。成功获取锁会返回0,失败返回-1。
• corelock_unlock:核间锁解锁。
• sys_register_putchar:注册系统输出回调函数,printf时会调用该函数。系统默认使用UART3,如果需要修改UART则调用uart_debug_init函数。
• sys_register_getchar:注册系统输入回调函数,scanf时会调用该函数。系统默认使用UART3,如果需要修改UART则调用uart_debug_init函数。
• sys_stdin_flush:清理stdin缓存。
• get_free_heap_size:获取空闲内存大小。
• printk:打印核心调试信息,用户不必理会。
系统的 printf 默认使用高速串口 UARTHS(UART0)
BOOT键按下为低电平
对应的头文件 plic.h
PLIC可以将任一外部中断源单独分配到每个CPU的外部中断上。这提供了强大的灵活性,能适应不同的应用需求。
PLIC模块可以设置中断回调函数,当触发中断时,会自动运行中断回调函数,并且可以配置中断优先级。
为用户提供以下接口:
• plic_init:PLIC初始化外部中断。
• plic_irq_enable:使能外部中断。
• plic_irq_disable:禁用外部中断。
• plic_set_priority:设置中断优先级。
• plic_get_priority:获取中断优先级。
• plic_irq_register:注册外部中断函数。
• plic_irq_deregister:注销外部中断函数。
芯片定时器总共有3个,每个定时器有4路通道.
每个定时器可以设置触发间隔和定时器中断处理函数。
定时器可以设置纳秒级别的超时时间,并且可以设置中断回调。
定时器可以通过控制 使能与禁止的方式来暂停和重新启动,而不需要重新配置。
对应的头文件 timer.h 为用户提供以下接口:
• timer_init:初始化定时器。
• timer_set_interval:设置定时间隔。
//timer_set_irq (0.6.0 后不再支持,请使用timer_irq_register)
• timer_set_enable:使能/禁止定时器。 0禁用 1使能
• timer_irq_register:注册定时器中断回调函数。
int timer_irq_register(
timer_device_number_t device, //定时器号
timer_channel_number_t channel, //定时器通道号
int is_single_shot, //是否单次通道
uint32_t priority, //中断优先级
timer_callback_t callback, //中断回调函数
void *ctx//中断回调函数参数
);
//返回0成功 1失败
• timer_irq_deregister:注销定时器中断。
/* 初始化系统中断并使能 */
plic_init();
sysctl_enable_irq();
void init_timer(void) {
/* 定时器初始化 */
timer_init(TIMER_DEVICE_0);
/* 设置定时器超时时间 */==单位为ns==
timer_set_interval(TIMER_DEVICE_0, TIMER_CHANNEL_0, 500 * 1e6);//0.5s
/* 设置定时器中断回调 */
timer_irq_register(TIMER_DEVICE_0, TIMER_CHANNEL_0, 0, 1, timer_timeout_cb, &g_count);
/* 使能定时器 */
timer_set_enable(TIMER_DEVICE_0, TIMER_CHANNEL_0, 1);
}
1 PWM的内部实现是基于定时器的定时功能 。
2 控制PWM的两个重要因素是频率和占空比。
对应的头文件 pwm.h 脉冲宽度调制器PWM用于控制脉冲输出的占空比,其本质是一个定时器,
所以注意设置PWM号与通道时,不要与TIMER定时器冲突。
• pwm_init
• pwm_set_frequency
• pwm_set_enable 1开启 0禁用
void init_pwm(void)
{
/* 初始化PWM */
pwm_init(PWM_DEVICE_1);
/* 设置PWM频率为200KHZ,占空比为0.5的方波 */
pwm_set_frequency(PWM_DEVICE_1, PWM_CHANNEL_0, 200000, 0.5);
/* 使能 PWM 输出 */
pwm_set_enable(PWM_DEVICE_1, PWM_CHANNEL_0, 1);
}
ov2640摄像头、LCD显示屏
OV2640 摄像头与K210开发板通过数字摄像头接口(DVP)连接DVP是常用的摄像头接口模块
具有以下特性:
对应的头文件 dvp.h
• dvp_init :DVP初始化。
• dvp_set_output_enable:设置输出模式(内存或AI)使能或禁止。
• dvp_set_image_format:设置图像接收模式,RGB或YUV。
• dvp_set_image_size:设置DVP图像采集尺寸。
• dvp_set_ai_addr:设置AI存放图像的地址,供AI模块进行算法处理。
• dvp_set_display_addr:设置采集图像在内存中的存放地址,可以用来显示。
• dvp_config_interrupt:设置图像开始和结束中断状态,使能或禁用。
• dvp_get_interrupt:判断是否是输入的中断类型,返回值:0为否,非0为是。
• dvp_clear_interrupt:清除中断。
• dvp_start_convert:开始采集图像,在确定图像采集开始中断后调用。
• dvp_enable_burst:使能突发传输模式。
• dvp_disable_burst:禁用突发传输模式。
• dvp_enable_auto:使能自动接收图像模式。
• dvp_disable_auto:禁用自动接收图像模式。
• dvp_sccb_send_data:通过sccb协议发送数据。
• dvp_sccb_receive_data:通过SCCB接收数据。
• dvp_sccb_set_clk_rate:设置sccb的速率。
• dvp_set_xclk_rate:设置输入时钟的速率。
加一个使能SPI0和DVP
void io_set_power
void dvp_cam_init(void)
{
/* DVP初始化,设置sccb的寄存器长度为8bit */
dvp_init(8);
/* 设置输入时钟为24000000*/
dvp_set_xclk_rate(24000000);
/* 使能突发传输模式 */
dvp_enable_burst();
/* 关闭AI输出模式,使能显示模式 */
dvp_set_output_enable(DVP_OUTPUT_AI, 0);
dvp_set_output_enable(DVP_OUTPUT_DISPLAY, 1);
/* 设置输出格式为RGB */
dvp_set_image_format(DVP_CFG_RGB_FORMAT);
/* 设置输出像素大小为320*240 */
dvp_set_image_size(CAM_WIDTH_PIXEL, CAM_HIGHT_PIXEL);
/* 设置DVP的显示地址参数和中断 */
display_buf = (uint32_t*)iomem_malloc(CAM_WIDTH_PIXEL * CAM_HIGHT_PIXEL * 2);
display_buf_addr = display_buf;
dvp_set_display_addr((uint32_t)display_buf_addr);
dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 0);
dvp_disable_auto();
}
配置中断,清楚中断标志位
for (index = 0; ov2640_config[index][0]; index++)
dvp_sccb_send_data(OV2640_ADDR, ov2640_config[index][0], ov2640_config[index][1]);
while (1)
{
/* 等待摄像头采集结束,然后清除结束标志 */
while (g_dvp_finish_flag == 0);
g_dvp_finish_flag = 0;
/* 显示画面 */
lcd_draw_picture(0, 0, 320, 240, display_buf_addr);
}
cmake … -DPROJ=camera -G "MinGW Makefiles