Hi3861 basic function summary of Hongmeng OS2.0 equipment development

This is a summary of common functions of Hi3861 developed in Hongmeng 2.0 full source code, which can help us quickly configure GPIO, such as how to realize PWM, I2C, ADC, etc.

1. Basic IO functions

1.1 output

Enable and configure the output value in two steps;

IoTGpioInit(GPIO_idx); 
IoTGpioSetDir(GPIO_idx,1);//1-output 0-input
IoTGpioSetOutputVal(GPIO_idx,1); //0-low 1-high

It should be noted that some gpios also need to set multiplexing function, which may not be the normal GPIO mode by default.
At this time, you need to use hi_io_set_func function; Take GPIO9 as an example, set it as ordinary IO;

hi_io_set_func(BEEP_IO,HI_IO_FUNC_GPIO_9_GPIO_OUT);

1.2 input

In three steps, enable, configure the input mode (up and down) and obtain the io level;

IoTGpioInit(GPIO_idx); 
IoTGpioSetDir(GPIO_idx,0);//1-output 0-input
hi_io_set_pull(GPIO_idx, HI_IO_PULL_UP); //==Pull up input
IoSetPull(GPIO_idx, HI_IO_PULL_UP); //Self encapsulated in iot_gpio.h 2021.09.23
IoTGpioGetInputVal(GPIO_idx,1); //0-low 1-high

1.3 system delay

There are many system delay functions. The specific difference depends on the use effect. Commonly used are

usleep(us); //   delay us
osDelay(us);//   delay us
hi_udelay(us);// delay_us int32

2.PWM output

Hi3861 has 6 pwm channels in total++ Hi3861-2.0 pwm use process + +: + 1. Initialize io, 2. Multiplex io to pwm, 3. Enable pwm channel, 4. Start outputting pwm, 5. Stop outputting pwm++

//==Initialize GPIO9 
IoTGpioInit(PWM0_TEST_GPIO); 
//==Initialize pwm multiplexing function of GPIO9
hi_io_set_func(PWM0_TEST_GPIO,HI_IO_FUNC_GPIO_9_PWM0_OUT); 
//==Initialize pwm channel 0
IoTPwmInit(PWM0); 
//==Configure pwm0 output parameters: duty cycle 50%, frequency 160M/80000=2KHz 
IoTPwmStart(PWM0,50,80000); 
IoTPwmStop(PWM0);  //The above PWM operation is based on IOT_ The function of PWM. H package is essentially to package hi_pwm.h

hi_pwm_init(hi_pwm_port port);
hi_pwm_start(hi_pwm_port port, hi_u16 duty, hi_u16 freq);
hi_pwm_stop(hi_pwm_port port); //The above pwm operation is based on hi_pwm.h package function

2.1 PWM common API

iot_pwm.h encapsulated function, and hi_ The function entry parameters of PWM. H package are different;

iot_ IoTPwmStart() defined in PWM. H;

unsigned int IoTPwmStart(unsigned int port, unsigned short duty, unsigned int freq)
 port: 0-5  pwm Channel number
 duty: 1-99 Duty cycle, not 0\100
 freq: >160M/65535 = 2441 And pwm Frequency related, not directly set
unsigned int IoTPwmStart(unsigned int port, unsigned short duty, unsigned int freq)
{
    unsigned short hiDuty;
    unsigned short hiFreq;
    hiFreq = (unsigned short)(CLK_160M / freq);
    hiDuty = (duty * hiFreq) / DUTY_MAX;

    return hi_pwm_start((hi_pwm_port)port, hiDuty, freq);
    // Source code: return hi_pwm_start((hi_pwm_port)port, hiDuty, hiFreq); 
    //The last parameter is the frequency division coefficient. 160M/freq cannot be used first when transmitting. This is wrong. It can be corrected on September 26, 2021
}

hi_ Hi defined in PWM. H_ pwm_ start();

Output by configured parameters PWM Signal. PWM Signal duty cycle=duty/freq. frequency=Clock source frequency/freq. 
* @param  port [IN] PWM Port number.
* @param  duty [IN] PWM Duty cycle count value. The value range is:[1, 65535]. The default value is 750. CNend
* @param  freq [IN] Frequency division multiple. The value range is:[1, 65535]. The default value is 1500.
hi_u32 hi_pwm_start(hi_pwm_port port, hi_u16 duty, hi_u16 freq);
It can be seen that function encapsulation can be used more conveniently PWM,Directly set the duty cycle (1-99). But found iot_pwm.h Encapsulated IoTPwmStart()Frequency error, resulting in pwm Not normal, because IoTPwmStart()In, hiFreq It is the actual frequency after calculation, not the frequency division coefficient hi_pwm_start()When data is passed in, it should not be passed in hiFreq,It should still be the original freq. I have corrected the package and successfully driven the buzzer.

PWM summary, whether IoTPwmStart() or hi_pwm_start() is used, the actual output frequency hiFreq:

hiFreq = (unsigned short)(CLK_160M / freq);
//Note: hi_u32 hi_pwm_set_clock(hi_pwm_clk_source clk_type); / / = = set clock source, 160M by default

pwm summary, using IoTPwmStart(port,duty,freq) actual duty cycle hiDuty:

hiFreq = (unsigned short)(CLK_160M / freq);
hiDuty = (duty * hiFreq) / 100;   //Percentage of total cycles

PWM summary, use hi_pwm_start(port,duty,freq) actual duty cycle hiDuty:

hiDuty = (duty) / 65535;

2.2 how to control the steering gear

Hi3861 PWM additional information
– theoretical frequency [1, 65.535]KHz
(CLK_160M / freq) < 0xFFFF(65535)
Frequency division coefficient freq [2442160m]
– the actual frequency will not be very low, no specific measurement, no oscilloscope,
Digital steering gear (T=20ms) cannot be controlled.
++Analog low-frequency pwm: delay + io output (0-1) analog implementation + + control accuracy requirements are not very high. We can do so. We look forward to the official solution.

3.ADC implementation

Hi3861 has 7 ADC channels in total. See table 6.2 of hi3861 manual for each channel (as intercepted below). There are 8 ADC channels in total, ADC0 – ADC7, but channel 7 is the reference voltage and cannot be converted to ADC.

3.1 common API of ADC

++Usage process of Hi3861-2.0 ADC: + + 1. Initialize io, 2. Input io, 3. Configure input mode, 4. Read AD data.

  IoTGpioInit(pinID);
  IoTGpioSetDir(pinID,IOT_GPIO_DIR_IN);
  hi_io_set_func(pinID,HI_IO_FUNC_GPIO_pinID_GPIO);
  //Optional, pull-up, etc.:
  //IoSetPull(pinID, HI_IO_PULL_UP);
  hi_io_set_pull(pinID,HI_IO_PULL_UP);
  hi_adc_read(HI_ADC_CHANNEL_0,&data,HI_ADC_EQU_MODEL_1,HI_ADC_CUR_BAIS_DEFAULT, 0);     

3.2 precautions for ADC use

Hi3861-2.0 version i2c   hi_adc_read() parameter parsing

hi_u32 hi_adc_read(hi_adc_channel_index channel, hi_u16 *data, 
hi_adc_equ_model_sel equ_model, hi_adc_cur_bais cur_bais, hi_u16 delay_cnt);
channel:  0-7,Channel 0-7 
*data : Collected AD data
equ_model:In the average algorithm mode, the collected data is averaged and reused. Taking 1 is the original data, which is not average.
cur_bais: Analog power control, generally set as default
delay_cnt:The delay time count from configuring sampling to starting sampling is 334 at a time ns,Its value must be 0~0xFF0 between

Getting data is a pointer passing value.

4. Drive i2c

4.1 i2c API

++Hi3861-2.0 version i2c usage process (two-way i2c): 1. Initialize io, 2. Reuse io as i2c, 3. Initialize corresponding i2c channel, 4. Read / send data++

//==i2c1 
    IoTGpioInit(I2C1_SDA_IO13); 
    IoTGpioInit(I2C1_SCL_IO14); //Initialize io interface
    hi_io_set_func(I2C1_SDA_IO13, HI_IO_FUNC_GPIO_13_I2C0_SDA);
    hi_io_set_func(I2C1_SCL_IO14 , HI_IO_FUNC_GPIO_14_I2C0_SCL); //==GPIO multiplexed to I2C0
    hi_i2c_init(OLED_I2C_IDX, OLED_I2C_BAUDRATE);                //==Enable i2c1 to set the transmission rate OLED_I2C_IDX value to 1
    hi_i2c_write((hi_i2c_idx)id, OLED_I2C_ADDR, &i2cData);
//==i2c0 
    IoTGpioInit(MPU_SDA_IO0);
    IoTGpioInit(MPU_SCL_IO1);
    hi_io_set_func(MPU_SDA_IO0, HI_IO_FUNC_GPIO_13_I2C0_SDA);
    hi_io_set_func(MPU_SCL_IO1, HI_IO_FUNC_GPIO_14_I2C0_SCL);
    hi_i2c_init(MPU_I2C_IDX, MPU_I2C_BAUDRATE); //==Enable i2c1 to set the transmission rate OLED_I2C_IDX value to 0
    hi_i2c_write((hi_i2c_idx)id, ((MPU_ADDR<<1)|0), &i2cData);  //==Send device address + Write Command + target register reg + data written
    hi_i2c_read((hi_i2c_idx)id,((MPU_ADDR<<1)|1), &i2cData);    //==Send device address + read command + target register reg + read data

4.2 i2c usage tips

Hi3861-2.0 version i2c has some important definitions:

The data read and sent is a structure;
The data is passed in the form of pointer;
The defined function can only receive and send 8-bit data at a time;

Some thoughts on i2c function:

If you read a register, the address is 16 bit What about your device?----Truncate and send in two times;
yes mpu6050 Sending and receiving data need to send two addresses (device address and target register address) at a time. How to achieve this?---Send the second address as data.

Small summary

  • Basic IO functions
  • I2C related API
  • PWM related API
  • ADC related API
    Common header files
#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h" / / = = system dependencies include usleep() osdelay()

#include "iot_gpio.h"  //==IoTGpioInit(),IoTGpioSetDir(),IoTGpioSetOutPutVal()
#include "iot_pwm.h"   //==IoTPwmStart(),IoTPwmInit()
#include "hi_io.h"     //==hi_io_set_func(),hi_io_set_pull()
#include "hi_pwm.h"    //==hi_pwm_start()
#include "hi_adc.h"    //==hi_adc_read()
#include "hi_time.h"  //==hi_udelay()

I wrote the development record PPT. If you need it, you can go to my station B and pick it up by private letter I'll get the information.

5. Demonstration cases and their links

After learning to use the above API s, you can realize various functions, such as various expansion boards (colorful boards, environmental monitoring boards and traffic light boards) provided in hispark Wi Fi IOT smart home suite. During the learning process, you have made some demonstration videos. If you are interested, you can click to view them:
i2c communication – connect MPU6050: I'll see the demo video
ADC, PWM control LED, buzzer, steering gear, various expansion boards: I'll see the demo video

6. Other functions (wifi access, web programming)

The goal of Hongmeng OS is to connect all things. In fact, what's more interesting is that Hi3861 supports Hongmeng OS lightweight small system, and has wifi network access capability. If you connect to the Internet, you can say that you can do a lot of things. For example At the end of the video, use your mobile phone to control the steering gear , think about what else you can do? Keyless door opening, switching lights, controlling household appliances, controlling equipment
The next issue will talk about wifi access to realize keyless opening of dormitory doors.

Tags: IoT harmonyos

Posted on Mon, 27 Sep 2021 23:51:16 -0400 by joshgarrod