HCM111Z QuecOpen(SDK) 外设接口开发指导
简介
移远通信 HCM111Z 模块支持 QuecOpen® 解决方案。QuecOpen® 是基于 RTOS 系统的嵌入式开发平台。它旨在简化物联网应用的开发和设计。有关 QuecOpen® 的详细信息,请参考 *文档 [1]*。
本文档适用于基于 SDK 构建环境的 QuecOpen® 解决方案。本文档主要介绍在 QuecOpen® 方案下,如何使用模块所支持的 GPIO、PMU GPIO、UART、ADC、PWM、SPI 和 I2C API 进行对应外设接口开发。
GPIO
GPIO API
头文件
ql_gpio.h,GPIO API 的头文件,在 components/quectel_api/ql_include 目录中。除非另有说明,本文档中提到的所有头文件都在此目录中。
API 概述
| 函数 | 描述 |
|---|---|
ql_gpio_set_port_mux() |
设置 GPIO 复用功能。 |
ql_gpio_init() |
初始化 GPIO。 |
ql_gpio_set_level() |
设置指定 GPIO 的引脚电平。 |
ql_gpio_get_level() |
获取指定 GPIO 的引脚电平。 |
ql_gpio_int_init() |
初始化和使能 GPIO 中断。 |
ql_gpio_int_disable() |
关闭配置的 GPIO 中断。 |
ql_gpio_set_port_pull() |
设置 GPIO 作为输入端口时的上拉模式。 |
API 描述
ql_gpio_set_port_mux
此函数用于设置 GPIO 复用功能。
原型:
ql_gpio_errcode_e ql_gpio_set_port_mux(ql_gpio_num_e pin, uint8_t func)
参数:
pin: [In] GPIO 引脚编号。有关详细信息,请参见 ql_gpio_num_e。func: [In] GPIO 复用功能。
返回值:
函数执行结果码,请参见 ql_gpio_errcode_e。
ql_gpio_init
此函数用于初始化 GPIO。
原型:
ql_gpio_errcode_e ql_gpio_init(ql_gpio_num_e pin, ql_gpio_mode_e mode)
参数:
pin: [In] GPIO 引脚编号。有关详细信息,请参见 ql_gpio_num_e。mode: [In] GPIO 模式。有关详细信息,请参见 ql_gpio_mode_e。
返回值:
函数执行结果码,请参见 ql_gpio_errcode_e。
ql_gpio_num_e
GPIO 编号信息的枚举:
typedef enum {
QL_GPIO_PA0,
QL_GPIO_PA1,
QL_GPIO_PA2,
QL_GPIO_PA3,
QL_GPIO_PA4,
QL_GPIO_PA5,
QL_GPIO_PA6,
QL_GPIO_PA7,
QL_GPIO_PB0,
QL_GPIO_PB1,
QL_GPIO_PB2,
QL_GPIO_PB3,
QL_GPIO_PB4,
QL_GPIO_PB5,
QL_GPIO_PB6,
QL_GPIO_PB7,
QL_GPIO_PC0,
QL_GPIO_PC1,
QL_GPIO_PC2,
QL_GPIO_PC3,
QL_GPIO_PC4,
QL_GPIO_PC5,
QL_GPIO_PC6,
QL_GPIO_PC7,
QL_GPIO_PD0,
QL_GPIO_PD1,
QL_GPIO_PD2,
QL_GPIO_PD3,
QL_GPIO_PD4,
QL_GPIO_PD5,
QL_GPIO_PD6,
QL_GPIO_PD7,
} ql_gpio_num_e;
| 成员 | 描述 |
|---|---|
| QL_GPIO_PA0 | GPIOA0 |
| QL_GPIO_PA1 | GPIOA1 |
| QL_GPIO_PA2 | GPIOA2 |
| QL_GPIO_PA3 | GPIOA3 |
| QL_GPIO_PA4 | GPIOA4 |
| QL_GPIO_PA5 | GPIOA5 |
| QL_GPIO_PA6 | GPIOA6 |
| QL_GPIO_PA7 | GPIOA7 |
| QL_GPIO_PB0 | GPIOB0 |
| QL_GPIO_PB1 | GPIOB1 |
| QL_GPIO_PB2 | GPIOB2 |
| QL_GPIO_PB3 | GPIOB3 |
| QL_GPIO_PB4 | GPIOB4 |
| QL_GPIO_PB5 | GPIOB5 |
| QL_GPIO_PB6 | GPIOB6 |
| QL_GPIO_PB7 | GPIOB7 |
| QL_GPIO_PC0 | GPIOC0 |
| QL_GPIO_PC1 | GPIOC1 |
| QL_GPIO_PC2 | GPIOC2 |
| QL_GPIO_PC3 | GPIOC3 |
| QL_GPIO_PC4 | GPIOC4 |
| QL_GPIO_PC5 | GPIOC5 |
| QL_GPIO_PC6 | GPIOC6 |
| QL_GPIO_PC7 | GPIOC7 |
| QL_GPIO_PD0 | GPIOD0 |
| QL_GPIO_PD1 | GPIOD1 |
| QL_GPIO_PD2 | GPIOD2 |
| QL_GPIO_PD3 | GPIOD3 |
| QL_GPIO_PD4 | GPIOD4 |
| QL_GPIO_PD5 | GPIOD5 |
| QL_GPIO_PD6 | GPIOD6 |
| QL_GPIO_PD7 | GPIOD7 |
ql_gpio_mode_e
GPIO 模式的枚举:
typedef enum {
QL_GMODE_INPUT_PULLDOWN = 1,
QL_GMODE_INPUT_PULLUP,
QL_GMODE_OUTPUT=0,
} ql_gpio_mode_e;
| 成员 | 描述 |
|---|---|
| QL_GMODE_INPUT_PULLDOWN | 下拉输入(暂不支持) |
| QL_GMODE_OUTPUT | 推挽输出 |
| QL_GMODE_INPUT_PULLUP | 上拉输入 |
ql_gpio_errcode_e
GPIO API 相关结果码枚举:
typedef enum {
QL_GPIO_SUCCESS = 0,
QL_GPIO_EXECUTE_ERR,
QL_GPIO_INVALID_PARAM_ERR,
QL_GPIO_EXTI_LINE_CLASH_ERR,
} ql_gpio_errcode_e;
| 成员 | 描述 |
|---|---|
| QL_GPIO_SUCCESS | 执行成功 |
| QL_GPIO_EXECUTE_ERR | 执行失败 |
| QL_GPIO_INVALID_PARAM_ERR | 无效参数 |
| QL_GPIO_EXTI_LINE_CLASH_ERR | GPIO 中断线设置冲突 |
ql_gpio_set_level
此函数用于设置指定 GPIO 的引脚电平,仅对已经配置为输出模式的引脚有效。
原型:
ql_gpio_errcode_e ql_gpio_set_level(ql_gpio_num_e pin, ql_gpio_output_level_e output_level)
参数:
pin: [In] GPIO 引脚编号。有关详细信息,请参见 ql_gpio_num_e。output_level: [In] 引脚电平设置,只针对输出引脚。有关详细信息,请参见 ql_gpio_output_level_e。
返回值:
函数执行结果码,请参见 ql_gpio_errcode_e。
ql_gpio_output_level_e
GPIO 输出电平的枚举:
typedef enum {
QL_GPIO_OUTPUT_LOW,
QL_GPIO_OUTPUT_HIGH,
} ql_gpio_output_level_e;
| 成员 | 描述 |
|---|---|
| QL_GPIO_OUTPUT_LOW | 低电平 |
| QL_GPIO_OUTPUT_HIGH | 高电平 |
ql_gpio_get_level
此函数用于获取指定 GPIO 的引脚电平。
原型:
ql_gpio_errcode_e ql_gpio_get_level(ql_gpio_num_e pin, uint32_t *input_level)
参数:
pin: [In] GPIO 编号。有关详细信息,请参见 ql_gpio_num_e。input_level: [Out] GPIO 引脚电平。
返回值:
函数执行结果码,请参见 ql_gpio_errcode_e。
ql_gpio_int_init
此函数用于初始化和使能 GPIO 中断。
原型:
ql_gpio_errcode_e ql_gpio_int_init(ql_gpio_num_e pin, ql_gpio_irq_trigger_e trigger, ql_gpio_irq_callback callback)
参数:
pin: [In] GPIO 引脚编号。有关详细信息,请参见 ql_gpio_num_e。trigger: [In] GPIO 中断触发方式。有关详细信息,请参见 ql_gpio_irq_trigger_e。callback: [In] GPIO 中断回调函数。有关详细信息,请参见 ql_gpio_irq_callback。
返回值:
函数执行结果码,请参见 ql_gpio_errcode_e。
ql_gpio_irq_trigger_e
GPIO 中断触发方式的枚举:
typedef enum {
QL_IRQ_TRIGGER_LOW_LEVEL,
QL_IRQ_TRIGGER_HIGH_LEVEL,
QL_IRQ_TRIGGER_RISING_EDGE,
QL_IRQ_TRIGGER_FALLING_EDGE,
} ql_gpio_irq_trigger_e;
| 成员 | 描述 |
|---|---|
| QL_IRQ_TRIGGER_LOW_LEVEL | 低电平中断 |
| QL_IRQ_TRIGGER_HIGH_LEVEL | 高电平中断 |
| QL_IRQ_TRIGGER_RISING_EDGE | 上升沿中断 |
| QL_IRQ_TRIGGER_FALLING_EDGE | 下降沿中断 |
ql_gpio_irq_callback
此函数为 GPIO 中断的回调函数。
typedef void (*ql_gpio_irq_callback)(void *arg, uint8_t line)
参数:
arg: [Out] 触发 GPIO 中断的引脚。line: [Out] 触发 GPIO 中断的外部中断线序号。
ql_gpio_int_disable
此函数用于关闭配置的 GPIO 中断。
原型:
ql_gpio_errcode_e ql_gpio_int_disable(ql_gpio_num_e pin)
参数:
pin: [In] GPIO 引脚编号。有关详细信息,请参见 ql_gpio_num_e。
返回值:
函数执行结果码,请参见 ql_gpio_errcode_e。
ql_gpio_set_port_pull
此函数用于设置 GPIO 作为输入端口时的上拉模式。
原型:
ql_gpio_errcode_e ql_gpio_set_port_pull(ql_gpio_num_e pin, uint8_t enable)
参数:
pin: [In] GPIO 引脚编号。有关详细信息,请参见 ql_gpio_num_e。enable: [In] 上拉模式设置。True 使能上拉模式,False 不设置。
返回值:
函数执行结果码,请参见 ql_gpio_errcode_e。
开发过程
本章描述如何在应用程序中使用上述的 GPIO API,并进行基础的调试,示例中默认使用 QL_GPIO_PD4、QL_GPIO_PD5 和 QL_GPIO_PD6 进行测试。
操作过程
模块 SDK 中提供了操作 GPIO 的示例。演示在 quectel_demo/ql_gpio_demo/code 目录下的 ql_gpio_demo.c 中。相关函数的描述如下:
demo_gpio():初始化 GPIO 和使能 GPIO 中断。ql_gpio_irq_test():中断回调函数,实现了设置 GPIO 引脚电平和关闭 GPIO 中断。
void demo_gpio(void)
{
ql_debug("digital gpio demo\r\n");
//digital gpio output
ql_gpio_set_port_mux(QL_GPIO_PD4, QL_PORTD4_FUNC_D4);
ql_gpio_set_port_mux(QL_GPIO_PD5, QL_PORTD5_FUNC_D5);
ql_gpio_set_port_mux(QL_GPIO_PD6, QL_PORTD6_FUNC_D6);
ql_gpio_init(QL_GPIO_PD4, QL_GMODE_OUTPUT);
ql_gpio_init(QL_GPIO_PD5, QL_GMODE_INPUT_PULLDOWN);
ql_gpio_set_level(QL_GPIO_PD4, QL_GPIO_OUTPUT_HIGH);
ql_gpio_init(QL_GPIO_PD6, QL_GMODE_INPUT_PULLDOWN);
ql_gpio_int_init(QL_GPIO_PD6, QL_IRQ_TRIGGER_RISING_EDGE, ql_gpio_irq_test);
}
void ql_gpio_irq_test(void *arg, uint8_t line)
{
static int cnt = 0;
uint32_t input_level = 0;
ql_gpio_get_level(QL_GPIO_PD5, &input_level);
ql_debug("exit_line=%d\r\n", line);
ql_debug(" gpio5 read=%d\r\n", input_level);
if(input_level == 0){
ql_gpio_set_level(QL_GPIO_PD4, QL_GPIO_OUTPUT_LOW);
} else {
ql_gpio_set_level(QL_GPIO_PD4, QL_GPIO_OUTPUT_HIGH);
}
cnt++;
ql_debug(" int cnt=%d\r\n", cnt);
if(cnt >= 10){
ql_gpio_int_disable(QL_GPIO_PD6);
cnt = 0;
}
}
函数调试
要调试 GPIO 函数,使用安装了模块的开发板(例如,HCM111Z TE-B),并按照以下步骤操作:
- 运行 操作过程 中描述的 GPIO 演示。
- 重新编译固件版本,并将其烧录到模块。
- 重启模块。
- 打开 UART 1 端口以获取日志信息。

若调试过程中打印中断信息,则表示触发 GPIO 中断。
PMU GPIO
PMU GPIO API
头文件
ql_pmu_gpio.h,PMU GPIO API 的头文件,在 components/quectel_api/ql_include 目录中。除非另有说明,本文档中提到的所有头文件都在此目录中。
PMU GPIO 相较于普通 GPIO 的区别是 PMU GPIO 可以让模块在睡眠状态下保持输出电平状态不变。
API 概述
| 函数 | 描述 |
|---|---|
ql_pmu_gpio_init() |
初始化 PMU GPIO。 |
ql_pmu_gpio_set_level() |
设置指定 PMU GPIO 的引脚电平。 |
ql_pmu_gpio_get_level() |
获取指定 PMU GPIO 的引脚电平。 |
ql_pmu_gpio_int_init() |
初始化和使能 PMU GPIO 中断。 |
ql_pmu_gpio_int_disable() |
关闭配置的 PMU GPIO 中断。 |
API 描述
ql_pmu_gpio_init
此函数用于初始化 PMU GPIO。
原型:
ql_gpio_errcode_e ql_pmu_gpio_init(ql_gpio_num_e pin, ql_gpio_mode_e mode)
参数:
pin: [In] PMU GPIO 引脚编号。有关详细信息,请参见 ql_gpio_num_e。mode: [In] PMU GPIO 模式。有关详细信息,请参见 ql_gpio_mode_e。
返回值:
函数执行结果码,请参见 ql_gpio_errcode_e。
ql_pmu_gpio_set_level
此函数用于设置指定 PMU GPIO 的引脚电平,仅对已经配置为输出模式的引脚有效。
原型:
ql_gpio_errcode_e ql_pmu_gpio_set_level(ql_gpio_num_e pin, ql_gpio_output_level_e output_level)
参数:
pin: [In] PMU GPIO 引脚编号。有关详细信息,请参见 ql_gpio_num_e。output_level: [In] 引脚电平设置,只针对输出引脚。有关详细信息,请参见 ql_gpio_output_level_e。
返回值:
函数执行结果码,请参见 ql_gpio_errcode_e。
ql_pmu_gpio_get_level
此函数用于获取指定 PMU GPIO 的引脚电平。
原型:
ql_gpio_errcode_e ql_pmu_gpio_get_level(ql_gpio_num_e pin, uint32_t *input_level)
参数:
pin: [In] PMU GPIO 引脚编号。有关详细信息,请参见 ql_gpio_num_e。input_level: [Out] PMU GPIO 引脚电平值。
返回值:
函数执行结果码,请参见 ql_gpio_errcode_e。
ql_pmu_gpio_int_init
此函数用于初始化和使能 PMU GPIO 中断。
原型:
ql_gpio_errcode_e ql_pmu_gpio_int_init(ql_gpio_num_e pin, ql_gpio_irq_trigger_e trigger, ql_pmu_gpio_irq_callback callback)
参数:
pin: [In] PMU GPIO 引脚编号。有关详细信息,请参见 ql_gpio_num_e。trigger: [In] PMU GPIO 中断触发方式。有关详细信息,请参见 ql_gpio_irq_trigger_e。callback: [In] PMU GPIO 中断回调函数。有关详细信息,请参见 ql_pmu_gpio_irq_callback。
返回值:
函数执行结果码,请参见 ql_gpio_errcode_e。
ql_pmu_gpio_irq_callback
此函数为 PMU GPIO 中断的回调函数。
typedef void (*ql_pmu_gpio_irq_callback)(void *arg)
参数:
arg: [Out] 预留。
ql_pmu_gpio_int_disable
此函数用于关闭配置的 PMU GPIO 中断。
原型:
ql_gpio_errcode_e ql_pmu_gpio_int_disable(ql_gpio_num_e pin)
参数:
pin: [In] PMU GPIO 引脚编号。有关详细信息,请参见 ql_gpio_num_e。
返回值:
函数执行结果码,请参见 ql_gpio_errcode_e。
开发过程
本章描述如何在应用程序中使用上述的 PMU GPIO API,并进行基础的调试,示例中默认使用 QL_GPIO_PD4、QL_GPIO_PD5 和 QL_GPIO_PD6 进行测试。
操作过程
模块 SDK 中提供了操作 PMU GPIO 的示例。演示在 quectel_demo/ql_pmu_gpio_demo/code 目录下的 ql_pmu_gpio_demo.c 中。相关函数的描述如下:
demo_pmu_gpio():初始化 PMU GPIO 和使能 PMU GPIO 中断。ql_gpio_pmu_irq_test():中断回调函数,实现了获取和设置 PMU GPIO 的引脚电平,以及关闭 PMU GPIO 中断的功能。
void demo_pmu_gpio(void)
{
ql_debug("pmu gpio demo\r\n");
ql_pmu_gpio_init(QL_GPIO_PD4, QL_GMODE_OUTPUT);
ql_pmu_gpio_init(QL_GPIO_PD5, QL_GMODE_INPUT_PULLDOWN);
ql_pmu_gpio_set_level(QL_GPIO_PD4, QL_GPIO_OUTPUT_HIGH);
ql_pmu_gpio_int_init(QL_GPIO_PD6, QL_IRQ_TRIGGER_FALLING_EDGE, ql_gpio_pmu_irq_test); //wakeup pin
}
void ql_gpio_pmu_irq_test(void *arg)
{
static int cnt = 0;
uint32_t input_level = 0;
ql_pmu_gpio_get_level(QL_GPIO_PD5, &input_level);
ql_debug(" gpio5 read=%d\r\n", input_level);
if(input_level == 0){
ql_pmu_gpio_set_level(QL_GPIO_PD4, QL_GPIO_OUTPUT_LOW);
} else {
ql_pmu_gpio_set_level(QL_GPIO_PD4, QL_GPIO_OUTPUT_HIGH);
}
cnt++;
ql_debug(" int cnt=%d\r\n", cnt);
if(cnt >= 10){
ql_pmu_gpio_int_disable(QL_GPIO_PD6);
cnt = 0;
}
}
函数调试
要调试 PMU GPIO 函数,使用安装了模块的开发板(例如,HCM111Z TE-B),并按照以下步骤操作:
- 运行 操作过程 中描述的 PMU GPIO 演示。
- 重新编译固件版本,并将其烧录到模块。
- 重启模块。
- 打开 UART 1 端口以获取日志信息。

若调试过程中打印如下信息,则表示触发 PMU GPIO 中断。
UART
UART API
头文件
ql_uart.h,UART API 的头文件,在 components/quectel_api/ql_include 目录中。除非另有说明,本文档中提到的所有头文件都在此目录中。
API 概述
| 函数 | 描述 |
|---|---|
ql_uart_set_dcbconfig() |
设置串口属性。 |
ql_uart_get_dcbconfig() |
获取串口属性配置。 |
ql_uart_open() |
打开串口。 |
ql_uart_close() |
关闭串口。 |
ql_uart_write() |
通过串口向模块写入数据。 |
ql_uart_read() |
通过串口读取模块的数据。 |
ql_uart_set_rx_cb() |
注册串口接收数据中断事件的回调函数。 |
API 描述
ql_uart_set_dcbconfig
此函数用于设置串口属性,设置后重新打开串口才能生效。
原型:
ql_uart_errcode_e ql_uart_set_dcbconfig(ql_uart_port_number_e port, ql_uart_config_s *dcb)
参数:
port: [In] 串口编号。有关详细信息,请参见 ql_uart_port_number_e。dcb: [In] 串口属性配置。有关详细信息,请参见 ql_uart_config_s。
返回值:
函数执行结果码,请参见 ql_uart_errcode_e。
ql_uart_port_number_e
串口编号信息枚举:
typedef enum {
QL_UART_PORT_1,
QL_UART_PORT_2,
} ql_uart_port_number_e;
| 成员 | 描述 |
|---|---|
| QL_UART_PORT_1 | 串口1 |
| QL_UART_PORT_2 | 串口2 |
ql_uart_config_s
串口属性配置信息结构体:
typedef struct {
uint8_t is_debug_port;
ql_uart_baud_e baudrate;
ql_uart_databit_e data_bit;
ql_uart_stopbit_e stop_bit;
ql_uart_parityit_e parity_bit;
} ql_uart_config_s;
| 类型 | 参数 | 功能描述 |
|---|---|---|
| uint8_t | is_debug_port |
1 打印log 0 收发数据 |
| ql_uart_baud_e | baudrate |
波特率,默认为115200 bps,详见 ql_uart_baud_e |
| ql_uart_databit_e | data_bit |
数据位,默认为8位,详见 ql_uart_databit_e |
| ql_uart_stopbit_e | stop_bit |
停止位,默认为1位,详见 ql_uart_stopbit_e |
| ql_uart_parityit_e | parity_bit |
校验位,默认无校验,详见 ql_uart_parityit_e |
ql_uart_baud_e
串口波特率枚举:
typedef enum {
QL_UART_BAUD_2400 = 2400,
QL_UART_BAUD_4800 = 4800,
QL_UART_BAUD_9600 = 9600,
QL_UART_BAUD_14400 = 14400,
QL_UART_BAUD_19200 = 19200,
QL_UART_BAUD_38400 = 38400,
QL_UART_BAUD_57600 = 57600,
QL_UART_BAUD_115200 = 115200,
QL_UART_BAUD_230400 = 230400,
QL_UART_BAUD_460800 = 460800,
QL_UART_BAUD_921600 = 921600,
} ql_uart_baud_e;
| 成员 | 描述 |
|---|---|
| QL_UART_BAUD_2400 | 2400 bps |
| QL_UART_BAUD_4800 | 4800 bps |
| QL_UART_BAUD_9600 | 9600 bps |
| QL_UART_BAUD_14400 | 14400 bps |
| QL_UART_BAUD_38400 | 38400 bps |
| QL_UART_BAUD_57600 | 57600 bps |
| QL_UART_BAUD_115200 | 115200 bps |
| QL_UART_BAUD_230400 | 230400 bps |
| QL_UART_BAUD_460800 | 460800 bps |
| QL_UART_BAUD_921600 | 921600 bps |
ql_uart_databit_e
串口数据位的枚举:
typedef enum {
QL_UART_DATABIT_5,
QL_UART_DATABIT_6,
QL_UART_DATABIT_7,
QL_UART_DATABIT_8,
} ql_uart_databit_e;
| 成员 | 描述 |
|---|---|
| QL_UART_DATABIT_5 | 5位 |
| QL_UART_DATABIT_6 | 6位 |
| QL_UART_DATABIT_7 | 7位 |
| QL_UART_DATABIT_8 | 8位 |
ql_uart_stopbit_e
串口停止位枚举:
typedef enum {
QL_UART_STOP_1,
QL_UART_STOP_2,
} ql_uart_stopbit_e;
| 成员 | 描述 |
|---|---|
| QL_UART_STOP_1 | 1位 |
| QL_UART_STOP_2 | 2位 |
ql_uart_parityit_e
串口校验位枚举:
typedef enum {
QL_UART_PARITY_NONE,
QL_UART_PARITY_ODD,
QL_UART_PARITY_EVEN,
} ql_uart_parityit_e;
| 成员 | 描述 |
|---|---|
| QL_UART_PARITY_NONE | 无校验 |
| QL_UART_PARITY_ODD | 奇校验 |
| QL_UART_PARITY_EVEN | 偶校验 |
ql_uart_errcode_e
UART API 结果码枚举:
typedef enum {
QL_UART_SUCCESS = 0,
QL_UART_EXECUTE_ERR,
QL_UART_MEM_ADDR_NULL_ERR,
QL_UART_INVALID_PARAM_ERR,
QL_UART_NOT_OPEN_ERR,
} ql_uart_errcode_e;
| 成员 | 描述 |
|---|---|
| QL_UART_SUCCESS | 执行成功 |
| QL_UART_EXECUTE_ERR | 执行失败 |
| QL_UART_MEM_ADDR_NULL_ERR | 参数地址为空 |
| QL_UART_INVALID_PARAM_ERR | 无效参数 |
| QL_UART_NOT_OPEN_ERR | 串口未打开 |
ql_uart_get_dcbconfig
此函数用于获取串口属性配置。
原型:
ql_uart_errcode_e ql_uart_get_dcbconfig(ql_uart_port_number_e port, ql_uart_config_s *dcb)
参数:
port: [In] 串口编号。有关详细信息,请参见 ql_uart_port_number_e。dcb: [In] 串口属性配置。有关详细信息,请参见 ql_uart_config_s。
返回值:
函数执行结果码,请参见 ql_uart_errcode_e。
ql_uart_open
此函数用于打开串口。
原型:
ql_uart_errcode_e ql_uart_open(ql_uart_port_number_e port)
参数:
port: [In] 串口编号。有关详细信息,请参见 ql_uart_port_number_e。
返回值:
函数执行结果码,请参见 ql_uart_errcode_e。
ql_uart_close
此函数用于关闭串口。
原型:
ql_uart_errcode_e ql_uart_close(ql_uart_port_number_e port)
参数:
port: [In] 串口编号。有关详细信息,请参见 ql_uart_port_number_e。
返回值:
函数执行结果码,请参见 ql_uart_errcode_e。
ql_uart_write
此函数用于通过串口向模块写入数据。
原型:
int ql_uart_write(ql_uart_port_number_e port, unsigned char *data, unsigned int data_len)
参数:
port: [In] 串口编号。有关详细信息,请参见 ql_uart_port_number_e。data: [In] 写入的数据。data_len: [In] 写入的数据长度。
返回值:
函数执行结果码,请参见 ql_uart_errcode_e。
ql_uart_read
此函数用于通过串口读取模块的数据。
原型:
int ql_uart_read(ql_uart_port_number_e port, unsigned char *data, unsigned int data_len)
参数:
port: [In] 串口编号。有关详细信息,请参见 ql_uart_port_number_e。data: [Out] 读取的数据。data_len: [In] 读取的数据长度。
返回值:
函数执行结果码,请参见 ql_uart_errcode_e。
ql_uart_set_rx_cb
此函数用于注册串口接收数据中断事件的回调函数。
原型:
ql_uart_errcode_e ql_uart_set_rx_cb(ql_uart_port_number_e port, ql_uart_callback uart_cb)
参数:
port: [In] 串口编号。有关详细信息,请参见 ql_uart_port_number_e。uart_cb: [In] 需要注册的回调函数。有关详细信息,请参见 ql_uart_callback。
返回值:
函数执行结果码,请参见 ql_uart_errcode_e。
ql_uart_callback
此函数为串口中断的回调函数。
typedef void (*ql_uart_callback)(char value)
参数:
value: [In] 通过串口接收的数据。
开发过程
本章描述如何在应用程序中使用上述的串口函数,并进行基础的调试,示例中默认使用串口 0 进行测试。
操作过程
模块 SDK 中提供了操作 UART 的示例。演示在 quectel_demo/ql_uart_demo/code 目录下的 ql_uart_demo.c 中。相关函数的描述如下:
demo_uart():初始化串口,注册中断回调函数。ql_uart_cb_test():中断回调函数,可通过串口接收数据。
void demo_uart(void)
{
ql_uart_config_s cfg = {
.is_debug_port = 0, //0 | 1
.baudrate = QL_UART_BAUD_115200,
.data_bit = QL_UART_DATABIT_8,
.stop_bit = QL_UART_STOP_1,
.parity_bit = QL_UART_PARITY_NONE,
};
ql_debug("uart demo\r\n");
ql_gpio_set_port_mux(QL_GPIO_PD4, QL_PORTD4_FUNC_UART0_RXD);
ql_gpio_set_port_mux(QL_GPIO_PD5, QL_PORTD5_FUNC_UART0_TXD);
ql_gpio_set_port_pull(QL_GPIO_PD4, true);
ql_uart_set_dcbconfig(QL_UART_PORT_0, &cfg);
ql_uart_set_rx_cb(QL_UART_PORT_0, ql_uart_cb_test);
ql_uart_open(QL_UART_PORT_0);
}
void ql_uart_cb_test(char value)
{
char data = value;
ql_debug("recv %0x\r\n", data);
ql_uart_write(QL_UART_PORT_0, (unsigned char*)&data, 1);
}
函数调试
要调试 UART 函数,使用安装了模块的开发板(例如,HCM111Z TE-B),并按照以下步骤操作:
- 运行 操作过程 中描述的 UART 演示。
- 重新编译固件版本,并将其烧录到模块。
- 重启模块。
- 打开 UART 1 端口以获取日志信息。

ADC
ADC API
头文件
ql_adc.h,ADC API 的头文件,在 components/quectel_api/ql_include 目录中。除非另有说明,本文档中提到的所有头文件都在此目录中。
API 概述
| 函数 | 描述 |
|---|---|
ql_adc_channel_init() |
配置 ADC 通道参数。 |
ql_adc_channel_start() |
使能 ADC 检测。 |
ql_adc_channel_stop() |
停止 ADC 检测。 |
API 描述
ql_adc_channel_init
此函数用于配置 ADC 通道参数。
原型:
ql_adc_errcode_e ql_adc_channel_init(ql_adc_obj_s *handle, ql_adc_obj_callback cb, ql_adc_channel_e channel, void *user_data)
参数:
handle: [In] ADC 通道信息。有关详细信息,请参见 ql_adc_obj_s。cb: [In] 通道检测完成的回调函数。有关详细信息,请参见 ql_adc_obj_callback。channel: [In] ADC 通道编号。有关详细信息,请参见 ql_adc_channel_e。user_data: [In] 用户数据。
返回值:
函数执行结果码,请参见 ql_adc_errcode_e。
ql_adc_obj_s
ADC 通道信息结构体:
typedef struct adc_obj_ {
void *user_data;
ql_adc_channel_e channel;
ql_adc_obj_callback cb;
struct adc_obj_ *next;
} ql_adc_obj_s;
| 类型 | 参数 | 描述 |
|---|---|---|
| void * | user_data |
用户数据 |
| ql_adc_channel_e | channel |
ADC 通道编号 |
| ql_adc_obj_callback | cb |
通道检测完成的回调函数 |
| struct adc_obj_ * | next |
链表下一个节点的地址 |
ql_adc_obj_callback
此函数为 ADC 通道检测完成回调函数。
typedef void (*ql_adc_obj_callback)(ql_adc_channel_e channel, int value, void *user_data)
参数:
channel: [Out] ADC 通道编号。有关详细信息,请参见 ql_adc_channel_e。value: [Out] ADC 通道电压采样结果。范围:0~1023。ADC 参考电压为 3.3 V,当采样结果为 1023 时表示该通道电压大于或等于 3.3 V。user_data: [Out] 用户数据。
ql_adc_channel_e
ADC 通道编号枚举:
typedef enum {
QL_ADC_CHANNEL_0 = 0x01,
QL_ADC_CHANNEL_1 = 0x02,
QL_ADC_CHANNEL_2 = 0x04,
QL_ADC_CHANNEL_3 = 0x08,
} ql_adc_channel_e;
| 成员 | 描述 |
|---|---|
| QL_ADC_CHANNEL_0 | 通道0,检测 QL_GPIO_PD4 引脚电压 |
| QL_ADC_CHANNEL_1 | 通道1,检测 QL_GPIO_PD5 引脚电压 |
| QL_ADC_CHANNEL_2 | 通道2,检测 QL_GPIO_PD6 引脚电压 |
| QL_ADC_CHANNEL_3 | 通道3,检测 QL_GPIO_PD7 引脚电压 |
ql_adc_errcode_e
ADC API 结果码枚举:
typedef enum {
QL_ADC_SUCCESS = 0,
QL_ADC_EXECUTE_ERR,
QL_ADC_INVALID_PARAM_ERR,
} ql_adc_errcode_e;
| 成员 | 描述 |
|---|---|
| QL_ADC_SUCCESS | 函数执行成功 |
| QL_ADC_EXECUTE_ERR | 函数执行失败 |
| QL_ADC_INVALID_PARAM_ERR | 参数无效 |
ql_adc_channel_start
此函数用于使能 ADC 检测。
原型:
ql_adc_errcode_e ql_adc_channel_start(ql_adc_obj_s *handle)
参数:
handle: [In] ADC 通道信息。有关详细信息,请参见 ql_adc_obj_s。
返回值:
函数执行结果码,请参见 ql_adc_errcode_e。
ql_adc_channel_stop
此函数用于停止 ADC 检测。
原型:
ql_adc_errcode_e ql_adc_channel_stop(ql_adc_obj_s *handle)
参数:
handle: [In] ADC 通道信息。有关详细信息,请参见 ql_adc_obj_s。
返回值:
函数执行结果码,请参见 ql_adc_errcode_e。
开发过程
本章描述如何在应用程序中使用上述的 API,并进行基础的调试,示例中默认使用通道 0 进行测试。
操作过程
模块 SDK 中提供了操作 ADC 的示例。演示在 quectel_demo/ql_adc_demo/code 目录下的 ql_adc_demo.c 中。相关函数的描述如下:
demo_adc():重映射 ADC 通道,初始化 ADC。adc_tim_fn():定时器回调函数,实现了每隔一秒检测 ADC 通道。ql_adc_detect_callback():打印 ADC 通道检测结果。
void demo_adc(void)
{
ql_debug("adc demo\r\n");
ql_gpio_set_port_mux(QL_GPIO_PD4, QL_PORTD4_FUNC_ADC0);
ql_soft_timer_init(&adc_timer, adc_tim_fn, NULL);
ql_soft_timer_start(&adc_timer, 1000, 1);
}
void adc_tim_fn(void *arg)
{
ql_adc_channel_init(&ql_test_adc, ql_adc_detect_callback, QL_ADC_CHANNEL_0, NULL);
ql_adc_channel_start(&ql_test_adc);
ql_adc_channel_stop(&ql_test_adc);
}
static void ql_adc_detect_callback(ql_adc_channel_e channel, int value, void *user_data)
{
ql_debug("adc channel %d , value %d \r\n", channel, value);
}
函数调试
要调试 ADC 函数,使用安装了模块的开发板(例如,HCM111Z TE-B),并按照以下步骤操作:
- 运行 操作过程 中描述的 ADC 演示。
- 重新编译固件版本,并将其烧录到模块。
- 重启模块。
- 打开 UART 1 端口以获取日志信息。改变引脚输入电压,检测值随之改变。

PWM
PWM API
头文件
ql_pwm.h,PWM API 的头文件,在 components/quectel_api/ql_include 目录中。除非另有说明,本文档中提到的所有头文件都在此目录中。
API 概述
| 函数 | 描述 |
|---|---|
ql_pwm_init() |
初始化 PWM。 |
ql_pwm_update_param() |
更新 PWM 配置参数。 |
ql_pwm_enable() |
使能 PWM 输出。 |
ql_pwm_disable() |
停止 PWM 输出。 |
API 描述
ql_pwm_init
此函数用于初始化 PWM。
原型:
ql_pwm_errcode_e ql_pwm_init(ql_pwm_channel_e channel, uint32_t frequency, uint32_t high_duty)
参数:
channel: [In] PWM 通道。有关详细信息,请参见 ql_pwm_channel_e。frequency: [In] PWM 频率。high_duty: [In] PWM 占空比值。
返回值:
函数执行结果码,请参见 ql_pwm_errcode_e。
ql_pwm_channel_e
PWM 通道枚举:
typedef enum {
QL_PWM_0 = 0,
QL_PWM_1,
QL_PWM_2,
QL_PWM_3,
QL_PWM_4,
QL_PWM_5,
} ql_pwm_channel_e;
| 成员 | 描述 |
|---|---|
| QL_PWM_0 | PWM 通道0 |
| QL_PWM_1 | PWM 通道1 |
| QL_PWM_2 | PWM 通道2 |
| QL_PWM_3 | PWM 通道3 |
| QL_PWM_4 | PWM 通道4 |
| QL_PWM_5 | PWM 通道5 |
ql_pwm_errcode_e
PWM API 结果码枚举:
typedef enum {
QL_PWM_SUCCESS = 0,
QL_PWM_EXECUTE_ERR,
QL_PWM_INVALID_PARAM_ERR,
} ql_pwm_errcode_e;
| 成员 | 描述 |
|---|---|
| QL_PWM_SUCCESS | 执行成功 |
| QL_PWM_EXECUTE_ERR | 执行失败 |
| QL_PWM_INVALID_PARAM_ERR | 无效参数 |
ql_pwm_update_param
此函数用于更新 PWM 配置参数,更新后在下一个 PWM 周期生效。
原型:
ql_pwm_errcode_e ql_pwm_update_param(ql_pwm_channel_e channel, uint32_t frequency, uint32_t high_duty)
参数:
channel: [In] PWM 通道。有关详细信息,请参见 ql_pwm_channel_e。frequency: [In] PWM 频率。high_duty: [In] PWM 占空比值。
返回值:
函数执行结果码,请参见 ql_pwm_errcode_e。
ql_pwm_enable
此函数用于使能 PWM 输出。
原型:
ql_pwm_errcode_e ql_pwm_enable(ql_pwm_channel_e channel)
参数:
channel: [In] PWM 通道。有关详细信息,请参见 ql_pwm_channel_e。
返回值:
函数执行结果码,请参见 ql_pwm_errcode_e。
ql_pwm_disable
此函数用于停止 PWM 输出。
原型:
ql_pwm_errcode_e ql_pwm_disable(ql_pwm_channel_e channel)
参数:
channel: [In] PWM 通道。有关详细信息,请参见 ql_pwm_channel_e。
返回值:
函数执行结果码,请参见 ql_pwm_errcode_e。
开发过程
本章描述如何在应用程序中使用上述的 PWM API,并进行基础的调试,示例中默认使用 QL_PWM_4 和 QL_PWM_5 进行测试。
操作过程
模块 SDK 中提供了操作 PWM 的示例。演示在 quectel_demo/ql_pwm_demo/code 目录下的 ql_pwm_demo.c 中。相关函数的描述如下:
demo_pwm():初始化 PWM、使能 PWM 输出和关闭 PWM 输出。
void demo_pwm(void)
{
ql_debug("digital_pwm demo\r\n");
ql_gpio_set_port_mux(QL_GPIO_PD4, QL_PORTD4_FUNC_PWM4);
ql_gpio_set_port_mux(QL_GPIO_PD5, QL_PORTD5_FUNC_PWM5);
ql_pwm_init(QL_PWM_4, 1000, 50);
ql_pwm_init(QL_PWM_5, 1000, 80);
ql_pwm_enable(QL_PWM_4);
ql_pwm_enable(QL_PWM_5);
ql_sys_delay_100us(20000); //1 KHz for 2 s
ql_pwm_update_param(QL_PWM_4, 10000, 80);
ql_pwm_update_param(QL_PWM_5, 10000, 50);
ql_sys_delay_100us(10000); //10K hz for 1 s
ql_pwm_disable(QL_PWM_4);
ql_pwm_disable(QL_PWM_5);
ql_sys_delay_100us(20000); //Stop for 2 s
ql_pwm_enable(QL_PWM_4);
ql_pwm_enable(QL_PWM_5);
ql_sys_delay_100us(10000); //Restart PWM with 10 kHz for 1 s
ql_pwm_disable(QL_PWM_4);
ql_pwm_disable(QL_PWM_5);
}
函数调试
要调试 PWM 函数,使用安装了模块的开发板(例如,HCM111Z TE-B),并按照以下步骤操作:
- 运行 操作过程 中描述的 PWM 演示。
- 重新编译固件版本,并将其烧录到模块。
- 重启模块。
- 打开 UART 1 端口以获取日志信息。


SPI
SPI API
头文件
ql_spi.h,SPI API 的头文件,在 components/quectel_api/ql_include 目录中。除非另有说明,本文档中提到的所有头文件都在此目录中。
API 概述
| 函数 | 描述 |
|---|---|
ql_spi_init() |
初始化 SPI。 |
ql_spi_transfer() |
发送或接收 SPI 数据。 |
API 描述
ql_spi_init
此函数用于初始化 SPI。
原型:
ql_spi_errcode_e ql_spi_init(ql_spi_config_s spi_cfg)
参数:
spi_cfg: [In] SPI 配置。有关详细信息,请参见 ql_spi_config_s。
返回值:
函数执行结果码,请参见 ql_spi_errcode_e。
ql_spi_config_s
SPI 配置信息结构体:
typedef struct {
uint32_t spiclk;
ql_spi_cpol_pol_e cpol;
ql_spi_cpha_pol_e cpha;
ql_spi_master_slave_mode_e masterorslave;
void (*spi_cs_ctrl)(uint8_t);
} ql_spi_config_s;
| 类型 | 参数 | 描述 |
|---|---|---|
| uint32_t | spiclk |
SPI 时钟频率;最大 24 MHz。 |
| ql_spi_cpol_pol_e | cpol |
SPI 时钟极性,详见 ql_spi_cpol_pol_e |
| ql_spi_cpha_pol_e | cpha |
SPI 时钟相位,详见 ql_spi_cpha_pol_e |
| ql_spi_master_slave_mode_e | masterorslave |
SPI 主从机选择,详见 ql_spi_master_slave_mode_e |
| void (*spi_cs_ctrl)(uint8_t) | spi_cs_ctrl |
函数指针,指向控制 CS 引脚的函数,具体可参考下方举例的ql_spi_cs_ctrl() |
ql_spi_cpol_pol_e
SPI 时钟极性枚举:
typedef enum {
QL_SPI_CPOL_LOW = 0,
QL_SPI_CPOL_HIGH,
} ql_spi_cpol_pol_e;
| 成员 | 描述 |
|---|---|
| QL_SPI_CPOL_LOW | SCK 在空闲状态处于低电平 |
| QL_SPI_CPOL_HIGH | SCK 在空闲状态处于高电平 |
ql_spi_cpha_pol_e
SPI 时钟相位枚举:
typedef enum {
QL_SPI_CPHA_1Edge,
QL_SPI_CPHA_2Edge,
} ql_spi_cpha_pol_e;
| 成员 | 描述 |
|---|---|
| QL_SPI_CPHA_1Edge | 在 SCK 周期的第一个边沿采样数据。 |
| QL_SPI_CPHA_2Edge | 在 SCK 周期的第二个边沿采样数据。 |
ql_spi_master_slave_mode_e
SPI 主从机选择枚举:
typedef enum {
QL_SPI_MASTER = 0,
QL_SPI_SLAVE,
} ql_spi_master_slave_mode_e;
| 成员 | 描述 |
|---|---|
| QL_SPI_MASTER | SPI 为主机 |
| QL_SPI_SLAVE | SPI 为从机(暂不支持) |
ql_spi_errcode_e
SPI API 结果码枚举:
typedef enum {
QL_SPI_SUCCESS = 0,
QL_SPI_EXECUTE_ERR,
QL_SPI_INVALID_PARAM_ERR,
} ql_spi_errcode_e;
| 成员 | 描述 |
|---|---|
| QL_SPI_SUCCESS | 执行成功 |
| QL_SPI_EXECUTE_ERR | 执行失败 |
| QL_SPI_INVALID_PARAM_ERR | 无效参数 |
ql_spi_transfer
此函数用于发送或接收 SPI 数据。
原型:
ql_errcode_spi_e ql_spi_transfer(ql_spi_message_s *spi_msg)
参数:
spi_msg: [In] SPI 发送或接收的数据。有关详细信息,请参见 ql_spi_message_s。
返回值:
函数执行结果码,请参见 ql_spi_errcode_e。
ql_spi_message_s
SPI 发送或接收的数据结构体:
typedef struct {
UINT8 *send_buf;
UINT32 send_len;
UINT8 *recv_buf;
UINT32 recv_len;
} ql_spi_message_s;
| 类型 | 参数 | 描述 |
|---|---|---|
| UINT8 * | send_buf |
发送数据 |
| UINT32 | send_len |
发送的数据的长度 |
| UINT8 * | recv_buf |
接收数据 |
| UINT32 | recv_len |
接收的数据的长度 |
开发过程
本章描述如何在应用程序中使用上述的 SPI API,并进行基础的调试。
操作过程
模块 SDK 中提供了操作 SPI 的示例。演示在 quectel_demo/ql_spi_demo/code 目录下的 ql_spi_demo.c 中。相关函数的描述如下:
demo_spi_master():初始化 SPI,发送并接收数据。ql_spi_cs_ctrl():控制 CS 引脚。
void demo_spi_master(void)
{
ql_debug("spi master demo\r\n");
uint8_t send_buff[128] = {0};
uint8_t recv_buff[128] = {0};
int i = 0;
for(i=0; i<128; i++)
send_buff[i] = i;
ql_spi_config_s cfg = {
.spiclk = 3000000,
.cpol = QL_SPI_CPOL_LOW,
.cpha = QL_SPI_CPHA_1EDGE,
.masterorslave = QL_SPI_MASTER,
.spi_cs_ctrl = ql_spi_cs_ctrl,
};
ql_spi_message_s msg = {
.send_buf = send_buff,
.send_len = 128,
.recv_buf = recv_buff,
.recv_len = 128,
};
ql_gpio_set_port_mux(QL_GPIO_PD4, QL_PORTD4_FUNC_SSP0_CLK);
//ql_gpio_set_port_mux(QL_GPIO_PD5, QL_PORTD5_FUNC_SSP0_CSN);
ql_gpio_set_port_mux(QL_GPIO_PD5, QL_PORTD5_FUNC_D5);
ql_gpio_init(QL_GPIO_PD5, QL_GMODE_OUTPUT);
ql_gpio_set_port_mux(QL_GPIO_PD6, QL_PORTD6_FUNC_SSP0_DOUT);
ql_gpio_set_port_mux(QL_GPIO_PD7, QL_PORTD7_FUNC_SSP0_DIN);
ql_spi_init(cfg);
ql_spi_transfer(&msg);
ql_debug("spi master demo over\r\n");
}
void ql_spi_cs_ctrl(uint8_t enable)
{
ql_gpio_set_level(QL_GPIO_PD5, enable);
}
函数调试
要调试 SPI 函数,使用安装了模块的开发板(例如,HCM111Z TE-B),并按照以下步骤操作:
- 运行 操作过程 中描述的 SPI 演示。
- 重新编译固件版本,并将其烧录到模块。
- 重启模块。
- 打开 UART 1 端口以获取日志信息。


I2C
I2C API
头文件
ql_i2c.h,I2C API 的头文件,在 components/quectel_api/ql_include 目录中。除非另有说明,本文档中提到的所有头文件都在此目录中。
API 概述
| 函数 | 描述 |
|---|---|
ql_i2c_init() |
初始化 I2C 总线。 |
ql_i2c_write() |
向 I2C 总线中写入数据。 |
ql_i2c_read() |
从 I2C 总线中读取数据。 |
ql_i2c_master_init() |
初始化 I2C 主机。 |
ql_i2c_master_transmit() |
I2C 主机向从机传输数据。 |
ql_i2c_master_receive() |
I2C 主机读取从机传输的数据。 |
ql_i2c_slave_init() |
初始化 I2C 从机。 |
ql_i2c_slave_transmit() |
I2C 从机向主机传输数据。 |
ql_i2c_slave_receive() |
I2C 从机读取主机传输的数据。 |
API 描述
ql_i2c_init
此函数用于初始化 I2C 总线。
原型:
ql_errcode_i2c_e ql_i2c_init(QL_DD_HANDLE *i2c_hdl, ql_i2c_mode mode, ql_i2c_channel_e channel)
参数:
i2c_hdl: [Out] 获取的 I2C 句柄。mode: [In] I2C 的工作模式。有关详细信息,请参见 ql_i2c_mode_e。channel: [In] I2C 通道。有关详细信息,请参见 ql_i2c_channel_e。
返回值:
函数执行结果码,请参见 ql_errcode_i2c_e。
ql_i2c_mode_e
I2C 工作模式枚举:
typedef enum {
QL_STANDARD_MODE = 0,
QL_FAST_MODE,
QL_FAST_PLUS_MODE
} ql_i2c_mode;
| 成员 | 描述 |
|---|---|
| QL_STANDARD_MODE | 标准模式,速率:100 kbps |
| QL_FAST_MODE | 快速模式,速率:400 kbps |
| QL_FAST_PLUS_MODE | 高速模式,速率:1000 kbps |
ql_i2c_channel_e
I2C 通道枚举:
typedef enum {
QL_I2C_CHANNEL_0 = 0,
QL_I2C_CHANNEL_1,
} ql_i2c_channel_e;
| 成员 | 描述 |
|---|---|
| QL_I2C_CHANNEL_0 | I2C 通道0 |
| QL_I2C_CHANNEL_1 | I2C 通道1 |
ql_errcode_i2c_e
I2C API 结果码枚举:
typedef enum {
QL_I2C_SUCCESS = 0,
QL_I2C_INIT_ERR,
QL_I2C_WRITE_ERR,
QL_I2C_READ_ERR,
} ql_errcode_i2c_e;
| 成员 | 描述 |
|---|---|
| QL_I2C_SUCCESS | 执行成功 |
| QL_I2C_INIT_ERR | I2C 初始化失败 |
| QL_I2C_WRITE_ERR | 向 I2C 总线中写入数据失败 |
| QL_I2C_READ_ERR | 从 I2C 总线中读取数据失败 |
ql_i2c_write
此函数用于向 I2C 总线中写入数据。
原型:
ql_errcode_i2c_e ql_i2c_write(QL_DD_HANDLE *i2c_hdl, uint8_t slave_addr, uint8_t reg_addr, char *data, uint32_t len)
参数:
i2c_hdl: [In] I2C 句柄。slave_addr: [In] I2C 从机设备地址。reg_addr: [In] I2C 从机寄存器地址。data: [In] 写入的数据。len: [In] 写入数据的长度。
返回值:
函数执行结果码,请参见 ql_errcode_i2c_e。
ql_i2c_read
此函数用于从 I2C 总线中读取数据。
原型:
ql_errcode_i2c_e ql_i2c_read(QL_DD_HANDLE *i2c_hdl, uint8_t slave_addr, uint8_t reg_addr, char *data, uint32_t len)
参数:
i2c_hdl: [In] I2C 句柄。slave_addr: [In] I2C 从机设备地址。reg_addr: [In] I2C 从机寄存器地址。data: [Out] 读取的数据。len: [In] 读取数据的长度。
返回值:
函数执行结果码,请参见 ql_errcode_i2c_e。
ql_i2c_master_init
此函数用于初始化 I2C 主机。
原型:
ql_errcode_i2c_e ql_i2c_master_init(ql_i2c_channel_e i2c_channel, ql_i2c_mode i2c_mode, ql_i2c_pin_mux_e pin_mux)
参数:
i2c_channel: [In] I2C 通道,仅支持QL_I2C_CHANNEL_1。i2c_mode: [In] I2C 的工作模式。pin_mux: [In] I2C 的 SCL 和 SDA 的复用 GPIO 组合。有关详细信息,请参见 ql_i2c_pin_mux_e。
返回值:
函数执行结果码,请参见 ql_errcode_i2c_e。
ql_i2c_pin_mux_e
I2C 的 SCL 和 SDA 的复用 GPIO 组合枚举:
typedef enum {
// I2C1_CLK I2C1_DAT
QL_PIN_MUX_0, // PORTA2 PORTA3
QL_PIN_MUX_1, // PORTA6 PORTA7
QL_PIN_MUX_2, // PORTB2 PORTB3
QL_PIN_MUX_3, // PORTB6 PORTB7
QL_PIN_MUX_4, // PORTC2 PORTC3
QL_PIN_MUX_5, // PORTC6 PORTC7
QL_PIN_MUX_6, // PORTD2 PORTD3
QL_PIN_MUX_7 // PORTD6 PORTD7
} ql_i2c_pin_mux_e;
| 成员 | 描述 |
|---|---|
| QL_PIN_MUX_0 | 选择 PA2 作为 SCL,PA3 作为 SDA |
| QL_PIN_MUX_1 | 选择 PA6 作为 SCL,PA7 作为 SDA |
| QL_PIN_MUX_2 | 选择 PB2 作为 SCL,PB3 作为 SDA |
| QL_PIN_MUX_3 | 选择 PB6 作为 SCL,PB7 作为 SDA |
| QL_PIN_MUX_4 | 选择 PC2 作为 SCL,PC3 作为 SDA |
| QL_PIN_MUX_5 | 选择 PC6 作为 SCL,PC7 作为 SDA |
| QL_PIN_MUX_6 | 选择 PD2 作为 SCL,PD3 作为 SDA |
| QL_PIN_MUX_7 | 选择 PD6 作为 SCL,PD7 作为 SDA |
ql_i2c_master_transmit
此函数用于 I2C 主机向从机传输数据。
原型:
ql_errcode_i2c_e ql_i2c_master_transmit(ql_i2c_channel_e i2c_channel, uint8_t slave_addr, uint8_t *data, uint16_t data_len)
参数:
i2c_channel: [In] I2C 通道,仅支持QL_I2C_CHANNEL_1。slave_addr: [In] I2C 从机设备地址,无需进行偏移。data: [In] 传输的数据。data_len: [In] 传输数据的长度。
返回值:
函数执行结果码,请参见 ql_errcode_i2c_e。
ql_i2c_master_receive
此函数用于 I2C 主机读取从机传输的数据。
原型:
ql_errcode_i2c_e ql_i2c_master_receive(ql_i2c_channel_e i2c_channel, uint8_t slave_addr, uint8_t *data, uint16_t *data_len)
参数:
i2c_channel: [In] I2C 通道,仅支持QL_I2C_CHANNEL_1。slave_addr: [In] I2C 从机设备地址,无需进行偏移。data: [Out] 读取的数据。data_len: [Out] 读取数据的长度。
返回值:
函数执行结果码,请参见 ql_errcode_i2c_e。
ql_i2c_slave_init
此函数用于初始化 I2C 从机。
原型:
ql_errcode_i2c_e ql_i2c_slave_init(ql_i2c_channel_e i2c_channel, ql_i2c_mode i2c_mode, ql_i2c_pin_mux_e pin_mux, uint16_t slave_addr)
参数:
i2c_channel: [In] I2C 通道,仅支持QL_I2C_CHANNEL_1。i2c_mode: [In] I2C 的工作模式。pin_mux: [In] I2C 的 SCL 和 SDA 的复用 GPIO 组合。有关详细信息,请参见 ql_i2c_pin_mux_e。slave_addr: [In] 从机的初始化地址。
返回值:
函数执行结果码,请参见 ql_errcode_i2c_e。
ql_i2c_slave_transmit
此函数用于 I2C 从机向主机传输数据。
原型:
ql_errcode_i2c_e ql_i2c_slave_transmit(ql_i2c_channel_e i2c_channel, uint8_t *data, uint16_t data_len)
参数:
i2c_channel: [In] I2C 通道,仅支持QL_I2C_CHANNEL_1。data: [In] 传输的数据。data_len: [In] 传输数据的长度。
返回值:
函数执行结果码,请参见 ql_errcode_i2c_e。
ql_i2c_slave_receive
此函数用于 I2C 从机读取主机传输的数据。
原型:
ql_errcode_i2c_e ql_i2c_slave_receive(ql_i2c_channel_e i2c_channel, uint8_t *data, uint16_t *data_len)
参数:
i2c_channel: [In] I2C 通道,仅支持QL_I2C_CHANNEL_1。data: [Out] 读取的数据。data_len: [Out] 读取的数据长度。
返回值:
函数执行结果码,请参见 ql_errcode_i2c_e。
开发过程
本章描述如何在应用程序中使用上述的 I2C API,并进行基础的调试,示例中默认使用 QL_I2C_CHANNEL_1 进行测试。
操作过程
模块 SDK 中提供了操作 I2C 的示例。演示在 quectel_demo/ql_i2c_demo/code 目录下的 ql_i2c_demo.c 中。本示例中,模块作为 I2C 主机与芯片进行通信。相关函数的描述如下:
demo_i2c():初始化 I2C 通道 1。
void demo_i2c(void)
{
uint8_t i2c_test_no = 0;
char data = 0;
uint8_t buff1[6];
uint8_t buff2[6];
ql_debug("IIC demo\r\n");
ql_gpio_set_port_mux(QL_GPIO_PD6, QL_PORTD6_FUNC_I2C1_CLK); //PD6
ql_gpio_set_port_mux(QL_GPIO_PD7, QL_PORTD7_FUNC_I2C1_DAT); //PD7
ql_gpio_set_port_pull(QL_GPIO_PD6, 1);
ql_gpio_set_port_pull(QL_GPIO_PD7, 1);
//IIC1, 1 MHz. slave addr: 0xd6
ql_i2c_init(&i2c_hdl, QL_STANDARD_MODE, QL_I2C_CHANNEL_1);
// iic_init(IIC_CHANNEL_1,1000,LSM6DS33_ADDR);
data = 0;
ql_i2c_write(&i2c_hdl, LSM6DS33_ADDR, 0x15, &data, 1);
ql_i2c_write(&i2c_hdl, LSM6DS33_ADDR, 0x16, &data, 1);
data = 0x80;
ql_i2c_write(&i2c_hdl, LSM6DS33_ADDR, 0x10, &data, 1);
ql_i2c_write(&i2c_hdl, LSM6DS33_ADDR, 0x11, &data, 1);
data = 0x04;
ql_i2c_write(&i2c_hdl, LSM6DS33_ADDR, 0x12, &data, 1);
while(1)
{
for(uint8_t i=0; i<6; i++)
{
ql_i2c_read(&i2c_hdl, LSM6DS33_ADDR, 0x28+i, (char*)&buff1[i], 1);
ql_i2c_read(&i2c_hdl, LSM6DS33_ADDR, 0x22+i, (char*)&buff2[i], 1);
}
ql_debug("X:%d |Y:%d |Z:%d\r\n", *(uint16_t *)buff1, *(uint16_t *)(buff1+2), *(uint16_t *)(buff1+4));
ql_debug("AccX:%d|Acc_Y:%d|Acc_Z:%d\r\n", *(uint16_t *)buff2, *(uint16_t *)(buff2+2), *(uint16_t *)(buff2+4));
i2c_test_no++;
if(i2c_test_no > 3)
break;
}
}
函数调试
要调试 I2C 函数,使用安装了模块的开发板(例如,HCM111Z TE-B),并按照以下步骤操作:
- 运行 操作过程 中描述的 I2C 演示。
- 重新编译固件版本,并将其烧录到模块。
- 重启模块。
- 使用逻辑分析仪抓取 I2C 波形。

I2C 主从模式调试
模块 SDK 代码中提供了操作 I2C 的主从模式示例,示例程序在 quectel_demo/ql_i2c_demo/code 目录的 ql_i2c_master.c 和 ql_i2c_slave.c 文件中。本示例中,一个模块作为 I2C 主机,一个模块作为从机进行通信。相关函数的描述如下:
ql_i2c_demo_slave_init():初始化 I2C 从机通道 1,PA6 作为 SCL,PA7 作为 SDA,PA0 作为数据准备完成的标志引脚。
void ql_i2c_demo_slave_init(void)
{
ql_debug("I2C SLAVE DEMO RUNNING\r\n");
/* Configure I/O port to check whether data is ready on the slave */
ql_gpio_set_port_mux(QL_GPIO_PA0, QL_PORTA0_FUNC_A0);
ql_gpio_set_dir(QL_GPIO_PA0, QL_GMODE_OUTPUT);
ql_gpio_set_level(QL_GPIO_PA0 , QL_GPIO_OUTPUT_HIGH);
/* Prepare the data to be sent */
for(uint32_t i = 0; i < sizeof(slave_send_data); i++)
{
slave_send_data[i] = i + 10;
}
/* Initialization I2C master */
if(QL_I2C_SUCCRSS != ql_i2c_slave_init(QL_I2C_CHANNEL_1, QL_FAST_PLUS_MODE, QL_PIN_MUX_1, IIC_SLVAE_ADDRESS))
{
ql_debug("I2C SLAVE INIT FAIL!\r\n");
}
while(1)
{
ql_i2c_slave_receive(QL_I2C_CHANNEL_1, ql_slave_recv_data, &ql_slave_recv_len);
if(ql_slave_recv_len > 0)
{
ql_debug("SLAVE -> RECV DATA FROM MASTER, DATA LENGTH:%d\r\n", ql_slave_recv_len);
for (uint32_t i = 0; i < ql_slave_recv_len; i++)
{
ql_debug("%02X ", ql_slave_recv_data[i]);
}
ql_debug("\r\n");
ql_gpio_set_level(QL_GPIO_PA0 , QL_GPIO_OUTPUT_HIGH);
slave_send_data[0] = ql_slave_send_cnt++;
if(ql_slave_send_cnt > 255) ql_slave_send_cnt = 0;
ql_i2c_slave_transmit(QL_I2C_CHANNEL_1, slave_send_data, sizeof(slave_send_data));
/* Notification master */
ql_gpio_set_level(QL_GPIO_PA0 , QL_GPIO_OUTPUT_LOW);
}
}
}
ql_i2c_demo_master_init():初始化 I2C 主机通道 1,PA6 作为 SCL,PA7 作为 SDA,PA0 作为数据准备完成的标志引脚。
void ql_i2c_demo_master_init(void)
{
ql_debug("I2C MASTER DEMO RUNNING\r\n");
/* Configure I/O port to check whether data is ready on the slave */
ql_gpio_set_port_pull(QL_GPIO_PA0,1);
ql_gpio_set_port_mux(QL_GPIO_PA0, QL_PORTA0_FUNC_A0);
ql_gpio_set_dir(QL_GPIO_PA0, QL_GMODE_INPUT_PULLUP);
/* Prepare the data to be sent */
for (uint32_t i = 1; i < sizeof(master_send_data); i++)
{
master_send_data[i] = i;
}
/* Initialization I2C master */
if(QL_I2C_SUCCRSS != ql_i2c_master_init(QL_I2C_CHANNEL_1, QL_FAST_MODE, QL_PIN_MUX_1))
{
ql_debug("I2C MASTER INIT FAIL!\r\n");
}
while (1)
{
/* Master send data counter */
master_send_data[0] = ql_master_send_cnt++;
if(ql_master_send_cnt > 255) ql_master_send_cnt = 0;
/* Master transmit data to slave via i2c port */
ql_i2c_master_transmit(QL_I2C_CHANNEL_1, IIC_SLVAE_ADDRESS, master_send_data, sizeof(master_send_data));
/* Master wait for the slave to prepare data */
while(gpio_get_pin_value(GPIO_PORT_A, GPIO_BIT_0));
/* Master receive data from slave via i2c port */
ql_i2c_master_receive(QL_I2C_CHANNEL_1, IIC_SLVAE_ADDRESS, ql_master_recv_data, &ql_master_recv_len);
ql_debug("MASTER -> RECV DATA FROM SLAVE, DATA LENGTH:%d\r\n", ql_master_recv_len);
for (uint32_t i = 0; i < ql_master_recv_len; i++)
{
ql_debug("%02X ", ql_master_recv_data[i]);
}
ql_debug("\r\n");
ql_sys_delay_100us(10000);
}
}
将两个模块 PA6、PA7、PA0 引脚分别互相连接,其中 PA0 作为从机数据准备的完成的标志引脚。I2C 从机收到主机传输的数据会将收到的数据打印出来并将数据传输回主机,分别烧录主机和从机的代码到模块。串口调试图如下图所示。

术语缩写
| 缩略语 | 英文全称 | 中文全称 |
|---|---|---|
| ADC | Analog-to-Digital Converter | 模数转换器 |
| API | Application Programming Interface | 应用程序接口 |
| CLK | Clock | 时钟 |
| CPHA | Clock Phase | 时钟相位 |
| CPOL | Clock Polarity | 时钟极性 |
| CS | Chip Select | 片选引脚 |
| EVB | Evaluation Board | 评估板 |
| GPIO | General-Purpose Input/Output | 通用型输入/输出 |
| I2C | Inter-Integrated Circuit | 内置集成电路总线 |
| IoT | Internet of Things | 物联网 |
| PMU | Power Management Unit | 电源管理单元 |
| PWM | Pulse Width Modulation | 脉冲宽度调制 |
| RTOS | Real-Time Operating System | 实时操作系统 |
| SCK | Serial Clock | 串行时钟 |
| SCL | Serial Clock Line | 串行时钟线 |
| SDA | Serial Data Line | 串行数据线 |
| SDK | Software Development Kit | 软件开发工具包 |
| SPI | Serial Peripheral Interface | 串行外设接口 |
| UART | Universal Asynchronous Receiver/Transmitter | 通用异步收发传输器 |

