STM32接收特定字符串,滤除回车符,直接得到所需字符串
分配USART2用于实现此功能
考虑很久,接收不打算用while(1)查询的方式实现了,浪费时钟周期,直接中断实现
USART配置
/******************************串口函数******************************/
void USART_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure; 
                                           
    //1步:打开GPIOUSART部件的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);    //打开GPIOA时钟 允许复用
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);    //打开USART1时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);    //打开USART2时钟
    // 2步:将USART TxGPIO配置为推挽复用模式
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_9;      //Pin_2 - USART2_TX  Pin_9 - USART1_TX 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    // 3步:将USART RxGPIO配置为浮空输入模式
    //    由于CPU复位后,GPIO缺省都是浮空输入模式,因此下面这个步骤不是必须的
    //    但是,我还是建议加上便于阅读,并且防止其它地方修改了这个口线的设置参数
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_10;        //Pin_3 - USART2_RX  Pin_10 - USART1_RX 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
                                                               
    // 4步:配置USART 数据格式、波特率等参数
    //    - BaudRate = 115200 baud
    //    - Word Length = 8 Bits
    //    - One Stop Bit
    //    - No parity
    //    - Hardware flow control disabled (RTS and CTS signals)
    //    - Receive and transmit enabled
   
    USART_InitStructure.USART_BaudRate = 115200;    //USARTDIV=72000000/115200*16=39.0625    对应误差率为0(查看参考手册)
字符串比较函数实现    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);
    USART_Init(USART2, &USART_InitStructure);
    // 5步:使能 USART 配置完毕
    USART_Cmd(USART1, ENABLE);
    USART_Cmd(USART2, ENABLE);
    //CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去
    //如下语句解决第1个字节无法正确发送出去的问题
    USART_ClearFlag(USART1, USART_FLAG_TC);    //清发送外城标志,Transmission Complete flag
    USART_ClearFlag(USART2, USART_FLAG_TC);
    //USART2要与wifi通信,因此需要接收命令,这里使用串口中断接收命令
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); 
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);        //配置优先级组
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级2
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);   
    //使能收发中断
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);         
}
我们日常所说的回车(ENTER)其实分为两步:回车:ASCII-0x0d  换行:ASCII-0x0a,接收的话必须要都滤除0x0d,0x0a,才能正常判断接收到的字符串,于是,索性接收到这两个字符串都不要,扔了就行
void USART2_IRQHandler(void)
{
    uint8_t tmp;
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)      //判断发生接收中断
    {
        tmp = USART_ReceiveData(USART2);
        if((tmp==0x0d)||(tmp==0x0a))
        {
            Rx_Lenght=0;     
            Rx_flg=1;       
            USART_ClearITPendingBit(USART2, USART_IT_RXNE);          //清除中断标志                   
        }
        else
        {
            Rx_Buffer[Rx_Lenght] = tmp;
            Rx_Lenght++;       
        }
}
void USART2_TX(char * str)//发送就用这种方式了,发送给模块的指令并不长,所以不会浪费太多时钟
{
    while(*str)
    {
        USART_SendData(USART2, *str++);
        // Loop until the end of transmission
        while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
    }
}
完成中断接受字符串之后,就是比较特定字符串了,
int USART1_Receive(const char *str)
{
    if(memcmp(U1Rx_Buffer, str , strlen(str))==0)
        return 1;
    else return 0;
}
Memcmp();这是C语言中对比存储空间中内容是否一样的函数(C语言中对于字符串的操作一些函数可见此博客:hi.baidu/justeasy123/item/baa1484602b3552911ee1e69)。
字符串对比函数如果返回1,则说明接收到了我们需要的字符串,否则没有接收到特定字符串。
接收到特定字符串之后则可以做出特定的程序反应:
if(USART1_Receive("enter WIFI config"))        USART2_TX(wifi_cmd_$$$);
if(USART1_Receive("set ip address"))            USART2_TX(set_ip_address);
if(USART1_Receive("set ip netmask"))            USART2_TX(set_ip_netmask);
if(USART1_Receive("set ip gateway"))            USART2_TX(set_ip_gateway);   
if(USART1_Receive("set ip localport"))        USART2_TX(set_ip_localport);
if(USART1_Receive("set ip host"))            USART2_TX(set_ip_host);
if(USART1_Receive("set ip remote"))            USART2_TX(set_ip_remote);
if(USART1_Receive("set ip protocol"))            USART2_TX(set_ip_protocol);

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。