首发极术社区。比如赵易创新GD32F310 MCU有兴趣,欢迎添加微信 aijishu2020 加入GD32技术讨论组。
功能描述
通过mcu与esp01通过uart连接,通过at指令来创建socket连接,接收远程控制灯的指令,实现灯亮、灭、闪; 打开两个串口,usart0(GPIO09-TX,GPIO10-RX)连接esp01,进行收发at指令,usart1(GPIO02-TX,GPIO03-RX)作为log输出口;
效果视频
接线图
ps.电阻不能直接连接EN和3.3V拉一根线也能起来; 有条件的话,可以选esp01s,无电阻。
介绍代码流程
uart0连接esp01、采用中断方式收发数据,检测接收数据OK,ERROR等关键字以后关闭接收。 uart中断
void USART0_IRQHandler(void) { if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) { /* receive data */ rx_buffer[rx_count ] = usart_data_receive(USART0); if(rx_count >= BUFFER_SIZE) { usart_interrupt_disable(USART0, USART_INT_RBNE); printf("rx buffer is full!!\n"); recv_flag = 0; } if(strstr((const char *)rx_buffer, "OK\r\n") || strstr((const char *)rx_buffer, "ERROR\r\n") ){ usart_interrupt_disable(USART0, USART_INT_RBNE); recv_flag = 0; } else if(strstr((const char *)rx_buffer, "blink") || strstr((const char *)rx_buffer, "on") || strstr((const char *)rx_buffer, "off") ){ usart_interrupt_disable(USART0, USART_INT_RBNE); recv_flag = 0; } } if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_TBE)) { /* transmit data */ usart_data_transmit(USART0, tx_buffer[tx_count ]); if(tx_count >= BUFFER_SIZE) { usart_interrupt_disable(USART0, USART_INT_TBE); send_flag = 0; } if(tx_count >= send_len) { usart_interrupt_disable(USART0, USART_INT_TBE); send_flag = 0; send_len = 0; } } }
uart初始化:
/* enable COM GPIO clock */ rcu_periph_clock_enable(RCU_GPIOA);
/* connect port to USARTx_Tx */ gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_9);
/* connect port to USARTx_Rx */ gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_10);
/* configure USART Tx as alternate function push-pull */ gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9); gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_9);
/* configure USART Rx as alternate function push-pull */ gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_10); gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_10);
/* enable USART clock */ rcu_periph_clock_enable(RCU_USART0);
/* USART configure */ usart_deinit(USART0); usart_baudrate_set(USART0, 115200U); usart_receive_config(USART0, USART_RECEIVE_ENABLE); usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_enable(USART0); nvic_irq_enable(USART0_IRQn, 0, 0);
LED初始化:
GPIO_InitTypeDef GPIO_InitStruct = {0}; /*GPIO Port Clock Enable */ rcu_periph_clock_enable(RCU_GPIOA); /*Configure GPIO pin : PtPin PA8*/ GPIO_InitStruct.gpio_periph = GPIOA; GPIO_InitStruct.mode = GPIO_MODE_OUTPUT; GPIO_InitStruct.pin = GPIO_PIN_8; GPIO_InitStruct.otype = GPIO_OTYPE_PP; GPIO_InitStruct.speed = GPIO_OSPEED_50MHZ; GPIO_InitStruct.pull_up_down = GPIO_PUPD_NONE; gpio_mode_set(GPIO_InitStruct.gpio_periph,GPIO_InitStruct.mode,GPIO_InitStruct.pull_up_down,GPIO_InitStruct.pin); /*Configure GPIO pin Output Level */ gpio_output_options_set(GPIO_InitStruct.gpio_periph,GPIO_InitStruct.otype,GPIO_InitStruct.speed,GPIO_InitStruct.pin); GPIO_BC(GPIO_InitStruct.gpio_periph) = GPIO_InitStruct.pin; /* EXTI interrupt init*/
主程序代码:
int main(void) { e_at_state at_state = e_init; /* enable DMA clock */ init(); led_flash(5); while(1) { switch (at_state) { case e_init: sat("ATE0\r\n", "OK"); if(!sat("AT\r\n", "OK")){ led_on(); at_state = e_at_ok; } else{ delay_1ms(100);
led_off();
}
break;
case e_at_ok:
if(!sat("AT+CWJAP=\"testssid\",\"12345678\"\r\n", "WIFI GOT IP"))
{
at_state = e_wifi_ok;
}
else{
delay_1ms(100);
}
break;
case e_wifi_ok:
if(!sat("AT+CIFSR\r\n", "CIFSR:STAIP"))
{
at_state = e_sock_ok;
}
else
{
delay_1ms(100);
}
at_state = e_sock_ok;
break;
case e_sock_ok:
//close socket
sat("AT+CIPCLOSE\r\n", "OK");
//start a new socket
if(!sat("AT+CIPSTART=\"TCP\",\"192.168.1.36\",1314\r\n", "CONNECT"))
{
//sat("AT+CIPSEND=10","OK");
at_state = e_connect_ok;
}
else
{
delay_1ms(100);
}
break;
case e_connect_ok:
{
char at_resp[128] = {0};
wait_atrsp(at_resp);
if(strstr(at_resp,"on")){
printf("light on\n");
led_on();
}
else if(strstr(at_resp,"off")){
printf("light off\n");
led_off();
}
else if(strstr(at_resp, "blink"))
{
printf("buling buling\n");
led_flash(10);
}
else
{
printf("other cmd got:[%s]\r\n", at_resp);
}
}
break;
default:
printf("Get into other:%d\n",at_state);
break;
}
//delay_1ms(100);
}
}
代码仓库地址
https://gitee.com/lyzcc/gd32-…
待改善
usart接收数据采用关键字判断结束,效率较低; at指令接收没有超时,如果得不到期望结果会卡住; socket异常断开没有做处理; 后面可以接一个继电器控制插座或者台灯 因为esp01升级不到最新版本,无法支持mqtt,只能点对点控制玩玩了,支持mqtt就可以做更多事情; 异步中断处理usart_interrupt_flag_get不是很理解,正常接收或者发送完数据应该是可以退出,但是好像一直无法退出,不知道是使用的问题还是哪里出的问题,有经验的大神可以交流交流指导指导;
作者:Ljfly