当前位置: 首页 > 科技观察

Hi3861的Micropython移植Pin

时间:2023-03-16 11:26:19 科技观察

更多内容请访问:与华为官方共建的鸿蒙技术社区https://ost.51cto.com1.OpenPin的编译需要配置MICROPY_PY_PIN为1,参与编译。它将包含在modmachine.c文件中的machine_module_globals_table数据中。{MP_ROM_QSTR(MP_QSTR_Pin),MP_ROM_PTR(&machine_pin_type)},2.移植Pin的接口函数需要在openharmony中包含gpio的头文件,里面包含了GPIO的操作函数。#include"hi_gpio.h"定义了可以引用的GPIO的名称。typedefstruct_machine_pin_obj_t{mp_obj_base_t基础;内部引脚;intble_ex;mp_obj_tpin_isr_cb;}machine_pin_obj_t;STATICmachine_pin_obj_tmachine_pin_obj[]={{{&machine_pin_type},1,1,MP_OBJ_NULL},{{&machine_pin_type},2,1,MP_OBJ_NULL},{{&machine_pin_type},3,1,MP_OBJ_NULL},{{&machine_pin_type},4,1,MP_OBJ_NULL},{{&machine_pin_type},101,1,MP_OBJ_NULL},{{&machine_pin_type},102,1,MP_OBJ_NULL},};然后移植并初始化定义函数mp_pin_make_new。mp_obj_tmp_pin_make_new(constmp_obj_type_t*type,size_tn_args,size_tn_kw,constmp_obj_t*args){mp_arg_check_num(n_args,n_kw,1,MP_OBJ_FUN_ARGS_MAX,true);//获取想要的引脚对象intwanted_pin=mp_obj_get_int(args[0]);constmachine_pin_obj_t*self=NULL;/*if(0<=wanted_pin&&wanted_pinbase.type==NULL){mp_raise_ValueError(MP_ERROR_TEXT("invalidpin"));}if(n_args>1||n_kw>0){//引脚模式给定,所以配置这个GPIOmp_map_tkw_args;mp_map_init_fixed_table(&kw_args,n_kw,args+n_args);马赫ine_pin_obj_init_helper(self,n_args-1,args+1,&kw_args);}returnMP_OBJ_FROM_PTR(self);}//pin.init(mode,pull=None,*,value)STATICmp_obj_tmachine_pin_obj_init_helper(machine_pin_obj_t*self,size_tn_args,constmp_obj_t*pos_args,mp_map_t*kw_args){枚举{ARG_mode,ARG_pull,ARG_value};staticconstmp_arg_tallowed_args[]={{MP_QSTR_mode,MP_ARG_REQUIRED|MP_ARG_INT},};//解析参数mp_arg_val_targs[MP_ARRAY_SIZE(allowed_args)];mp_arg_parse_all(n_args,pos_args,kw_args,MP_ARRAY_SIZE(allowed_args),allowed_args,args);//获取io模式uintmode=args[ARG_mode].u_int;开关(模式){caseGPIO_MODE_IN:{模式=IOT_GPIO_DIR_IN;休息;}caseGPIO_MODE_OUT:{模式=IOT_GPIO_DIR_OUT;休息;}默认:{模式=IOT_GPIO_DIR_OUT;休息;}}if(self->ble_ex==0){IoTGpioInit(自身->引脚);IoTGpioSetDir(self->pin,模式);hi_io_set_pull(self->pin,1);hi_io_set_func(self->pin,0);//设置IO口模式}else{set_io_attribute(self->pin,mode);}returnmp_const_none;}定义Pin后,需要获取IO的状态或设置IO的状态//pin.value([value])STATICmp_obj_tmachine_pin_value(size_tn_args,constmp_obj_t*args){returnmachine_pin_call(args[0],n_args-1,0,args+1);}STATICMP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_value_obj,1,2,machine_pin_value);在micropython的函数定义中,可以使用MP_DEFINE_CONST_FUN_OBWEJ_VAR来定义参数范围的关键字。根据定义,如果这个函数中的参数为空,就是获取参数,如果参数有值,就是设置IO电平。//获取/设置引脚值的快速方法STATICmp_obj_tmachine_pin_call(mp_obj_tself_in,size_tn_args,size_tn_kw,constmp_obj_t*args){mp_arg_check_num(n_args,n_kw,0,1,false);//machine_self_pin_("machine_pin_calln_args=%d\r\n",n_args);if(n_args==0){if(self->ble_ex==0){hi_gpio_valuegpio_val=HI_GPIO_VALUE1;IoTGpioGetInputVal(self->pin,&gpio_val);返回mp_obj_new_bool(gpio_val);}else{intval=0;get_io_value(self->pin,&val);返回mp_obj_new_bool(val);}}else{if(self->ble_ex==0){IoTGpioSetOutputVal(self->pin,mp_obj_is_true(args[0]));}else{set_io_value(self->pin,mp_obj_is_true(args[0]));}返回mp_const_none;}}3.在中断模式下,如果想得到IO的高低电平,可以traininrotation模式是其中之一,但是一定离不开中间的IO口。中断模式micropython也支持中断模式。STATICmp_obj_tmachine_pin_irq(size_tn_args,constmp_obj_t*pos_args,mp_map_t*kw_args){enum{ARG_handler,ARG_trigger};staticconstmp_arg_tallowed_args[]={{MP_QSTR_handler,MP_ARG_OBJ,{.u_obj=mp_const_none}},{MP_QSTR_trigger,MP_ARG_INT,{.u_int=PIN_IRQ_MODE_RISING}},};machine_pin_obj_t*self=MP_OBJ_TO_PTR(pos_args[0]);mp_arg_val_targs[MP_ARRAY_SIZE(allowed_args)];mp_arg_parse_all(n_args-1,pos_args+1,kw_args,MP_ARRAY_SIZE(allowed_args),allowed_args,args);printf("machine_pin_irqselfint=%d\r\n",self->pin);if(n_args>1||kw_args->used!=0){//配置irqmp_obj_thandler=args[ARG_handler].u_obj;if(handler!=mp_const_none){self->pin_isr_cb=handler;}else{printf("%s\r\n","handler=mp_const_none.");}uint32_ttrigger=args[ARG_trigger].u_int;IoTGpioRegisterIsrFunc(self->pin,1,trigger,machine_pin_isr_handler,(void*)self);}returnmp_const_none;}STATICMP_DEFINE_CONST_FUN_OBJ_KW(machineIO_pin_irq_obj,1,machine_pin_irq);当中断触发时,该函数用于设置中断和machine_pin_irq中断触发后,注册的函数machine_pin_isr_handlerSTATICvoidmachine_pin_isr_handler(void*arg){machine_pin_obj_t*self=arg;printf("machine_pin_isr_handler=%d\r\n",self->pin);mp_sched_schedule(self->pin_isr_c,MP_OBJ_FROM_PTR(self));}然后调用mp_sched_schedule(self->pin_isr_cb,MP_OBJ_FROM_PTR(self));实现回调函数的引用。后续会具体介绍mp_sched_schedule的工作原理。4、Python编程驱动IO(1)实现LED灯闪烁。importtimefrommachineimportPinled=Pin(12,Pin.OUT)whileTrue:led.value(0)#关闭time.sleep(0.5)led.value(1)#打开time.sleep(0.5)(2)IO电平采集。frommachineimportPinp_in=Pin(1,Pin.IN)print(p_in.value())#获取值,0或1(3)IO中断。frommachineimportPinkey_0=Pin(12,Pin.IN)deffunc(v):print("HelloHaoqixing\r\n")key_0.irq(handler=func,trigger=Pin.IRQ_RISING)5.总结IO口使用是我们学习单片机的开始,IO由python驱动,进一步降低了我们的学习成本。将micropython移植到hi3861的过程,也是一个学习C和Python的过程。这个方便的内容以后会持续更新。更多信息请访问:与华为官方共建的鸿蒙技术社区https://ost.51cto.com