赞
踩
目前正在打大学生嵌入式大赛,本人负责的部分是对Hi3861开发板进行开发,因为以前玩的更多的是STM32,所以产生的idea会先在STM32上实现再试着转移到Hi3861开发板上,这其实符合大部分日嵌入式开发玩家的流程开发。
提示:下面案例可供参考
Hi3861其实并不是华为独自研发的,Hi3861是润和开发的一款开发板,华为海思和他们是一个合作的关系。
Hi3861LV100是一款高度集成的2.4GHz WiFi SoC芯片,集成IEEE 802.11b/g/n基带和RF电路,RF电路包括功率放大器PA、低噪声放大器LNA、RF balun、天线开关以及电源管理等模块;支持20MHz标准带宽和5MHz/10MHz窄带宽,提供最大72.2Mbit/s物理层速率。
Hi3861LV100WiFi基带支持正交频分复用(OFDM)技术,并向下兼容直接序列扩频(DSSS)和补码键控(CCK)技术,支持IEEE 802.11b/g/n协议的各种数据速率。
Hi3861LV100芯片集成高性能32bit微处理器、硬件安全引擎以及丰富的外设接口,外设接口包括SPI、UART、I2C、PWM、GPIO和多路ADC,同时支持高速SDIO2.0
Slave接口,最高时钟可达50MHz;芯片内置SRAM和Flash,可独立运行,并支持、在Flash上运行程序。
Hi3861LV100支持Huawei LiteOS和第三方组件,并配套提供开放、易用的开发和调试运行环境。
Hi3861LV100芯片适应于智能家电、智能门锁、低功耗Camera、BUTTON等物联网低功耗智能产品领域。
首先,一个STM32的程序怎么转移过去一个其他的板子呢?(本文为Hi3861)
3. 在导入对应的代码包(如adc.h此类),建议Hi3861直接用一个官方给的Hello world例程开发,这样就省去了很多和STM32一样的导包麻烦啦
4. 导包完成就是配置Hi3861支持的库了(专业名称BSP(板级支持包))。这一步很重要!这一步很重要!这一步很重要!如果你要使用Hi3861的相应功能但是你没有勾选支持的BSP的话,代码写对了也没用!比如要写一个OLED的显示功能,那么必须勾选IIC的support。
弄完了基础的配置之后就是如何转移代码的问题了。我直接贴上一部分的代码分析,有需要的自行去文章末尾下载工程文件
STM32代码如下:
int main(void) { u16 adcx; float temp; u8 lcd_id[12]; //存放LCD ID字符串 delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 LED_Init(); //LED端口初始化 Adc_Init(); //ADC初始化 LCD_Init(); sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//将LCD ID打印到lcd_id数组。 POINT_COLOR=RED;//设置字体为红色 LCD_ShowString(60,50,200,16,16,"Elite STM32"); LCD_ShowString(60,70,200,16,16,"ADC TEST"); LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK"); LCD_ShowString(60,110,200,16,16,"2015/1/14"); //显示提示信息 POINT_COLOR=BLUE;//设置字体为蓝色 LCD_ShowString(60,130,200,16,16,"ADC_CH0_VAL:"); LCD_ShowString(60,150,200,16,16,"ADC_CH0_VOL:0.000V"); while(1) { adcx=Get_Adc_Average(ADC_Channel_1,10); LCD_ShowxNum(156,130,adcx,4,16,0);//显示ADC的值 temp=(float)adcx*(3.3/4096); adcx=temp; LCD_ShowxNum(156,150,adcx,1,16,0);//显示电压值 temp-=adcx; temp*=1000; LCD_ShowxNum(172,150,temp,3,16,0X80); LED0=!LED0; delay_ms(250); LED0=!LED0; delay_ms(1000); } } //此处直接用的是正点原子的官方ADC例程,主要是为了转移的思想,转移什么代码不重要
这个代码主要的步骤就是初始化需要采集电压引脚,配置ADC,拿到模拟量之后用函数转移为数字量(ADC过程)显示到LCD上。代码的思想很简单
Hi3861代码如下:
#include <hi_early_debug.h> #include <hi_task.h> #include <stdio.h> #include <hi_adc.h> #include <hi_gpio.h> #include <hi_io.h> #include <hi_stdlib.h> #include <hi_i2c.h> #include <ssd1306_oled.h> #define WATER_SENSOR_TASK_SIZE ( 1024*2 ) #define WATER_SENSOR_TASK_PRIO ( 28 ) #define ADC_LENGTH ( 20 ) #define VLT_MIN (100) hi_u16 g_water_sensor_adc_buf[ADC_LENGTH]; extern hi_u32 oled_init(hi_void); extern hi_void oled_show_str(hi_u8 x, hi_u8 y, hi_u8 *chr, hi_u8 char_size); /* @berf gpio_config:i2c 0 Pin reuse is I2C mode */ hi_void gpio_config() { hi_io_set_func(HI_IO_NAME_GPIO_13, HI_IO_FUNC_GPIO_13_I2C0_SDA); hi_io_set_func(HI_IO_NAME_GPIO_14, HI_IO_FUNC_GPIO_14_I2C0_SCL); } /* @berf oled Screen display initialization @param hi_void */ hi_void water_sensor_display(hi_void) { hi_i2c_init(HI_I2C_IDX_0, HI_I2C_IDX_BAUDRATE); /* baudrate: 400kbps */ hi_i2c_set_baudrate(HI_I2C_IDX_0, HI_I2C_IDX_BAUDRATE); oled_init(); oled_fill_screen(OLED_CLEAN_SCREEN);//clear screen } /* gpio init Pin initialization */ hi_void water_sensor_gpio_init(hi_void) { hi_io_set_func(HI_IO_NAME_GPIO_7, HI_IO_FUNC_GPIO_7_GPIO); hi_gpio_set_dir(HI_GPIO_IDX_7, HI_GPIO_DIR_IN); } hi_void *water_sensor(hi_void *param) { hi_u32 ret; hi_u16 data; float voltage; hi_float vlt_max = 0; hi_float vlt_min = VLT_MIN; hi_u32 i; while (1) { memset_s(g_water_sensor_adc_buf, sizeof(g_water_sensor_adc_buf), 0x0, sizeof(g_water_sensor_adc_buf)); for (i = 0; i < ADC_LENGTH; i++) { vlt_max =0; ret = hi_adc_read(HI_ADC_CHANNEL_3, &data, HI_ADC_EQU_MODEL_4, HI_ADC_CUR_BAIS_DEFAULT, 0xF0); //CHANNAL 3 GPIO 7 if (ret != HI_ERR_SUCCESS) { printf("ADC Read Fail\n"); return HI_NULL; } printf("adc original data %d \n", data); voltage = (float)data * 1.8 * 4 / 4096.0; /* vlt * 1.8 * 4 / 4096.0 is to convert codeword to voltage */ vlt_max = (voltage > vlt_max) ? voltage : vlt_max; vlt_min = (voltage < vlt_min) ? voltage : vlt_min; printf( "vlt_min:%.3f, vlt_max:%.3f \n", vlt_min, vlt_max ); if (vlt_max > 1) { oled_show_str(0, 4, "is Rainning", 16);/*The test results will be displayed on the screen, if moisture is detected, it will display "it's raining"*/ } else if (vlt_max < 1) { oled_show_str(0, 4, "a sunny day", 16);/*The test results will be displayed on the screen, if no moisture is detected, "sunny" will be displayed”*/ } } hi_sleep(100); } } /* @berf Create simulated moisture sensor task @param hi_void @return Task created successfully ret = HI_ERR_SUCCESS,Failed ret = 0x800xxxx */ hi_u32 water_sensor_task(hi_void) { hi_u32 ret; hi_task_attr attr ={0}; hi_u32 water_sensor_id; gpio_config(); /*adc gpio init*/ water_sensor_gpio_init(); /*oled display*/ water_sensor_display(); /*attr Configuration of structural parameters*/ attr.stack_size = WATER_SENSOR_TASK_SIZE;//Task stack memory attr.task_prio = WATER_SENSOR_TASK_PRIO;//The task priority ranges from 0 to 31. Tasks 0 to 10 should not be used. The SDK has been used. The higher the value, the lower the priority attr.task_name = (hi_char*)"water_sensor_task";//task name /*create task*/ ret = hi_task_create(&water_sensor_id, &attr, water_sensor, HI_NULL); if (ret != HI_ERR_SUCCESS) { printf("Failed to create water_sensor_task\r\n"); } return HI_ERR_SUCCESS; }
这个代码是拿官方写的一个adc例程(此处我怕贴我自己写的不好讲清楚)
可以看到Hi3861和STM32最大的不同点就是Hi3861采用的是多线程执行方式,STM32采用的是顺序执行方式。所以正规的开发Hi3861的流程是:先创建一个线程任务,即create task,然后将需要实现的放入到线程任务跳转的功能函数中。
例:/create task/
ret = hi_task_create(&water_sensor_id, &attr, water_sensor, HI_NULL);
其中water_sensor是功能函数。
没了解过多线程单片机系统开发的先不要纠结为什么这么写,先学会用!照猫画虎
钢铁侠说过:有时候学会走之前要先试着跑起来!(是这么说的嘛我不记得了,大概大概 )
Hi3861中的hi_adc_read函数,这些就需要去看API文档和相关硬件设计的文档了。这里附上一些我接触过了引脚复用为ADC的
1.ret = hi_adc_read(HI_ADC_CHANNEL_3, &data, HI_ADC_EQU_MODEL_4, HI_ADC_CUR_BAIS_DEFAULT, 0xF0); //CHANNAL 3 GPIO 7
2.ret = hi_adc_read(HI_ADC_CHANNEL_2, &data, HI_ADC_EQU_MODEL_4, HI_ADC_CUR_BAIS_DEFAULT, 0); //CHANNAL 2 GPIO 5
3.ret = hi_adc_read(HI_ADC_CHANNEL_5, &data, HI_ADC_EQU_MODEL_4, HI_ADC_CUR_BAIS_DEFAULT, 0xF0); //CHANNAL 5 GPIO 11
里面的参数设计就需要看API文档了,我贴心 的给大家准备好了
本文介绍了怎么把一个STM32的程序转移到Hi3861上,其实这个思想适用于大多数的转移开发板代码。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。