1. 程式人生 > >STM32串列埠USART1程式(受啟發,前進一步)

STM32串列埠USART1程式(受啟發,前進一步)

原理圖:

#include "stm32f10x.h" #include "stm32f10x_usart.h" #include "misc.h" #include "stdarg.h" /* Private variables ---------------------------------------------------------*/ USART_InitTypeDef USART_InitStructure; uint8_t TxBuffer1[] = "USART Interrupt Example: This is USART1 DEMO";   uint8_t RxBuffer1[],rec_f,tx_flag; __IO uint8_t TxCounter1 = 0x00; __IO uint8_t RxCounter1 = 0x00;  uint32_t Rec_Len; /* Private function prototypes -----------------------------------------------*/ void RCC_Configuration(void); void GPIO_Configuration(void); void NVIC_Configuration(void); void Delay(__IO uint32_t nCount); void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...); char *itoa(int value, char *string, int radix); void USART_Config(USART_TypeDef* USARTx); GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStruct; USART_ClockInitTypeDef USART_ClockInitStruct; /**************************************************************************** * 名    稱:USART_Config(USART_TypeDef* USARTx) * 功    能:配置串列埠 * 入口引數: * 出口引數:無 * 說    明: * 呼叫方法:例如: USART_Config(USART1) ****************************************************************************/ void USART_Config(USART_TypeDef* USARTx){   USART_DeInit(USART1);   USART_InitStructure.USART_BaudRate = 9600;//速率115200bps   USART_InitStructure.USART_WordLength = USART_WordLength_8b;//資料位8位   USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位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;//收發模式   /* Configure USART1 */   USART_Init(USARTx, &USART_InitStructure);//配置串列埠引數函式   /* Enable USART1 Receive and Transmit interrupts */   USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);                    //使能接收中斷 //  USART_ITConfig(USART1, USART_IT_TXE, ENABLE);//使能傳送緩衝空中斷    USART_ClearFlag(USART1, USART_FLAG_TC );   /* Enable the USART1 */   USART_Cmd(USART1, ENABLE); } /**************************************************************************** * 名    稱:int main(void) * 功    能:奮鬥板主函式 * 入口引數:無 * 出口引數:無 * 說    明: * 呼叫方法:無  ****************************************************************************/ int main(void) {    uint8_t a=0;   /* System Clocks Configuration */   RCC_Configuration(); //系統時鐘設定   /*巢狀向量中斷控制器配置了USART1的優先順序分組為0,搶佔優先順序級別0(無) ,和響應優先順序級別0(0-7) */ 
  NVIC_Configuration(); //中斷源配置   /*對控制LED指示燈的IO口進行了初始化,將埠配置為推輓上拉輸出,口線速度為50Mhz。PA9,PA10埠複用為串列埠1的TX,RX。   在配置某個口線時,首先應對它所在的埠的時鐘進行使能。否則無法配置成功,由於用到了埠B, 因此要對這個埠的時鐘   進行使能,同時由於用到複用IO口功能用於配置串列埠。因此還要使能AFIO(複用功能IO)時鐘。*/   GPIO_Configuration(); //埠初始化   USART_Config(USART1); //串列埠1初始化   USART_OUT(USART1,"****(C) COPYRIGHT 2013 奮鬥嵌入式開發工作室 *******\r\n");   //向串列埠1傳送開機字元。   USART_OUT(USART1,"*                                                 *\r\n");       USART_OUT(USART1,"*         奮鬥版STM32開發板 USART1 實驗           *\r\n");     USART_OUT(USART1,"*                                                 *\r\n");         USART_OUT(USART1,"*  以HEX模式輸入一串資料,以16進位制0d 0a作為結束   *\r\n");       USART_OUT(USART1,"*                                                 *\r\n");       USART_OUT(USART1,"*  奮鬥STM32論壇:www.ourstm.net                  *\r\n");      USART_OUT(USART1,"*                                                 *\r\n");        USART_OUT(USART1,"***************************************************\r\n");    USART_OUT(USART1,"\r\n");    USART_OUT(USART1,"\r\n");        while (1)   { if(rec_f==1){//判斷是否收到一幀有效資料 rec_f=0; USART_OUT(USART1,"\r\n您傳送的資訊為: \r\n");     USART_OUT(USART1,&TxBuffer1[0]); if(a==0) {GPIO_SetBits(GPIOB, GPIO_Pin_5); a=1;}      //LED1  V6(V3V5板) V2(MINI板) 明暗閃爍                 else {GPIO_ResetBits(GPIOB, GPIO_Pin_5);a=0;  } }   } } /**************************************************************************** * 名    稱:void Delay(__IO uint32_t nCount) * 功    能:延時函式 * 入口引數:無 * 出口引數:無 * 說    明: * 呼叫方法:無  ****************************************************************************/ void Delay(__IO uint32_t nCount) {   for(; nCount != 0; nCount--); } /**************************************************************************** * 名    稱:void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...) * 功    能:格式化串列埠輸出函式 * 入口引數:USARTx:  指定串列埠 Data:   傳送陣列 ...:     不定引數 * 出口引數:無 * 說    明:格式化串列埠輸出函式         "\r"回車符   USART_OUT(USART1, "abcdefg\r")    "\n"換行符   USART_OUT(USART1, "abcdefg\r\n") "%s"字串   USART_OUT(USART1, "字串是:%s","abcdefg") "%d"十進位制   USART_OUT(USART1, "a=%d",10) * 呼叫方法:無  ****************************************************************************/ void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...){  const char *s;     int d;     char buf[16];     va_list ap;     va_start(ap, Data); while(*Data!=0){                //判斷是否到達字串結束符 if(*Data==0x5c){//'\' switch (*++Data){ case 'r'://回車符 USART_SendData(USARTx, 0x0d);    Data++; break; case 'n'://換行符 USART_SendData(USARTx, 0x0a); Data++; break; default: Data++;     break; }  } else if(*Data=='%'){// switch (*++Data){ case 's'://字串                  s = va_arg(ap, const char *);                  for ( ; *s; s++) {                     USART_SendData(USARTx,*s); while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);                 }  Data++;                 break; case 'd'://十進位制                 d = va_arg(ap, int);                 itoa(d, buf, 10);                 for (s = buf; *s; s++) {                     USART_SendData(USARTx,*s); while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);                 } Data++;                 break; default: Data++;     break; }  } else  USART_SendData(USARTx, *Data++); while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET); } } /****************************************************** 整形資料轉字串函式         char *itoa(int value, char *string, int radix) radix=10 標示是10進位制非十進位制,轉換結果為0;       例:d=-379; 執行itoa(d, buf, 10); 後 buf="-379"      **********************************************************/ char *itoa(int value, char *string, int radix) {     int     i, d;     int     flag = 0;     char    *ptr = string;     /* This implementation only works for decimal numbers. */     if (radix != 10)     {         *ptr = 0;         return string;     }     if (!value)     {         *ptr++ = 0x30;         *ptr = 0;         return string;     }     /* if this is a negative value insert the minus sign. */     if (value < 0)     {         *ptr++ = '-';         /* Make the value positive. */         value *= -1;     }     for (i = 10000; i > 0; i /= 10)     {         d = value / i;         if (d || flag)         {             *ptr++ = (char)(d + 0x30);             value -= (d * i);             flag = 1;         }     }     /* Null terminate the string. */     *ptr = 0;     return string; } /* NCL_Itoa */ /**************************************************************************** * 名    稱:void RCC_Configuration(void) * 功    能:系統時鐘配置為72MHZ, 外設時鐘配置 * 入口引數:無 * 出口引數:無 * 說    明: * 呼叫方法:無  ****************************************************************************/  void RCC_Configuration(void) {    SystemInit();     RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 |RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB                             | RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO  , ENABLE);   } /**************************************************************************** * 名    稱:void GPIO_Configuration(void) * 功    能:通用IO口配置 * 入口引數:無 * 出口引數:無 * 說    明: * 呼叫方法: ****************************************************************************/   void GPIO_Configuration(void) {   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;  //LED1控制--PB5   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推輓輸出   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   GPIO_Init(GPIOB, &GPIO_InitStructure);    /* 預設複用功能 */   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;         //USART1 TX   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     //複用推輓輸出   GPIO_Init(GPIOA, &GPIO_InitStructure);    //A埠    /* 複用功能的輸入引腳必須配置為輸入模式(浮空/上拉/下拉的一種)*/   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;          //USART1 RX   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;    //複用浮空輸入   GPIO_Init(GPIOA, &GPIO_InitStructure);          //A埠    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;     //LCD背光控制   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   GPIO_Init(GPIOD, &GPIO_InitStructure);   GPIO_ResetBits(GPIOD, GPIO_Pin_13);          //LCD背光關閉 } /**************************************************************************** * 名    稱:void NVIC_Configuration(void) * 功    能:中斷源配置 * 入口引數:無 * 出口引數:無 * 說    明: * 呼叫方法:無  ****************************************************************************/ void NVIC_Configuration(void) {   /*  結構宣告*/   NVIC_InitTypeDef NVIC_InitStructure;   /* Configure the NVIC Preemption Priority Bits */     /* Configure one bit for preemption priority */   /* 優先順序組 說明了搶佔優先順序所用的位數,和響應優先順序所用的位數   在這裡是0, 4    0組:  搶佔優先順序佔0位, 響應優先順序佔4位   1組:  搶佔優先順序佔1位, 響應優先順序佔3位   2組:  搶佔優先順序佔2位, 響應優先順序佔2位   3組:  搶佔優先順序佔3位, 響應優先順序佔1位   4組:  搶佔優先順序佔4位, 響應優先順序佔0位     */           NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);       NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;    //設定串列埠1中斷   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;     //搶佔優先順序 0   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//子優先順序為0   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能   NVIC_Init(&NVIC_InitStructure); } /******************* (C) COPYRIGHT 2013 奮鬥STM32 *****END OF FILE****/
 /*****
初始化系統時鐘,初始化
RCC_APB2Periph_USART1(串列埠USART1) ,RCC_APB2Periph_GPIOA(PA9,PA10) ,RCC_APB2Periph_GPIOB (LED燈),RCC_APB2Periph_GPIOD(LCD背光)*****/ void RCC_Configuration(void) {    SystemInit();     RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 |RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB                             | RCC_APB2Periph_GPIOD, ENABLE);   }

/*****
中斷向量表串列埠
NVIC_PriorityGroup_0 ,初始化USART1 *****/ void NVIC_Configuration(void) {   /*  結構宣告*/   NVIC_InitTypeDef NVIC_InitStructure;   /* Configure the NVIC Preemption Priority Bits */     /* Configure one bit for preemption priority */   /* 優先順序組 說明了搶佔優先順序所用的位數,和響應優先順序所用的位數   在這裡是0, 4    0組:  搶佔優先順序佔0位, 響應優先順序佔4位   1組:  搶佔優先順序佔1位, 響應優先順序佔3位   2組:  搶佔優先順序佔2位, 響應優先順序佔2位   3組:  搶佔優先順序佔3位, 響應優先順序佔1位   4組:  搶佔優先順序佔4位, 響應優先順序佔0位     */           NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);       NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;     //設定串列埠1中斷   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;     //搶佔優先順序 0   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//子優先順序為0   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能   NVIC_Init(&NVIC_InitStructure); } 
初始化GPIO口,TX:
GPIO_Mode_Out_PP ,RX:GPIO_Mode_AF_PP,PB5為低電平  void GPIO_Configuration(void) {   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;     //LED1控制--PB5   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推輓輸出   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   GPIO_Init(GPIOB, &GPIO_InitStructure);    /* 預設複用功能 */   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;          //USART1 TX   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     //複用推輓輸出   GPIO_Init(GPIOA, &GPIO_InitStructure);     //A埠    /* 複用功能的輸入引腳必須配置為輸入模式(浮空/上拉/下拉的一種)*/   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;          //USART1 RX   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;    //複用浮空輸入   GPIO_Init(GPIOA, &GPIO_InitStructure);          //A埠    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;       //LCD背光控制   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   GPIO_Init(GPIOD, &GPIO_InitStructure);   GPIO_ResetBits(GPIOD, GPIO_Pin_13);              //LCD背光關閉 } 
初始化
USART1 ,允許傳送,接收中斷 void USART_Config(USART_TypeDef* USARTx){   USART_DeInit(USART1);   USART_InitStructure.USART_BaudRate = 9600;//速率115200bps   USART_InitStructure.USART_WordLength = USART_WordLength_8b;//資料位8位   USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位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;//收發模式   /* Configure USART1 */   USART_Init(USART1, &USART_InitStructure);//配置串列埠引數函式   /* Enable USART1 Receive and Transmit interrupts */   USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);                    //使能接收中斷   USART_ITConfig(USART1, USART_IT_TXE, ENABLE);//使能傳送緩衝空中斷    //USART_ClearFlag(USART1, USART_FLAG_TC );   /* Enable the USART1 */   USART_Cmd(USART1, ENABLE); } 
/*****傳送函式*****/
void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...){  const char *s;     int d;     char buf[16];     va_list ap;     va_start(ap, Data); while(*Data!=0){                  //判斷是否到達字串結束符 if(*Data==0x5c){//'\' switch (*++Data){ case 'r'://回車符 USART_SendData(USARTx, 0x0d);       //傳送0X0d Data++; break; case 'n': //換行符 USART_SendData(USARTx, 0x0a); Data++; break; default: Data++;     break; }  } else if(*Data=='%'){// switch (*++Data){ case 's'://字串                 s = va_arg(ap, const char *);                 for ( ; *s; s++) {                     USART_SendData(USARTx,*s); while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);                 } Data++;                 break;             case 'd'://十進位制                 d = va_arg(ap, int);                 itoa(d, buf, 10);                 for (s = buf; *s; s++) {                     USART_SendData(USARTx,*s); while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);                 } Data++;                 break; default: Data++;     break; }  } else USART_SendData(USARTx, *Data++); while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET); } } 
/*****中斷函式*****/
void USART1_IRQHandler(void)      //串列埠1 中斷服務程式 {   unsigned int i;   if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //判斷讀暫存器是否非空   {     RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);   //將讀暫存器的資料快取到接收緩衝區裡     if(RxBuffer1[RxCounter1-2]==0x0d&&RxBuffer1[RxCounter1-1]==0x0a)  //判斷結束標誌是否是0x0d 0x0a     {   for(i=0; i< RxCounter1; i++) TxBuffer1[i]= RxBuffer1[i]; //將接收緩衝器的資料轉到傳送緩衝區,準備轉發   rec_f=1;//接收成功標誌   TxBuffer1[RxCounter1]=0;                 //傳送緩衝區結束符       RxCounter1=0;     }   }   if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)                      {       USART_ITConfig(USART1, USART_IT_TXE, ENABLE);        } }