STM32 uses serial port interrupts to send and receive data

Publisher:BlissfulMomentsLatest update time:2018-06-10 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

The chip used here is STM32F103, which uses interrupts to receive and send serial port data.

Here we use the method of directly operating the registers. Using the library function is similar to this, except that we just call the corresponding library function instead.

Configure serial ports and multiplexed IO ports

void uart_init(u32 pclk2,u32 bound)
{       
    float temp;
    u16 mantissa;
    u16 fraction;       
    temp=(float)(pclk2*1000000)/(bound*16);//frequency division
    mantissa=temp; //integer part obtained by frequency division
    fraction=(temp-mantissa)*16; //fractional part     
    mantissa<<=4;
    mantissa+=fraction; 
    RCC->APB2ENR|=1<<2; //Enable GPIOA clock 
    RCC->APB2ENR|=1<<14; //Enable serial port 1 clock 
    RCC->APB2ENR|=1<<0; //(+)Alternate function I/O clock enable It seems that it is not necessary. Is it enabled by default?
    GPIOA->CRH&=0XFFFFF00F;//Clear IO corresponding
    bitGPIOA->CRH|=0X000008B0;//IO status settingRCC-
    
    >APB2RSTR|=1<<14; //Reset serial port 1
    RCC->APB2RSTR&=~(1<<14);//Stop resetUSART1-             
    
    >BRR=mantissa;//Set baud rateUSART1-
    >CR1|=0X200C; //1 stop bit, no parity bit    

    //Enable send interruptUSART1-
    >CR1|=1<<6;  
    USART1->SR&=(~(1<<6));//Clear interrupt flag

    //Enable receiving terminal
    USART1->CR1|=1<<8; //PE interrupt enable?
    USART1->CR1|=1<<5; //Receive buffer not empty interrupt enable           
    MY_NVIC_Init(3,3,USART1_IRQn,2); //Second group of interrupts, lowest priority 
}

 
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)    

    u32 temp;    
    MY_NVIC_PriorityGroupConfig(NVIC_Group);//Set group
    temp=NVIC_PreemptionPriority<<(4-NVIC_Group);      
    temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
    temp&=0xf;//Take the lower four bits
    if(NVIC_Channel<32)NVIC->ISER[0]|=1<    else NVIC->ISER[1]|=1<<(NVIC_Channel-32);    
    NVIC->IP[NVIC_Channel]|=temp<<4;//Set response priority and preemption priority                                 
}


//Send interrupt settings

void USART_SendXByte(USART_TypeDef* USARTx, u16 SendByteNum)
{        
        HAVE_SEND_LEN=0;//Clear the sent data length mark (global variable)
        ALL_SEND_LEN=SendByteNum;//ALL_SEND_LEN is the length of data to be sent this time
        IsSending=1;
        USART1->DR=SEND_BUF[HAVE_SEND_LEN];
        HAVE_SEND_LEN++;
}



Interrupt handling function

u16 USART_RX_STA=0; //Used to mark that one bit of data has been received

//u16 USART_SEND_COMPLETE=1; //Send completion mark
u8 REC; //Used to receive one byte of data received by the serial port, global variable, read this variable in other programs to get the data received by the serial port
u16 HAVE_SEND_LEN=0;
u16 ALL_SEND_LEN=0;
char SEND_BUF[USART_SEND_LEN]; //Unused
char REC_BUF[USART_REC_LEN]; //Unused
void USART1_IRQHandler(void)
{
    if(USART1->SR&(1<<5))//Received data
    {     
        USART_RX_STA=1; //Set the flag bit, read this flag bit as true, then read REC to get the received data

       CountReciByte++;
        REC=USART1->DR;
    }

    if(USART1->SR&(1<<6))//(+)·Sending a byte completes interrupt
    {    
        if(HAVE_SEND_LEN        {    
            USART1->DR=SEND_BUF[HAVE_SEND_LEN];//SEND_BUF[] is a global variable, storing the data to be
            sentHAVE_SEND_LEN++;
        }
      if(HAVE_SEND_LEN==ALL_SEND_LEN)
        {
            USART_SEND_COMPLETE=1;
            while(!(USART1->SR&(1<<6)))
            {
                       //Wait for the last byte to be sent
            }    
            USART1->SR&=(~(1<<6)); //Clear the send interrupt flag
            IsSending=0;
        }
            
    }        


main function

int main(void)
{     
    Stm32_Clock_Init(9);   
    uart_init(72,115200);       
    delay_init(72);          
   
    while(1)//echo the first 10 bytes received "each time"
    {    
        if((1==USART_RX_STA)&&(CountReciByte<=10))
        {    
            SEND_BUF[SerialBufOffset] = REC;
            USART_RX_STA=0;
            SerialBufOffset++;
            if(10==SerialBufOffset)
            {    
                ReadZiku(100,100,SEND_BUF,Black, White);
                //strcpy(SEND_BUF, "ABCDEFGHIJKLDR");
                USART_SendXByte(USART1, SEND_BUF, 10);
                //memset(SEND_BUF,0,sizeof(SEND_BUF));
                SerialBufOffset=0;            
                CountReciByte=0;
                //delay_ms(1000);
            }
            USART_RX_STA=0;//In order to prevent the next time from receiving the byte that was not taken out last time
        }
       
}    


Keywords:STM32 Reference address:STM32 uses serial port interrupts to send and receive data

Previous article:STM32 serial port interrupt sending
Next article:STM32 serial port transmission is abnormal

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号