TWEN-ASR ONE 语音识别系列教程(2)--- GPIO、ADC、PWM的使用

TWEN-ASR ONE 语音识别系列教程(2)— GPIO、ADC、PWM的使用
提示:作者使用 TWEN-ASR ONE V1.0开发板进行开发学习。



前言

    通过《TWEN-ASR 语音识别系列教程(1)—运行第一个程序》文章,我们学习了如何编写一个TWEN-ASR程序、下载程序、调试程序。从上文可知,TWEN-ASR ONE开发板引脚丰富,引脚主要功能有GPIO、ADC、PWM、 UART、IIC、SPI。本文将介绍TWEN-ASR ONE的GPIO、ADC、PWM使用。 主要内容有:

  • TWEN-ASR GPIO读写操作;
  • TWEN-ASR ADC获取当前电压值;
  • TWEN-ASR 根据ADC的值,使用PWM调节红灯的亮度。

一、TWEN-ASR ONE GPIO读写操作

1.1 GPIO 使用说明

    了解GPIO使用前,先了解TWEN-ASR ONE芯片的一些信息,如下图所示芯片引脚信息图。
在这里插入图片描述

图1.1 TWEN-ASR ONE 引脚信息图

    TWEN-ASR GPIO可支持27个GPIO口(IO功能复用)、每个GPIO口可配置中断功能、支持两路带滤波功能外部中断。因为IO功能复用,所以GPIO工作前需要选择引脚功能。当然如果使用默认的话,可以不设置。 例如P0_0引脚功能[1]如下图1.2 引脚功能描述图所示:
在这里插入图片描述

图1.2 引脚功能描述图

从上图1.2可以看出,P0_0是芯片的第4引脚,IO口有4mA的驱动能力。默认是输入模式。T+D表示三态下拉。具体的状态定义如下表1.1所示。

表1.1 状态定义表
缩写含义
I输入
O输出
IO双向
P电源或地
T+D三态下拉
T+U三态上拉
OUT上电默认为输出模式
IN上电默认为输入模式

    功能选择。可以不看手册,直接在图形IO的名称上,就可以看出。P0_0-3,默认功能就是模拟功能。例如P0_5引脚。在图形块中可以看出:第一功能空,第二功能是GPIO,第三功能UART1_TX;图形块已经设置好。 输入模式对应读取引脚,输出模式对应写引脚。
在这里插入图片描述

图1.3 P0_5设置引脚块

如果你想查看关于引脚功能描述更多内容,请参考文章【1】。下载地址:天问ASR-ONE芯片手册
    GPIO 有输入、输出、中断模式。 其中中断模式可以设置为高电平、低电平、上升沿、下降沿、双边沿触发。如下图所示:
在这里插入图片描述

图1.4 中断相关程序块

一般引脚触发中断后,在程序块里面读取引脚是否有中断,有中断的话,执行中断代码。中断代码里面用清除中断引脚标志位。

1.2 GPIO 代码编写

    根据前面的分析,如果我们使用P0_0为GPIO的输入输出引脚,需要设定为第一功能引脚。同时根据使用需求,设置为输入模式、输出、中断触发。
    (1)P0_0输出模式测试程序。 实现程序主要是通过P0_0输出高低电平,控制灯的亮灭。 电路原理图如下:
在这里插入图片描述

图1.5 P0_0外接扩展电路图

其中,高电平红灯灭,低电平红灯亮。 这与官方的板载RGB灯恰好相反。具体代码编写如下:

  • 图形代码:
    在这里插入图片描述
图1.6 P0_0输出模式测试程序图
  • 字符代码:
#include "asr.h"
#include "setup.h"

uint32_t snid;
void ASR_CODE();

//{ID:250,keyword:"命令词",ASR:"最大音量",ASRTO:"音量调整到最大"}
//{ID:251,keyword:"命令词",ASR:"中等音量",ASRTO:"音量调整到中等"}
//{ID:252,keyword:"命令词",ASR:"最小音量",ASRTO:"音量调整到最小"}
void app(){
  while (1) {
    digitalWrite(0,1);
    delay(1000);
    digitalWrite(0,0);
    delay(1000);
  }
vTaskDelete(NULL);
}
/*描述该功能...
*/
void ASR_CODE(){
  if((snid) == 4){
    digitalWrite(13,1);
  }
  if((snid) == 6){
    digitalWrite(13,0);
  }
}

void setup()
{
  //{speak:小蝶-清新女声,vol:10,speed:10}
  //{playid:10001,voice:欢迎使用智能管家,用智能管家唤醒我。}
  //{playid:10002,voice:我退下了,用智能管家唤醒我}
  //{ID:2,keyword:"唤醒词",ASR:"智能管家",ASRTO:"我在"}
  //{ID:4,keyword:"命令词",ASR:"打开红灯",ASRTO:"好的,马上打开红灯"}
  //{ID:6,keyword:"命令词",ASR:"关闭红灯",ASRTO:"好的,马上关闭红灯"}
  setPinFun(0,FIRST_FUNCTION);
  pinMode(0,output);
  xTaskCreate(app,"app",128,NULL,4,NULL);

}

    (2)P0_0输入模式。 实现程序主要是按键按下,P0_0获取到高电平;按键松开,P0_0获取到低电平。 电路原理图如下:
在这里插入图片描述

图1.7 P0_0 按键输入接线图

也许有人会疑问为什么KEY1 1引脚接3.3V。因为P0_0默认T+D(三态下拉),即默认P0_0悬空的情况下,读取到的是低电平。 所以KEY1 1引脚接3.3V,当按键KEY1按下时,P0_0读取到高电平,松开按键KEY1读取到低电平。

  • 图形代码:
    在这里插入图片描述
图1.8 P0_0输入模式程序图
  • 字符代码:
#include "asr.h"
#include "setup.h"
#include "HardwareSerial.h"

uint32_t snid;
void ASR_CODE();

//{ID:250,keyword:"命令词",ASR:"最大音量",ASRTO:"音量调整到最大"}
//{ID:251,keyword:"命令词",ASR:"中等音量",ASRTO:"音量调整到中等"}
//{ID:252,keyword:"命令词",ASR:"最小音量",ASRTO:"音量调整到最小"}
void app(){
  while (1) {
    Serial.println((digitalRead(0)));
    delay(1000);
  }
vTaskDelete(NULL);
}
/*描述该功能...
*/
void ASR_CODE(){
  if((snid) == 4){
    digitalWrite(13,1);
  }
  if((snid) == 6){
    digitalWrite(13,0);
  }
}

void setup()
{
  Serial.begin(9600);
  //{speak:小蝶-清新女声,vol:10,speed:10}
  //{playid:10001,voice:欢迎使用智能管家,用智能管家唤醒我。}
  //{playid:10002,voice:我退下了,用智能管家唤醒我}
  //{ID:2,keyword:"唤醒词",ASR:"智能管家",ASRTO:"我在"}
  //{ID:4,keyword:"命令词",ASR:"打开红灯",ASRTO:"好的,马上打开红灯"}
  //{ID:6,keyword:"命令词",ASR:"关闭红灯",ASRTO:"好的,马上关闭红灯"}
  setPinFun(0,FIRST_FUNCTION);
  pinMode(0,input);
  xTaskCreate(app,"app",128,NULL,4,NULL);

}

    (3)P0_0中断模式。 中断属于输入,实现程序主要是P0_0中断相应会进行计数,并且用串口打印输出。 电路原理图如图1.7 P0_0 按键输入接线图所示。
在这里插入图片描述

图1.9 中断测试程序
#include "asr.h"
#include "setup.h"
#include "HardwareSerial.h"

uint32_t snid;
uint8_t Counter = 0;
void ASR_CODE();

//{ID:250,keyword:"命令词",ASR:"最大音量",ASRTO:"音量调整到最大"}
//{ID:251,keyword:"命令词",ASR:"中等音量",ASRTO:"音量调整到中等"}
//{ID:252,keyword:"命令词",ASR:"最小音量",ASRTO:"音量调整到最小"}
void GPIO0_irq(){
  if(gpio_get_irq_status(0)){
    Clear_GPIO_irq(0);
    Counter = Counter + 1;
    Serial.println(Counter);
  }

}
/*描述该功能...
*/
void ASR_CODE(){
  if((snid) == 4){
    digitalWrite(13,1);
  }
  if((snid) == 6){
    digitalWrite(13,0);
  }
}

void setup()
{
  Serial.begin(9600);
  //{speak:小蝶-清新女声,vol:10,speed:10}
  //{playid:10001,voice:欢迎使用智能管家,用智能管家唤醒我。}
  //{playid:10002,voice:我退下了,用智能管家唤醒我}
  //{ID:2,keyword:"唤醒词",ASR:"智能管家",ASRTO:"我在"}
  //{ID:4,keyword:"命令词",ASR:"打开红灯",ASRTO:"好的,马上打开红灯"}
  //{ID:6,keyword:"命令词",ASR:"关闭红灯",ASRTO:"好的,马上关闭红灯"}
  pinMode(0,input);
  setPinFun(0,FIRST_FUNCTION);
  pinMode(0,input);
  Set_GPIO_irq(0,up_edges_trigger,GPIO0_irq);

}

1.3 GPIO 代码分析

    如果上面的代码含义明白可以跳过【1.3节代码分析】。不太清楚,可以参考下面的代码分析。

    (1)P0_0输出模式测试程序分析。

  • 初始化:
    • 设置引脚功能为第一引脚功能;
    • 设置输出模式。
  • 线程中写操作:
    • 使用写引脚块,可设置为高,低电平。

在线程中,重复执行P0_0高电平,低电平。中间延时一秒钟。关键代码注释如下:

在这里插入图片描述

图1.10 P0_0输出模式程序注释图

    (2)P0_0输入模式测试程序分析。

  • 初始化:

    • 设置串口0波特率为9600;
    • 设置引脚功能为第一引脚功能;
    • 设置输入模式。
  • 线程中读操作:

    • 使用读引脚块,读取的内容通过串口打印出来。

在线程中,每秒钟读取P0_0状态,并通过串口打印出来。关键代码注释如下:
在这里插入图片描述

图1.11 P0_0输入模式程序注释图

    (3)P0_0中断测试程序分析。 P0_0上升沿触发中断,进入中断服务程序块后,首先会判断是否有中断,如有中断清空中断,执行中断服务程序。在中断里Counter会增加1,最后串口打印Counter的值。
在这里插入图片描述

图1.12 中断测试程序注释

1.4 GPIO 运行测试

    (1)P0_0输出模式程序运行测试。 红灯闪烁,红灯每间隔一秒亮或灭。输出高电平红灯灭,输出高电平红灯亮。
在这里插入图片描述

图1.13 P0_0输出高电平红灯灭

在这里插入图片描述

图1.14 P0_0输出低电平红灯亮

    (2)P0_0输入模式程序运行测试。 当松开按键读取到低电平,当按键按下时,P0_0读取到高电平。具体测试结果如下图所示。
在这里插入图片描述

图1.15 P0_0输入模式松开按键

在这里插入图片描述

图1.16 P0_0输入模式按下按键

    (3)P0_0中断程序运行测试。 当松开按键按下时,P0_0会变化成高电平,即上升沿,会触发中断服务程序。由于按键被按下后,会有抖动。即按键按下后,可能会多次触发中断。如下测试,我是按了6次按键。中断执行了19次。

在这里插入图片描述

图1.17 按6次按键,中断触发次数结果

再按两次按键,结果如下所示:
在这里插入图片描述

图1.18 再按2次,中断触发次数结果

1.5 GPIO 使用小结

    GPIO的使用,一般需要设置功能引脚,设置输入、输出模式,输入模式对应读取引脚状态,输出模式对应输出高或低电平。实际使用设置功能引脚需要查看芯片引脚功能描述。而输入或输出模式则需要根据实际使用情况设置。GPIO可设置为中断,中断触发中断服务程序块执行。


二、TWEN-ASR ONE ADC读取操作

2.1 ADC 使用说明

    TWEN-ASR ONE ADC拥有4路12bit SAR ADC输入通道。 ADC IO可与数字GPIO进行功能复用。从图1.1 TWEN-ASR ONE 引脚信息图,可知ADC 引脚分别是AIN0~AIN3,对应是P0_0 ~P0_3。因为IO复用特别需要注意功能引脚设置。而ADC是默认的功能。所以使用ADC无需另外设置功能引脚。

2.2 ADC 代码编写

    实现程序主要是读取AIN0数值,并进行电压换算,最后用串口打印电压值。 关于电压的换算,由于TWEN-ASR是12位的ADC,那么读取的范围0 ~(212 - 1),即0 ~ 4095。0对应电压为0V,4095对应3.3V(参考电压)。读取数值和电压是线性关系,换算公式1如下:

U = V a l 4095 ∗ 3.3 v U=\frac{Val}{4095}*3.3v U=4095Val3.3v

--- 公式1

其中, V a l Val Val是读取的ADC值, U U U是换算出来的电压值。测试ADC将会使用滑动电位器, 测试电路原理如下图2.1所示:
在这里插入图片描述

图2.1 ADC测试接线图

其中,P0_0对应AIN0,滑到最左边电压为3.3V,滑到最右边电压为0V。

  • 图形代码:
    在这里插入图片描述
图2.2 ADC测试程序图
  • 字符代码:
#include "asr.h"
#include "setup.h"
#include "HardwareSerial.h"

uint32_t snid;
float res = 0;
void ASR_CODE();

//{ID:250,keyword:"命令词",ASR:"最大音量",ASRTO:"音量调整到最大"}
//{ID:251,keyword:"命令词",ASR:"中等音量",ASRTO:"音量调整到中等"}
//{ID:252,keyword:"命令词",ASR:"最小音量",ASRTO:"音量调整到最小"}
void app(){
  while (1) {
    Serial.print("U=");
    Serial.print(((adc_read(0) / 4096.0) * 3.3));
    Serial.println("V");
    delay(1000);
  }
vTaskDelete(NULL);
}
/*描述该功能...
*/
void ASR_CODE(){
  switch (snid) {
   case 4:
    digitalWrite(13,1);
    break;
   case 6:
    digitalWrite(13,0);
    break;
  }
}

void setup()
{
  Serial.begin(9600);
  //{speak:小蝶-清新女声,vol:10,speed:10}
  //{playid:10001,voice:欢迎使用智能管家,用智能管家唤醒我。}
  //{playid:10002,voice:我退下了,用智能管家唤醒我}
  //{ID:2,keyword:"唤醒词",ASR:"智能管家",ASRTO:"我在"}
  //{ID:4,keyword:"命令词",ASR:"打开红灯",ASRTO:"好的,马上打开红灯"}
  //{ID:6,keyword:"命令词",ASR:"关闭红灯",ASRTO:"好的,马上关闭红灯"}
  xTaskCreate(app,"app",128,NULL,4,NULL);

}

2.3 ADC 代码分析

    如果上面的代码含义明白可以跳过【2.3 ADC 代码分析】。不太清楚,可以参考下面的代码分析。
    P0_0引脚默认是ADC功能引脚,所以不需要设置功能引脚。 在线程app里面,"读入ADC值AN0"就是读取AIN0的值,并根据公式1进行电压换算。
在这里插入图片描述

图2.3 ADC测试程序注释图

2.4 ADC 运行测试

    程序下载完后,打开串口监视器。
在这里插入图片描述

图2.4 万用表与串口打印数据比较(1)图

由上图可知,串口打印出U=3.3 V,而实际万用表测出来是3.608V,误差有0.308V左右。因为参考电压选用了3.3V,而实际是3.608V。当我再次测量ASR-ONE 3.3V引脚时,实测电压为3.637V。所以修改程序为:
在这里插入图片描述

图2.5 根据实测3.3V引脚电压,修改程序图

调节滑动电位器,到最左端。万用表实测电压为3.640V,串口输出为3.63V或3.64V。可见经过修改参考值后,数据与万用表接近。
在这里插入图片描述

图2.6 万用表与串口打印数据比较(2)图

再次调节滑动电位器。万用表实测电压为2.275V,串口输出为2.27、2.28、2.29V。可见数据与万用表接近。误差还是很小的,在接受范围内。
在这里插入图片描述

图2.7 万用表与串口打印数据比较(3)图

2.5 ADC 使用小结

     ADC 使用不需要设置功能引脚,因为默认就是ADC功能。ADC 引脚分别是AIN0~AIN3,对应是P0_0 ~P0_3。本文使用P0_0进行测试,可见ADC使用,需要对参考电压的修正,才能准确测量出电压值。当然如果使用稳压管的电压作为参考电压,这样就不用修正。或者ASR-ONE是否有内部的基准电压可用。想要用好ASR-ONE的ADC还需要对芯片更多的了解。


三、TWEN-ASR ONE PWM使用

3.1 PWM 使用说明

    PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进行调制,等效出所需要的波形(包含形状以及幅值),对模拟信号电平进行数字编码,也就是说通过调节占空比的变化来调节信号、能量等的变化,占空比就是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,例如方波的占空比就是50%[2]
在这里插入图片描述

图3.1 PWM占空比示意图

    在天问Block软件中,有两个PWM相关的块。使用PWM只需要进行PWM初始化,设置占空比、初始值、调整占空比。
在这里插入图片描述

图3.2 天问Block PWM相关块

3.2 PWM 代码编写

    实现程序主要是读取AIN0数值,根据读到的数值,调节板载RGB灯的绿灯的亮度,值越大亮度越大,反之,亮度越小。 RGB灯的电路原理图如下所示:
在这里插入图片描述

图3.3 RGB灯电路原理图

其中,PWM5是控制绿灯。

  • 图形代码:
    在这里插入图片描述
图3.4 PWM测试程序图
  • 字符代码:
#include "asr.h"
#include "setup.h"

uint32_t snid;
void ASR_CODE();

//{ID:250,keyword:"命令词",ASR:"最大音量",ASRTO:"音量调整到最大"}
//{ID:251,keyword:"命令词",ASR:"中等音量",ASRTO:"音量调整到中等"}
//{ID:252,keyword:"命令词",ASR:"最小音量",ASRTO:"音量调整到最小"}
void app(){
  while (1) {
    pwm_set_duty(PWM5,adc_read(0),0x1000);
    delay(50);
  }
vTaskDelete(NULL);
}
/*描述该功能...
*/
void ASR_CODE(){
  if((snid) == 4){
    digitalWrite(13,1);
  }
  if((snid) == 6){
    digitalWrite(13,0);
  }
}

void setup()
{
  //{speak:小蝶-清新女声,vol:10,speed:10}
  //{playid:10001,voice:欢迎使用智能管家,用智能管家唤醒我。}
  //{playid:10002,voice:我退下了,用智能管家唤醒我}
  //{ID:2,keyword:"唤醒词",ASR:"智能管家",ASRTO:"我在"}
  //{ID:4,keyword:"命令词",ASR:"打开红灯",ASRTO:"好的,马上打开红灯"}
  //{ID:6,keyword:"命令词",ASR:"关闭红灯",ASRTO:"好的,马上关闭红灯"}
  setPinFun(14,SECOND_FUNCTION);
  PWM_enble(PWM5,1000,0x1000,0x000);
  pwm_set_duty(PWM5,adc_read(0),0x1000);
  xTaskCreate(app,"app",128,NULL,4,NULL);

}

3.3 PWM 代码分析

    如果上面的代码含义明白可以跳过【3.3 PWM 代码分析】。不太清楚,可以参考下面的代码分析。
PWM 频率设置为1000,最大占空比为0x1000。这么设置是因为ADC最大值为0xFFF。
在这里插入图片描述

图3.5 PWM测试程序注释图

3.4 PWM 运行测试

    调节电位器的大小。AIN0读到值大时,灯会比较亮。如下图所示:
在这里插入图片描述

图3.6 ADC数值较大时

    AIN0读到值小时,灯会比较暗。如下图所示:

在这里插入图片描述

图3.7 ADC数值较小时

改变PWM占空比,相当于改变PWM5引脚的电压值,从而达到调节亮度的目的。

3.5 PWM 使用小结

    在天问Block软件里面,PWM使用非常便捷,设置频率,设置占空比。PWM块有PWM0~PWM5可以使用。PWM在控制直流电机速度、LED灯亮度等等场合应用比较多,使用ASR-ONE可以快速的实现想要的效果。


四、总结

    本文介绍TWEN-ASR ONE的GPIO、ADC、PWM使用。GPIO使用,设置功能引脚,设置为输入输出模式。ADC使用,需要注意参考电压,12位ADC的数值范围为0~4095。PWM使用,设置频率,占空比。TWEN-ASR-ONE总体来说,不管GPIO、ADC、PWM编程实现非常方便,有很多块可以使用。


参考文章:
[1] 天问ASR-ONE芯片手册
[2] 什么是PWM信号,如何实现PWM信号输出?

  • 8
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
以下是CLRC66301HN的IIC版本开发例程: 1. 确认硬件连接 首先,需要确认CLRC66301HN芯片的硬件连接是否正确。在IIC版本中,通常使用两个引脚SCL和SDA连接到主控芯片的IIC总线上。请检查这两个引脚是否正确连接。 2. 初始化IIC总线 在开始使用CLRC66301HN芯片之前,需要初始化IIC总线。以下是一个简单的例程,可以初始化IIC总线: ```c void i2c_init(void) { // 初始化IIC总线 // 设置IIC时钟频率为100kHz TWBR = 72; // 打开IIC总线 TWCR = (1 << TWEN); } ``` 3. 写入寄存器 在使用CLRC66301HN芯片之前,需要将一些寄存器设置为正确的值。以下是一个写入寄存器的例程: ```c void write_register(uint8_t reg, uint8_t value) { // 发送起始信号 TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); // 检查状态码 if ((TWSR & 0xF8) != TW_START) return; // 发送从地址和写入位 TWDR = CLRC66301HN_I2C_ADDR << 1; TWCR = (1 << TWINT) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); // 检查状态码 if ((TWSR & 0xF8) != TW_MT_SLA_ACK) return; // 发送寄存器地址 TWDR = reg; TWCR = (1 << TWINT) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); // 检查状态码 if ((TWSR & 0xF8) != TW_MT_DATA_ACK) return; // 发送数据 TWDR = value; TWCR = (1 << TWINT) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); // 检查状态码 if ((TWSR & 0xF8) != TW_MT_DATA_ACK) return; // 发送停止信号 TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); } ``` 这个例程将一个字节写入指定的寄存器中。 4. 读取寄存器 如果需要读取CLRC66301HN芯片中的某个寄存器的值,可以使用以下例程: ```c uint8_t read_register(uint8_t reg) { uint8_t value = 0; // 发送起始信号 TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); // 检查状态码 if ((TWSR & 0xF8) != TW_START) return 0; // 发送从地址和写入位 TWDR = CLRC66301HN_I2C_ADDR << 1; TWCR = (1 << TWINT) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); // 检查状态码 if ((TWSR & 0xF8) != TW_MT_SLA_ACK) return 0; // 发送寄存器地址 TWDR = reg; TWCR = (1 << TWINT) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); // 检查状态码 if ((TWSR & 0xF8) != TW_MT_DATA_ACK) return 0; // 发送重启信号 TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); // 检查状态码 if ((TWSR & 0xF8) != TW_REP_START) return 0; // 发送从地址和读取位 TWDR = (CLRC66301HN_I2C_ADDR << 1) | 0x01; TWCR = (1 << TWINT) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); // 检查状态码 if ((TWSR & 0xF8) != TW_MR_SLA_ACK) return 0; // 读取数据 TWCR = (1 << TWINT) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); value = TWDR; // 发送停止信号 TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); return value; } ``` 这个例程将返回指定寄存器中存储的一个字节的值。 5. 总结 这是一个非常简单的CLRC66301HN IIC版本的开发例程。您可以将其用作基础,以构建更复杂的应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

初五霸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值