用USART2给ESP8266发送AT指令,触发USART2接收中断后收到接收数据还是我发送的AT指令,求解。
数据接收是通过超时接收的方式判断是否数据接收结束,USART3 打印到串口通信助手,debug调试
ESP8266_Tool.h
#define USART2_MAX_SEND_LEN 1024
#define USART2_MAX_RECEIVE_LEN 1024
#define WIFI_NAME 9119 // WIFI名字
#define WIFI_PASSWORD 123123123 // WIFI密码
extern uint8_t rx_index;
extern uint8_t rx_flag;
extern uint8_t USART2_TX_BUF[USART2_MAX_SEND_LEN];
extern uint8_t USART2_RX_BUF[USART2_MAX_RECEIVE_LEN];
void usart2_Init(void );
void usart2_printf(char *fmt, ...);
int USART3_fputc(int ch, FILE *f);
void usart2_Send_Byte(USART_TypeDef* USARTx, uint8_t Data );
void usart2_Send_String(USART_TypeDef* USARTx, const char *Data);
void ESP8266_Init(void );
uint8_t ESP8266_Send_Cmd(char *cmd,char *ack,uint16_t waitTime);
uint8_t* ESP8266_Check_Cmd(char *str);
void Rx_Init(void );
ESP8266_Tool.c
uint8_t USART2_TX_BUF[USART2_MAX_SEND_LEN];
uint8_t USART2_RX_BUF[USART2_MAX_RECEIVE_LEN];
uint8_t rx_index = 0;
uint8_t rx_flag = 0;
void usart2_Init(void ){
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // TX PA2引脚
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; // RX PA3引脚
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOA,&GPIO_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn; // !!?
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2,&USART_InitStruct);
USART_ITConfig(USART2,USART_IT_RXNE,ENABLE); // 使能串口接收中断
USART_Cmd(USART2,ENABLE);
}
/* 重定向 fputc打印通道 */
int fputc(int ch,FILE *fp){
while (USART_GetFlagStatus(USART3,USART_FLAG_TXE) == RESET); //等待上次数据发送结束后在获取
USART_SendData(USART3,ch);
return ch;
}
/* 发送字符 */
void usart2_Send_Byte(USART_TypeDef* USARTx, uint8_t Data){
while (USART_GetFlagStatus(USARTx,USART_FLAG_TXE) == RESET); // 判断是否发送完毕
printf("usart2_Send_Byte:%c\n",Data);
USART_SendData(USARTx,Data);
}
/* usart2,重定义printf格式化发送数据 */
void usart2_printf(char *fmt, ...){
uint16_t i,j;
va_list ap;
va_start(ap,fmt);
vsprintf((char *)USART2_TX_BUF, fmt, ap);
va_end(ap);
j = strlen((const char *)USART2_TX_BUF);
for(i = 0;i<j;i++){
usart2_Send_Byte(USART2, (uint8_t) USART2_TX_BUF[i]);
}
}
/* 调试使用 发送字符串 */
void usart2_Send_String(USART_TypeDef* USARTx, const char *Data){
while (*Data !='\0'){
usart2_Send_Byte(USARTx, *Data);
++Data;
}
while (USART_GetFlagStatus(USARTx,USART_FLAG_TXE) == RESET);
}
/* WIFI初始化 连接设置WIFI */
void ESP8266_Init(void ){
char cmd[128];
uint8_t ESP8266_Init_flag;
printf("AT\r\n");
ESP8266_Init_flag = ESP8266_Send_Cmd("AT","OK",50); // 检查ESP8266模块 是否正常工作
if(ESP8266_Init_flag)
printf("AT ERROR\r\n");
printf("AT+CWMODE=1\r\n");
Rx_Init();
ESP8266_Init_flag = ESP8266_Send_Cmd("AT+CWMODE=1","OK",50); // 配置ESP8266模块 为station模式
if(ESP8266_Init_flag)
printf("AT+CWMODE=1 ERROR\r\n");
printf("AT+RST\r\n");
Rx_Init();
ESP8266_Init_flag = ESP8266_Send_Cmd("AT+RST","ready",20); // 重启ESP8266
if(ESP8266_Init_flag)
printf("AT+RST ERROR\r\n");
delay_ms(1000);
printf("AT+CWJA\r\n");
Rx_Init();
sprintf(cmd, "AT+CWJAP=\"%c\",\"%c\"", WIFI_NAME, WIFI_PASSWORD);
ESP8266_Init_flag = ESP8266_Send_Cmd(cmd,"WIFI GOT IP",300); // 连接 WIFI
if(ESP8266_Init_flag)
printf("AT+CWJA ERROR\r\n");
printf("AT+CIPSTART\r\n");
Rx_Init();
ESP8266_Init_flag = ESP8266_Send_Cmd("AT+CIPSTART=\"TCP\",\"192.168.137.1\",8080","CONNECT",200);
if(ESP8266_Init_flag)
printf("AT+CIPSTART\r\n");
}
/**
* 向ESP8266发送命令
* cmd:发送的命令;ack:期待的应答结果,如果为空,则表示不需要等待响应;waitTime:等待时间(单位10ms)
* 返回值:0,表示发送成功;1 表示发送失败
* */
uint8_t ESP8266_Send_Cmd(char *cmd,char *ack,uint16_t waitTime){
uint8_t res = 0;
do{
usart2_printf("%s\r\n", cmd);
if(ESP8266_Check_Cmd(ack)){
printf("ack:%s\r\n",(uint8_t*)ack);
break;
}
delay_ms(10);
}while(-- waitTime);
if(waitTime == 0)
res = 1;
return res;
}
void Rx_Init(void ){
memset(USART2_RX_BUF,0, sizeof(USART2_RX_BUF)); // 接收数组清空
rx_index = 0;
rx_flag = 0;
}
/**
* 发送AT命令后,检测收到的应当
* str 期待的应答结果
* 返回:0 没有得到期待的应答结果,返回:str地址 得到期待的应答结果一个字符的首地址
* */
uint8_t* ESP8266_Check_Cmd(char *str){
char *strx;
while (1){
if(rx_flag){
if (strstr((const char *)USART2_RX_BUF,str) != NULL){
strx = strstr((const char *)USART2_RX_BUF,str);
usart2_Send_String(USART3, (const char *)USART2_RX_BUF);
return (uint8_t*)strx;
}
return NULL;
}
}
}
void USART2_IRQHandler(void ){
int IRQ_flag = 0;
if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET){
printf("USART2_IRQHandler...\n");
USART2_RX_BUF[rx_index ++] = USART_ReceiveData(USART2);
if(USART2_RX_BUF[rx_index] == '\r'){
IRQ_flag = 1;
printf("IRQ_flag: %d\n",IRQ_flag);
}
if (IRQ_flag && USART2_RX_BUF[rx_index] == '\n'){
printf("USART2_IRQHandler -> %s\n",USART2_RX_BUF);
}
if(rx_index > (uint8_t)USART2_MAX_RECEIVE_LEN){
rx_index = (uint8_t)USART2_MAX_RECEIVE_LEN;
}
timer_Num = 0; // 超时定时器,每来一个数据timer_Num 清零
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
}
}
debug_usart03.c
static void usrt3_GPIO_Init(void ){
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
USART_Cmd(USART3,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PA10
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART3,&USART_InitStructure);
USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
USART_Cmd(USART3,ENABLE);
}
static void usrt3IT_Init(void ){ //串口中断配置
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = 39;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void usrt2_Init1(void ){
usrt3_GPIO_Init();
usrt3IT_Init();
setbuf(stdout, NULL);
}
Timer.h
extern uint16_t timer_Num;
void timer_Init(void );
Timer.c
uint16_t timer_Num = 0;
void timer_Init(void ){
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_InternalClockConfig(TIM2);
TIM_TimeBaseInitStruct.TIM_Prescaler = 72 - 1; // 1ms
TIM_TimeBaseInitStruct.TIM_Period = 1000 - 1;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
TIM_ClearFlag(TIM2,TIM_FLAG_Update); // 避免程序初始化结束进入中断问题
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //更新中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_Init(&NVIC_InitStruct);
TIM_Cmd(TIM2,ENABLE);
}
/* Tim2 中断触发执行 */
void TIM2_IRQHandler(void ){
if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET){
timer_Num ++; // 每1ms timer_Num++
if(timer_Num > 400){
timer_Num = 0;
rx_flag = 1; // ESP8266数据接收完成
printf("rx_index:%d\n",rx_index);
}
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
mian.c
void systemInit(void ){
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //NVIC分组
sysTick_Init();
timer_Init();
// LED_init();
// buzzer_init();
// infraredSensorInit();
usrt2_Init1();
//GPIO_InitStruct();
//USART1_UART_Init();
usart2_Init();
ESP8266_Init();
}
void content(void ){
while (1){
}
}
void test(){
while (1){
ESP8266Content();
// printf("Hello, USART3!\n");
delay_ms(300);
}
}
int main(void)
{
systemInit();
//content();
test();
return 0;
}
问题解决了 这里串口2接收中断,每接收一个数据就进行判断,出现问题,这里修改了一下,通过判断到\r\n,在判断是否接收到所有数据,在进行判断。
因为AT指令返回值是 \r\n 内容 \r\n 的形式返回
void USART2_IRQHandler(void ){
if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) {
uint8_t data = USART_ReceiveData(USART2);
USART2_RX_BUF[rx_index++] = data;
if ((data == '\r' || data == '\n') && rx_index >= 2 && USART2_RX_BUF[rx_index-2] == '\r') {
receive_complete_flag = 1; // 接收完成标志,表示一行数据接收完成
}
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
}
}
uint8_t* ESP8266_Check_Cmd(char *str){
char *strx;
while (1){
if(receive_complete_flag){
if (strstr((const char *)USART2_RX_BUF,str) != NULL){
strx = strstr((const char *)USART2_RX_BUF,str);
usart2_Send_String(USART3, (const char *)USART2_RX_BUF);
return (uint8_t*)strx;
}
return NULL;
}
}
}