本帖最后由 陈哲东 于 2023-1-17 10:56 编辑
概述: 1. ASRPRO有3组串口,UART0 预留为程序升级接口,方便后期升级。如需和其它 MCU 通讯建议使用 UART1 或者 UART2。 2. ASRPRO IO口为3.3V电平,为了可靠性,建议设置TX、RX引脚内部上下电阻无效,同时设置TX为开漏模式,外接上拉电阻到5V,串联电阻,电路示意图如下所示: Arduino UNO(5V单片机)
电路连接: 范例1:ASRPRO语音发送串口控制Arduino执行动作 ASRPRO端程序
Arduino端程序 #include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
String value;
#define LED_PIN 13 #define RELAY_PIN 12
void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only }
mySerial.begin(9600); pinMode(LED_PIN, OUTPUT); pinMode(RELAY_PIN, OUTPUT); }
void loop() { // run over and over if (mySerial.available()) { value = (mySerial.readString()); Serial.println(value); if (value == "LED ON") { digitalWrite(LED_PIN,HIGH); } else if (value == "LED OFF") { digitalWrite(LED_PIN,LOW); } else if (value == "RELAY ON") { digitalWrite(RELAY_PIN,HIGH); } else if (value == "RELAY OFF") { digitalWrite(RELAY_PIN,LOW); } } }
程序效果: 通过用“天问五幺”语音唤醒后,分别说测试语音“打开灯光”、“关闭灯光”、“打开继电器”、“关闭继电器”,Arduino端接收到串口命令后会执行对应引脚的控制和串口打印。
范例2: Arduino发送串口控制ASRPRO播放语音 ASRPRO端程序
Arduino端程序 #include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX void setup() { mySerial.begin(9600); } void loop() { // run over and over mySerial.print("TempAdd"); delay(5000); mySerial.print("TempSub"); delay(5000); }
程序效果: Arduino端间隔5秒串口发送“TempAdd”、"TempSub",ASRPRO接收到串口命令后会马上唤醒自动播报语音“温度增加一度”、“温度减小一度”。
STC(5V单片机)
电路连接: 本案例以P5_0为RX,P5_1为TX举例。P5_0与ASR PRO的TX连接,也就是接在PB7,P5_1与ASR PRO的RX连接,也就是接在PC0,注意STC8的电源插脚接到5V,GND引脚互相连接。
范例:ASRPRO与STC8进行串口通讯语音控制STC8板载灯 ASRPRO端程序
STC8端程序
程序效果: 通过用“天问五幺”语音唤醒后,分别说测试语音“打开板载灯”、“关闭板载灯”控制STC8板载灯亮灭。
STM32(3V单片机)电路连接: ASRPRO的PB7(TX)引脚接STM32的A10(RX)引脚,PC0(RX)引脚接STM32的A9(TX)引脚。
范例1:ASRPRO语音发送串口控制STM32执行动作 ASRPRO端程序
STM32部分程序 main.c #include "stm32f10x.h" #include "usart.h" #include "led.h" #include "delay.h" u16 USART_RX_STA=0; //接收状态标记 static u16 fac_ms = 0; int main(void) { LED_Init(); MyUSART_Init(); delay_init(); while(1) { } }
usart.c v#include "usart.h" #include "led.h"
//重定向C库函数printf到串口,重定向后可使用printf函数 int fputc(int ch,FILE *f) { /* 发送一个字节数据到串口 */ USART_SendData(USART1,(uint8_t) ch); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); return (ch); } //重定向C库函数scanf到串口,重写向后可使用scanf、getchar等函数 int fgetc(FILE *f) { /* 等待串口输入数据 */ while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); return (int)USART_ReceiveData(USART1); } void MyUSART_Init() { /* 定义GPIO、NVIC和USART初始化的结构体 */ GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; USART_InitTypeDef USART_InitStructure; /* 使能GPIO和USART的时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); /* 将USART TX(A9)的GPIO设置为推挽复用模式 */ GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); /* 将USART RX(A10)的GPIO设置为浮空输入模式 */ GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10; GPIO_Init(GPIOA,&GPIO_InitStructure);
/* 配置串口 */ USART_InitStructure.USART_BaudRate=9600; //波特率了设置为9600 USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //不使用硬件流控制 USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx; //使能接收和发送 USART_InitStructure.USART_Parity=USART_Parity_No; //不使用奇偶校验位 USART_InitStructure.USART_StopBits=USART_StopBits_1; //1位停止位 USART_InitStructure.USART_WordLength=USART_WordLength_8b; //字长设置为8位 USART_Init(USART1, &USART_InitStructure);
/* Usart1 NVIC配置 */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2 NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; NVIC_Init(&NVIC_InitStructure);
/*初始化串口,开启串口接收中断 */ USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); /* 使能串口1 */ USART_Cmd(USART1,ENABLE);
} /* USART1中断函数 */ void USART1_IRQHandler(void) { uint8_t ucTemp; //接收数据 if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET) { ucTemp = USART_ReceiveData(USART1); USART_SendData(USART1,ucTemp); if(ucTemp == 0x32) { LED_ON(); } if(ucTemp == 0x33) { LED_OFF(); } } } /* 发送一个字节 */ void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch) { /* 发送一个字节数据到USART */ USART_SendData(pUSARTx,ch);
/* 等待发送数据寄存器为空 */ while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); } /* 发送字符串 */ void Usart_SendString( USART_TypeDef * pUSARTx, char *str) { unsigned int k=0; do { Usart_SendByte( pUSARTx, *(str + k) ); k++; } while(*(str + k)!='\0');
/* 等待发送完成 */ while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) {} }
}
led.c #include "led.h" void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //使能B端口时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB GPIO_SetBits(GPIOB,GPIO_Pin_10); // GPIO_SetBits(GPIOA,GPIO_Pin_8); } void LED_OFF(void) { GPIO_SetBits(GPIOB,GPIO_Pin_10); } void LED_ON(void) { GPIO_ResetBits(GPIOB,GPIO_Pin_10); }
程序效果: 通过用“天问五幺”语音唤醒后,分别说测试语音“打开灯光”、“关闭灯光”,STM32端接收到串口命令后会执行对应引脚的控制和串口打印,“2”代表打开,“1”代表关闭。
范例2:STM32串口发送控制ASRPRO播报语音 ASRPRO端程序
STM32部分程序 main.c #include "stm32f10x.h" #include "usart.h" #include "led.h" #include "delay.h"
u16 USART_RX_STA=0; //接收状态标记 static u16 fac_ms = 0; //void delay_init(void); //void delay_ms(u16 nms); int main(void) { LED_Init(); MyUSART_Init(); delay_init(); while(1) { Usart_SendString( USART1,"LED ON"); LED_ON(); delay_ms(5000); Usart_SendString( USART1,"LED OFF"); LED_OFF(); delay_ms(5000); } }
usart.c #include "usart.h" #include "led.h"
//重定向C库函数printf到串口,重定向后可使用printf函数 int fputc(int ch,FILE *f) { /* 发送一个字节数据到串口 */ USART_SendData(USART1,(uint8_t) ch); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); return (ch); } //重定向C库函数scanf到串口,重写向后可使用scanf、getchar等函数 int fgetc(FILE *f) { /* 等待串口输入数据 */ while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); return (int)USART_ReceiveData(USART1); } void MyUSART_Init() { /* 定义GPIO、NVIC和USART初始化的结构体 */ GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; USART_InitTypeDef USART_InitStructure; /* 使能GPIO和USART的时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); /* 将USART TX(A9)的GPIO设置为推挽复用模式 */ GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); /* 将USART RX(A10)的GPIO设置为浮空输入模式 */ GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10; GPIO_Init(GPIOA,&GPIO_InitStructure);
/* 配置串口 */ USART_InitStructure.USART_BaudRate=9600; //波特率了设置为9600 USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //不使用硬件流控制 USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx; //使能接收和发送 USART_InitStructure.USART_Parity=USART_Parity_No; //不使用奇偶校验位 USART_InitStructure.USART_StopBits=USART_StopBits_1; //1位停止位 USART_InitStructure.USART_WordLength=USART_WordLength_8b; //字长设置为8位 USART_Init(USART1, &USART_InitStructure);
/* Usart1 NVIC配置 */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2 NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; NVIC_Init(&NVIC_InitStructure);
/*初始化串口,开启串口接收中断 */ USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); /* 使能串口1 */ USART_Cmd(USART1,ENABLE);
} /* USART1中断函数 */ void USART1_IRQHandler(void) { uint8_t ucTemp; //接收数据 if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET) { ucTemp = USART_ReceiveData(USART1); USART_SendData(USART1,ucTemp); if(ucTemp == 0x32) { LED_ON(); } if(ucTemp == 0x31) { LED_OFF(); } } }
/* 发送一个字节 */ void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch) { /* 发送一个字节数据到USART */ USART_SendData(pUSARTx,ch);
/* 等待发送数据寄存器为空 */ while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); } /* 发送字符串 */ void Usart_SendString( USART_TypeDef * pUSARTx, char *str) { unsigned int k=0; do { Usart_SendByte( pUSARTx, *(str + k) ); k++; } while(*(str + k)!='\0');
/* 等待发送完成 */ while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) {} }
程序效果: STM32端间隔一段时间串口发送“LED ON”、"LED OFF",ASRPRO接收到串口命令后会马上唤醒自动播报语音“灯光已打开”、“灯光已关闭”。
ESP32(3V单片机)
电路连接: 掌控板的P15引脚的TX,接ASR PRO的RX,也就是接在PB6;P16引脚接到ASR PRORX引脚(PB5),两者的3V引脚互相连接,GND引脚互相连接。
范例:ASR PRO与掌控板进行串口通讯;编写一个程序,通过ASR PRO控制掌控板的板载RGB灯显示不同的颜色。 ASR PRO端程序
掌控板端程序
micro:bit(3V单片机)
电路连接: 在进行串口通信时,两个设备进行双向通信,此时两个设备的RX和TX要交错连接。例如Micro:bit,定义P16为RX口,则要接到ASR PRO的TX上,也就是PA2。Micro:bit的P16引脚的RX,接ASR PRO的TX,也就是接在PA2;P12引脚接到ASR PRO的RX引脚(PA3),两者的3V引脚互相连接,GND引脚互相连接。
范例:ASR PRO与Micro:bit进行串口通讯 ASR PRO程序
Micro:bit程序
程序效果: 按下micro:bit的AB按键,通过串口可以给ASR PRO发送字符串hello和world;当ASR PRO接收到后,就会回复对应的语音;当对ASR PRO说出“打开灯光、关闭灯光”时,ASR PRO和micro:bit的串口信息会显示在micro:bit的点阵屏上。 |