串口操作

蛋疼得很,竟然忘记用NVIC了,太久没有操作STM32的底层了。

这里贴上原子的串口操作---

typedef struct
{
u8 Timeout;
u16 RX_STA;
u8 RX_BUF[1024]; //1024
u8 TX_BUF[30];
}Usart;

Usart uart1;

void nvic()
{
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel =USART1_IRQn; 
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=5;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   
    NVIC_Init(&NVIC_InitStructure); 
}    
void init()
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    USART_ClockInitTypeDef USART_ClockInitStructure;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB|
            RCC_APB2Periph_AFIO, 
            ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    /* A9 USART1_Tx */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP;//GPIO_Mode_IN_FLOATING;//        //推挽输出-TX
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* A10 USART1_Rx  */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入-RX
    GPIO_Init(GPIOA, &GPIO_InitStructure);


    USART_InitStructure.USART_BaudRate =115200;
    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_Tx| USART_Mode_Rx;
    
    USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
    USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
    USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
    USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;

    USART_ClockInit(USART1, &USART_ClockInitStructure);
    USART_Init(USART1, &USART_InitStructure);
    /* Enable the USARTx */
    USART_Cmd(USART1, ENABLE);
    //串口1使用接收中断   
    USART_ClearFlag(USART1,USART_FLAG_TC);
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//只打开接收中断

}

void main()//怎么操作串口,如下
{
    nvic();
    init();
    //接收
    if((uart1.RX_STA&0x8000)==0x8000)
    {
        uart1.RX_BUF[1023]=0;//添加结束符
        DBG("%s", uart1.RX_BUF);
        uart1.RX_STA=0;
        memset(uart1.RX_BUF,0,sizeof(uart1.RX_BUF));
    }
    //发送,用usart1.TXBUF来发送就是了
}

void USART1_IRQHandler(void)
{
    u8 res;
    if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)
    {
        USART_ClearITPendingBit(USART1,USART_IT_RXNE);
        res = USART_ReceiveData(USART1);         
        if((uart1.RX_STA  &(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据
        {
            if(uart1.RX_STA < 1024)    //还可以接收数据
            {
                uart1.Timeout = RECMSGTIMEOUT; //10MS没有数据,则强制封包
                uart1.RX_BUF[uart1.RX_STA++] = res;    //记录接收到的值     
            }
            else 
            {
                uart1.RX_STA |= 1<<15;                //强制标记接收完成
                uart1.Timeout = 0;
            }
        }
    }
    //溢出-如果发生溢出需要先读SR,再读DR寄存器 则可清除不断入中断的问题
    if(USART_GetFlagStatus(USART1,USART_FLAG_ORE)==SET)
    {
        USART_ClearFlag(USART1,USART_FLAG_ORE);    //读SR
        USART_ReceiveData(USART1);                //读DR
    }
}

//在定时器中,加入下面这个逻辑,用于上面的RECMSGTIMEOUT
//RECMSGTIMEOUT=3  下面设置成10ms,则30ms没有接受到新的数据,则封包
if(uart1.Timeout>0)
{
    uart1.Timeout--;
    if(uart1.Timeout==0)
    {
        uart1.RX_STA|=1<<15;
    }
}

//#define ECHO
/*定义 fputc 此函数为printf所用*/
int fputc(int ch, FILE *f) 
{ 
    //if(DEBUG)
    {
        //  #ifdef ECHO 
        // xSemaphoreTake(xMutex,(portTickType)10);
        while((USART1->SR&0X40) == 0);//循环发送,直到发送完毕   
        USART1->DR = (u8) ch;
        // xSemaphoreGive(xMutex);
        // #endif
    }
    return ch;
}

void uart1_putchar(u8 ch) //发送一个字符
{     
    USART_ClearFlag(USART1,USART_FLAG_TC);
    USART_SendData(USART1,ch);
    while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);

}

void UART1Write(u8 *data,u32 len)     //发送n个字符
{    
    if (DEBUG)
    {
        u16 i;
        if( len == 0)    
        {    
            for(i = 0;data[i] != '\0';i++)
            {
                uart1_putchar(data[i]);
            }
        }

        else
        {        
            for(i = 0;i < len;i++)
            {
                uart1_putchar(data[i]);
            }
        }
    }
}

 

posted @ 2018-01-18 16:17  XZHDJH  阅读(168)  评论(0)    收藏  举报