色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

以RISC-V架構的D1 Dock Pro和D1 Nezha開發板

芯片開放社區 ? 來源:玄鐵杯第二屆RISC-V應用創 ? 作者:玄鐵杯第二屆RIS ? 2022-12-19 10:20 ? 次閱讀

本項目以RISC-V架構的D1 Dock Pro和D1 Nezha開發板為硬件平臺,應用物聯網區塊鏈技術,設計開發一套分布式能源智慧管理小型示范系統,在該系統上實現能源生產和消費數據的實時監測。該項目在“玄鐵杯第二屆RISC-V應用創新大賽”活動中榮獲一等獎。

關于分布式能源智慧管理和M2M交易系統的技術細節,請看本文詳細介紹。

01項目介紹

能源和環保是關乎人類未來的重要課題。為實現碳中和目標,大力發展可再生清潔能源以替代傳統化石能源,提高能源系統監控和消費的智能化水平,是可行的重要途徑之一。本項目以RISC-V架構的D1 Dock Pro和D1 Nezha開發板為硬件平臺,應用物聯網和區塊鏈技術,設計開發一套分布式能源智慧管理小型示范系統,在該系統上實現能源生產和消費數據的實時監測。

02技術方案

項目使用 D1 Dock Pro 開發板設計開發一款專用網關,實時采集電池控制器、氣象環境傳感器等其它傳感器的數據,并通過無線通信方式(WiFi)以HTTP協議或MQTT協議將傳感器數據上傳至物聯網后臺。

17570832-7f43-11ed-8abf-dac502259ad0.jpg??

圖1.專用網關示意

1791faaa-7f43-11ed-8abf-dac502259ad0.jpg

圖2.專用網關實物圖

智能開關用于能源消費端,實現對能源消費者(電器負載)的供電控制、電能消費數據的采集和傳輸等功能。該智能開關基于 D1 Dock Pro 開發板進行設計開發,通過開發板的I/O口控制繼電器、UART接收電能計量模塊的數據。設計一個擴展電路板與開發板配合使用,擴展電路板集成電能計量模塊、繼電器等。本文設計的智慧開關的功能主要是控制電器開關與計量電器用電參數以及環境參數并上傳到云端服務器。

17c2c180-7f43-11ed-8abf-dac502259ad0.jpg

圖3.智能開關示意圖

17f22718-7f43-11ed-8abf-dac502259ad0.jpg

圖4.智能開關實物圖

03核心業務代碼

3.1智能開關電能采集分析

// sensor variable
float sensor_data[9] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9};
int recv_cmd; 
unsigned long Voltage_data, Current_data, Power_data, Energy_data, Pf_data, CO2_data, HZ;

// read the consumer date
void read_consumer_data(void)
{

//send the instruction
unioncrc_data
{
unsigned int word16;
unsigned char byte[2];
} crc_now;

tx_buffer[0] = 0x01;
tx_buffer[1] = 0x03;
tx_buffer[2] = 0x01;
tx_buffer[3] = 0x00;
tx_buffer[4] = 0x02;
tx_buffer[5] = 0x08;
crc_now.word16 = chk_crc(tx_buffer, 6);
tx_buffer[6] = crc_now.byte[1];//CRC verification
tx_buffer[7] = crc_now.byte[0];

ret = csi_uart_send_async(&g_uart, tx_buffer,8);
//wait until send finished
while(1) {
if (tx_async_flag) {
tx_async_flag = 0;
break;
}
}

printf("send succeed
");
   ret = csi_uart_receive_async(&g_uart, rx_buffer, 1);
   //wait until receieve  finished
   while(1) {
//   printf("not_receieved
");
   aos_msleep(200);
     if (rx_async_flag) {
         break;
     }
   }


  printf("Line 358: got data");
  parse_data();
  publish_sensor_data(client, "publish");
  
}

//analyze the consumer date
void parse_data(void)
{
csi_error_t ret;
unsigned char i;
union crc_data
{
unsigned int word16;
unsigned char byte[2];
} crc_now;

if (rx_async_flag == 1){ // check if receieve finished
rx_async_flag = 0;
if ((rx_buffer[0] == 0x01)) { //check the ID of the device
crc_now.word16 = chk_crc(rx_buffer, recieve_data_num - 2);//crc verification
if ((crc_now.byte[0] == rx_buffer[recieve_data_num - 1]) && (crc_now.byte[1] == rx_buffer[recieve_data_num - 2])) {
//parse voltage
Voltage_data = (((unsigned long)(rx_buffer[3])) << 24) | (((unsigned long)(rx_buffer[4])) << 16) | (((unsignedlong)(rx_buffer[5])) << 8) | rx_buffer[6];
sensor_data[0] = (float)(Voltage_data * 0.0001);

//parse current
Current_data = (((unsigned long)(rx_buffer[7])) << 24) | (((unsigned long)(rx_buffer[8])) << 16) | (((unsignedlong)(rx_buffer[9])) << 8) | rx_buffer[10];
sensor_data[1] = (float)(Current_data * 0.0001);

//parse power
Power_data = (((unsignedlong)(rx_buffer[11])) << 24) | (((unsigned long)(rx_buffer[12])) << 16) | (((unsignedlong)(rx_buffer[13])) << 8) | rx_buffer[14];
sensor_data[2] = (float)(Power_data * 0.0001);

//parse energy
Energy_data = (((unsignedlong)(rx_buffer[15])) << 24) | (((unsigned long)(rx_buffer[16])) << 16) | (((unsignedlong)(rx_buffer[17])) << 8) | rx_buffer[18];
sensor_data[3] = (float)(Energy_data * 0.0001);

//parse power factor
Pf_data = (((unsignedlong)(rx_buffer[19])) << 24) | (((unsigned long)(rx_buffer[20])) << 16) | (((unsignedlong)(rx_buffer[21])) << 8) | rx_buffer[22];
sensor_data[4] = (float)(Pf_data * 0.001);

//parse CO2
CO2_data = (((unsigned long)(rx_buffer[23])) << 24) | (((unsigned long)(rx_buffer[24])) << 16) | (((unsignedlong)(rx_buffer[25])) << 8) | rx_buffer[26];
sensor_data[5] = (float)(CO2_data * 0.0001);

//parse frequency of the Single phase alternating current
HZ = (((unsigned long)(rx_buffer[31])) << 24) | (((unsigned long)(rx_buffer[32])) << 16) | (((unsignedlong)(rx_buffer[33])) << 8) | rx_buffer[34];
sensor_data[6] = (float)(HZ * 0.01);

} else {
printf("CRC_error
");
}
}

} else {
printf("receieve_not_finished
");
  }
}
// EOF uart

3.2MQTT電能數據上云

// mqtt 
char pub_topic[] = "wattnode/data"; 
char sub_topic[] = "wattnode/cmd"; 
mqtt_client_t *client;
int is_mqtt_ready = 0;

void mqtt_do_connect(mqtt_client_t *client);
static void mqtt_incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags);
void publish_sensor_data(mqtt_client_t *client, void *arg);

/* Called when publish is complete either with sucess or failure */
static void mqtt_pub_request_cb(void *arg, err_t result)
{
  if(result != ERR_OK) {
    printf("Publish result: %d
", result);
  }
}

/* The idea is to demultiplex topic and create some reference to be used in data callbacks
   Example here uses a global variable, better would be to use a member in arg
   If RAM and CPU budget allows it, the easiest implementation might be to just take a copy of
   the topic string and use it in mqtt_incoming_data_cb
*/
static int inpub_id;
static void mqtt_incoming_publish_cb(void *arg, const char *topic, u32_t tot_len)
{
  printf("Incoming publish at topic %s with total length %u
", topic, (unsigned int)tot_len);

  /* Decode topic string into a user defined reference */
  if(strcmp(topic, "print_payload") == 0) {
    inpub_id = 0;
  } else if(topic[0] == 'A') {
    /* All topics starting with 'A' might bwhile(1)e handled at the same way */
    inpub_id = 1;
  } else {
    /* For all other topics */
    inpub_id = 2;
  }
}

static void mqtt_sub_request_cb(void *arg, err_t result)
{
  /* Just print the result code here for simplicity, 
     normal behaviour would be to take some action if subscribe fails like 
     notifying user, retry subscribe or disconnect from server */
    printf("Subscribe result: %d
", result);
}

static void mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status)
{
  err_t err;
  if(status == MQTT_CONNECT_ACCEPTED) {
    printf("mqtt_connection_cb: Successfully connected
");
    
    /* Setup callback for incoming publish requests */
    mqtt_set_inpub_callback(client, mqtt_incoming_publish_cb, mqtt_incoming_data_cb, arg);
    
    /* Subscribe to a topic named "subtopic" with QoS level 1, call mqtt_sub_request_cb with result */ 
    err = mqtt_subscribe(client, sub_topic, 1, mqtt_sub_request_cb, arg);

    if(err != ERR_OK) {
      printf("mqtt_subscribe return: %d
", err);
    }

    printf("ready to read data");

    is_mqtt_ready = 1;

  } else {
    printf("mqtt_connection_cb: Disconnected, reason: %d
", status);
    
    /* Its more nice to be connected, so try to reconnect */
    mqtt_do_connect(client);
  }  
}

static void mqtt_incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
{
  printf("Incoming publish payload with length %d, flags %u
", len, (unsigned int)flags);

  if(flags & MQTT_DATA_FLAG_LAST) {
    /* Last fragment of payload received (or whole part if payload fits receive buffer
       See MQTT_VAR_HEADER_BUFFER_LEN)  */

    /* Call function or do action depending on reference, in this case inpub_id */
    if(inpub_id == 0) {
      /* Don't trust the publisher, check zero termination */
      if(data[len-1] == 0) {
        //printf("mqtt_incoming_data_cb: %s
", (const char *)data);
      }
    } else if(inpub_id == 1) {
      /* Call an 'A' function... */
    } else {
    //   printf("mqtt_incoming_data_cb: Ignoring payload...
");
        // printf("mqtt_incoming_data_cb: %s
", (const char *)data);
        recv_cmd = atoi((const char *)data);



        printf("receive data: %d
", recv_cmd);
    
    }
  } else {
    /* Handle fragmented payload, store in buffer, write to file or whatever */
  }
}

void publish_sensor_data(mqtt_client_t *client, void *arg)
{
    err_t err;
    u8_t qos = 0; /* 0 1 or 2, see MQTT specification */
    u8_t retain = 0; /* No don't retain such crappy payload... */

    const int LEN = 9;
    // cat all float data to string
    char sep = ';';
    // char *prefix = "data=";
    char *prefix = "";
    char _str_data[10];
    char post_str[128];

    strcpy(post_str, prefix);
    for (int i = 0; i < LEN-1; i++) {
        sprintf(_str_data, "%.3f", sensor_data[i]);
        _str_data[strlen(_str_data)-1] = sep;
        strcat(post_str, _str_data);
    }

    sprintf(_str_data, "%.3f", sensor_data[LEN-1]);
    strcat(post_str, _str_data);

    err = mqtt_publish(client, pub_topic, post_str, strlen(post_str), qos, retain, mqtt_pub_request_cb, arg);
    if(err != ERR_OK) {
        printf("Publish err: %d
", err);
    }
}

void mqtt_do_connect(mqtt_client_t *client)
{
    struct mqtt_connect_client_info_t ci;
    err_t err;

    ip4_addr_t ip_addr;
    IP4_ADDR(&ip_addr, 106, 14, 44, 95);

    /* Setup an empty client info structure */
    memset(&ci, 0, sizeof(ci));

    /* Minimal amount of information required is client identifier, so set it here */ 
    ci.client_id = "wattnode1";

    /* Initiate client and connect to server, if this fails immediately an error code is returned
        otherwise mqtt_connection_cb will be called with connection result after attempting 
        to establish a connection with the server. 
        For now MQTT version 3.1.1 is always used */

    err = mqtt_client_connect(client, &ip_addr, MQTT_PORT, mqtt_connection_cb, 0, &ci);

    /* For now just print the result code if something goes wrong */
    if(err != ERR_OK) {
        printf("mqtt_connect return %d
", err);
    }
}

static void mqtt_main_task(void *d)
{
    printf("Enter mqtt_main_task
");
    // mqtt_client_t *client = mqtt_client_new();
    client = mqtt_client_new();
    if(client != NULL) {
        mqtt_do_connect(client);
    }
}
// EOF mqtt

3.3智能開關

// switch variable
const int SWITCH_PIN = PC1;
static csi_gpio_pin_t pin;
#define GPIO_CHECK_RETURN(ret)           
    do {                                 
        if (ret != CSI_OK) {             
            return -1;                   
        }                                
    } while(0);

//init the switch
void switch_init()
{
  ret = csi_gpio_pin_init(&pin, SWITCH_PIN);
  GPIO_CHECK_RETURN(ret);

  /* Set output mode */
  ret = csi_gpio_pin_dir(&pin, GPIO_DIRECTION_OUTPUT);
  GPIO_CHECK_RETURN(ret);
}
// EOF switch

3.4串口處理部分

// uart variable
static csi_uart_t g_uart;
static volatile uint8_t rx_async_flag = 0;
static volatile uint8_t tx_async_flag = 0;
static uint8_t tx_buffer[140];
static uint8_t rx_buffer[140];
int recieve_data_num = 37;
#define DATE_UART_BAUDRATE   4800
#define DATE_UART_IDX 5
#define UART_CHECK_RETURN(ret)                      
        do {                                        
            if (ret != CSI_OK) {                    
                return -1;                          
            }                                       
        } while(0);

// crc function
unsigned int calc_crc(unsigned char crcbuf, unsigned int crc);
unsigned int chk_crc(unsigned char* buf, unsigned char len);

//task
static aos_task_t task_date_uart5;

void date_uart5_entry()
{
   
while(1)
{
switch(recv_cmd){
case 0:
break;
case 1:
csi_gpio_pin_write(&pin, GPIO_PIN_HIGH);
recv_cmd = 0;
break;
case 2:
csi_gpio_pin_write(&pin, GPIO_PIN_LOW);
recv_cmd = 0;
break;
case 3:
read_consumer_data();
recv_cmd = 0;
break;
default:
break;

}//eof switch

aos_msleep(2000);
    }//eof while
}//eof func

//callback function of uart
static void uart_event_cb(csi_uart_t *uart, csi_uart_event_t event, void *arg)
{
  switch (event) {
    case UART_EVENT_SEND_COMPLETE:
      tx_async_flag = 1;
      break;

    case UART_EVENT_RECEIVE_COMPLETE:
      rx_async_flag = 1;
      break;

    default:
      break;
  }//eof switch
}//eof func


void uart_init()
{
  csi_pin_set_mux(PB4, PB4_UART5_TX);
  csi_pin_set_mux(PB5, PB5_UART5_RX);

  /* init uart, DATE_UART_IDX == 5 */
  ret = csi_uart_init(&g_uart, DATE_UART_IDX);
  UART_CHECK_RETURN(ret);

  /* set uart baudrate */
  ret = csi_uart_baud(&g_uart, DATE_UART_BAUDRATE);
  UART_CHECK_RETURN(ret);

  /* set uart format */
  ret = csi_uart_format(&g_uart, UART_DATA_BITS_8, UART_PARITY_NONE, UART_STOP_BITS_1);
  UART_CHECK_RETURN(ret);

  /* attach callback to uart device */
  ret = csi_uart_attach_callback(&g_uart, uart_event_cb, NULL);
  UART_CHECK_RETURN(ret);

}



// calculate crc function
unsigned int calc_crc(unsigned char crcbuf, unsigned int crc)
{
unsigned char i;
unsigned char chk;
crc = crc ^ crcbuf; for (i = 0; i < 8; i++)
{
chk = (unsigned char)(crc & 1);
crc = crc >> 1;
crc = crc & 0x7fff;
if (chk == 1) crc = crc ^ 0xa001;
crc = crc & 0xffff;
}
return crc;
}

// verify crc function
unsigned int chk_crc(unsigned char* buf, unsigned char len)
{
unsigned char hi, lo;
unsigned int i;
unsigned int crc;
crc = 0xFFFF;
for (i = 0; i < len; i++)
{
crc = calc_crc(*buf, crc);
buf++;
}

hi = (unsigned char)(crc % 256);
lo = (unsigned char)(crc / 256);
crc = (((unsigned int)(hi)) << 8) | lo;
return crc;
}

3.5主函數

int main(void)
{
  cxx_system_init();
  board_yoc_init();

  switch_init();
  uart_init();
    
  /* Subscribe */
  event_subscribe(EVENT_NETMGR_GOT_IP, network_event, NULL);
  event_subscribe(EVENT_NETMGR_NET_DISCON, network_event, NULL);
  
  aos_task_new_ext(&task_date_uart5, "task_date_uart5", date_uart5_entry, NULL, 4096, AOS_DEFAULT_APP_PRI);
//  aos_task_new_ext(&uart5_proc, "uart5_proc", data_proc, NULL, 1024, 30);
  
  app_wifi_init();

  // while (1) {
  //   if (is_mqtt_ready == 1) {
  //   //   read_consumer_data();
  //     printf("OK");
  //     // aos_msleep(1000);
  //   }
  //   // test_uart();
    
  //   // aos_msleep(2000);
  // }
}

04問題匯總

uart的配置

在官方的GitBook中對驅動函數進行了詳細地講解并附有相關例程:文檔首頁· GitBook (t-head.cn)

但并未對具體的底層配置修改進行說明,在一開始編寫串口部分的代碼時,一直未能成功初始化并調通串口,在工程師的幫助之下對D1 dock pro的底層配置有了一定的了解。這里以led_demo為例,演示如何在此基礎之上成功配置uart5。

改動1

181fac06-7f43-11ed-8abf-dac502259ad0.png

改動2

184a2e5e-7f43-11ed-8abf-dac502259ad0.png

改動3

189f4ca4-7f43-11ed-8abf-dac502259ad0.png

改動4

191571cc-7f43-11ed-8abf-dac502259ad0.png

做完以上三處改動,即可參考UART·GitBook(t-head.cn)中的使用示例對uart5進行驗證,注意需要先csi_pin_set_mux(PB4,PB4_UART5_TX);和csi_pin_set_mux(PB5,PB5_UART5_RX);

05項目總結

“我們對‘碳中和’比較感興趣,學校也鼓勵我們探索交叉學科,我負責系統架構搭建和區塊鏈技術,另外兩位隊員負責硬件編程及網頁編程。從最初簡單的能源物聯網演示,到利用區塊鏈技術實現M2M自主交易,我們做了很多討論和嘗試,終于在RISC-V平臺上跑通了程序!”“萌新隊”隊長、華東師范大學大四學生龔丹妮說。

審核編輯 :李倩

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 能源系統
    +關注

    關注

    0

    文章

    85

    瀏覽量

    11121
  • 開發板
    +關注

    關注

    25

    文章

    5032

    瀏覽量

    97373
  • RISC-V
    +關注

    關注

    45

    文章

    2270

    瀏覽量

    46129

原文標題:應用速遞 | 摘得頭獎的小隊究竟是做了什么項目?

文章出處:【微信號:芯片開放社區,微信公眾號:芯片開放社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    RISC-V架構及MRS開發環境回顧

    ,華為海思轉向了開源指令集架構RISC-V,針對鴻蒙操作系統的開發者發布了首款RISC-V開發板Hi3861。Hi3861針對的是物聯網市場
    發表于 12-16 23:08

    SiFive 推出高性能 Risc-V CPU 開發板 HiFive Premier P550

    “ ?HiFive Premier P550:世界上性能最高的 RISC-V CPU 開發板 Mini-DTX 外形提供高性能 Linux 開發平臺,支持下一波
    的頭像 發表于 12-16 11:16 ?136次閱讀
    SiFive 推出高性能 <b class='flag-5'>Risc-V</b> CPU <b class='flag-5'>開發板</b> HiFive Premier P550

    如何使用 RISC-V 進行嵌入式開發

    、準備開發環境 選擇開發板RISC-V架構的嵌入式開發板有多種選擇,如GD32VF103R-START、飛凌嵌入式OK113i-S等。選
    的頭像 發表于 12-11 17:32 ?470次閱讀

    Made with KiCad(十六):全志RISC-V 64 SoC F133/D1s開發板

    Linux 的開發板一起推出的全志D1 RISC-V 處理器的低成本版,它和D1的主要區別在于D1s內置的RAM是 64MB DDR2。
    的頭像 發表于 12-04 18:22 ?966次閱讀
    Made with KiCad(十六):全志<b class='flag-5'>RISC-V</b> 64 SoC F133/<b class='flag-5'>D1</b>s<b class='flag-5'>開發板</b>

    【RA8D1試用活動】RA8D1B-CPKCOR開發板移植linux

    【RA8D1試用活動】RA8D1B-CPKCOR開發板移植linux
    的頭像 發表于 11-16 01:02 ?220次閱讀
    【RA8<b class='flag-5'>D1</b>試用活動】RA8<b class='flag-5'>D1</b>B-CPKCOR<b class='flag-5'>開發板</b>移植linux

    香蕉派開發板BPI-CanMV-K230D-Zero 嘉楠科技 RISC-V開發板開發

    K230D Zero 開發板。這款創新的開發板是由嘉楠科技與香蕉派開源社區聯合設計研發,搭載了先進的勘智 K230D 芯片。 K230D
    發表于 11-05 15:29

    香蕉派開發板BPI-CanMV-K230D-Zero 嘉楠科技 RISC-V開發板開發

    科技 K230D RISC-V芯片設計,探索 RISC-V Vector1.0 的前沿技術,選擇嘉楠科技的 Canmv K230D Zero 開發板
    的頭像 發表于 11-05 15:27 ?350次閱讀
    香蕉派<b class='flag-5'>開發板</b>BPI-CanMV-K230<b class='flag-5'>D</b>-Zero 嘉楠科技 <b class='flag-5'>RISC-V</b><b class='flag-5'>開發板</b>公<b class='flag-5'>開發</b>售

    香蕉派 BPI-CanMV-K230D-Zero 采用嘉楠科技 K230D RISC-V芯片設計

    開發板采用的是嘉楠科技Kendryte?系列AIoT芯片中的最新一代SoC芯片K230D。該芯片采用全新的多異構單元加速計算架構,集成了2個RISC-V高能效計算核心,內置新一代KPU
    發表于 07-30 17:43

    在ESP Wemos D1 Mini Pro上將FTDI連接到RX和TX遇到的疑問求解

    我在 ESP Wemos D1 Mini Pro 上將 FTDI 連接到我的 RX 和 TX。我必須物理斷開 Wemos D1 上的 RX 引腳才能刷新新固件。我的猜測是引腳與 Wemos
    發表于 07-10 07:29

    RISC-V最新開發板

    最近市面上有啥新出的RISC-V開發板,可以介紹學習下
    發表于 04-28 22:12

    全志D1s開發板裸機開發之壞境搭建

    的DongshanPI-D1S 開發板。 DongshanPI-D1S 是百問網推出的一款基于 RISC-V 架構的學習裸機、 RTOS 的
    發表于 03-06 13:54

    RISC-V SoC + AI | 在全志 D1「哪吒」開發板上,跑個 ncnn 神經網絡推理框架的 demo

    的為 RISC-V 架構做過適配和優化的神經網絡框架。 本文 是一份教程,步驟騎著步驟 (step by step) 地展示了如何在一塊全新的全志 D1「哪吒」開發板上,跑個 ncnn
    發表于 02-26 10:51

    香蕉派發布RISC-V架構BPI-F3開發板

    2 月 3 日,香蕉派發布了基于 RISC-V 架構處理器的開發板 BPI-F3。該產品配備了由進迭時空研發的八核 K1 CPU 芯片,這是全球第一款達到
    的頭像 發表于 02-03 16:17 ?1152次閱讀

    訊飛智能AI鍵盤D1:融合語音識別與智能交互的前沿科技產品

    訊飛智能AI鍵盤D1——引領未來辦公新潮流隨著科技的飛速發展,訊飛星火認知大模型AI智能鍵盤D1應運而生,這款融合了訊飛星火認知大模型的前沿科技產品,不僅具備三模84鍵矮軸機械鍵盤,還具備智能截圖
    的頭像 發表于 01-03 11:05 ?551次閱讀
    訊飛智能AI鍵盤<b class='flag-5'>D1</b>:融合語音識別與智能交互的前沿科技產品

    科技創新與智能助力:揭秘科大訊飛智能鍵盤D1的獨特魅力

    科技創新與智能助力:揭秘科大訊飛智能鍵盤D1的獨特魅力引言:AI鍵盤賦予普通鍵盤智能化的能力,為移動辦公和語音翻譯等場景提供了更便捷高效的解決方案。在這篇文章中,我們將揭秘科大訊飛智能鍵盤D1的獨特
    的頭像 發表于 01-03 11:02 ?643次閱讀
    科技創新與智能助力:揭秘科大訊飛智能鍵盤<b class='flag-5'>D1</b>的獨特魅力
    主站蜘蛛池模板: 国产成人a一在线观看| 2224x最新网站| 亚洲色图激情小说| 亚洲精品在看在线观看| 野花日本免费完整版高清版动漫| 亚洲视频国产| 97人人添人人澡人人澡人人澡| qvod免费电影| 达达兔欧美午夜国产亚洲| 国产精品手机在线视频| 花蝴蝶在线高清视频观看免费播放| 啦啦啦 中文 日本 韩国 免费| 欧美久久综合网| 探花口爆颜射乳交日韩| 亚洲欧美综合在线中文| 2020国产欧洲精品视频| 草久久久久| 国产午夜一区二区三区免费视频| 久久精品国产欧美| 青柠在线电影高清免费观看| 午夜福利92看看电影80| 在线精品国精品国产不卡| 被强J高H纯肉公交车啊| 国产午夜亚洲精品理论片八戒 | adc我们的永久网址| 国产超碰精久久久久久无码AV| 精品国产99久久久久久麻豆| 牛牛免费视频| 亚洲国产日韩欧美在线a乱码 | 亚洲国产中文字幕在线视频综合| 中文字幕在线观看亚洲视频 | QVOD在线播放| 国产在线综合色视频| 暖暖视频在线高清播放| 午夜福利理论片高清在线| 在线免费观看视频a| 高h喷水荡肉爽文总攻| 久久亚洲网站| 性绞姿始动作动态图| 97caopeng| 国产亚洲精品久久久久小|