嵌入式單片機學習之串口接收數據實例

  //通過判斷接收連續2個字符之間的時間差不大于10ms來決定是不是一次連續的數據.

  //如果2個字符接收間隔超過10ms,則認為不是1次連續數據.也就是超過10ms沒有接收到

  //任何數據,則表示此次接收完畢.

  //接收到的數據狀態

  //[15]:0,沒有接收到數據;1,接收到了一批數據.

  //[14:0]:接收到的數據長度

  vu16 USART3_RX_STA=0;

  一。uart3.c中的函數

  1. 初始化串口3

  //初始化IO 串口3

  //pclk1:PCLK1時鐘頻率(Mhz)

  //bound:波特率

  void usart3_init(u32 bound)

  {

  NVIC_InitTypeDef NVIC_InitStructure;

  GPIO_InitTypeDef GPIO_InitStructure;

  USART_InitTypeDef USART_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // GPIOB時鐘

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //串口3時鐘使能

  USART_DeInit(USART3); //復位串口3

  //USART3_TX PB10

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB10

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出

  GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB10

  //USART3_RX PB11

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入

  GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB11

  USART_InitStructure.USART_BaudRate = bound;//波特率一般設置為9600;

  USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數據格式

  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(USART3, &USART_InitStructure); //初始化串口3

  USART_Cmd(USART3, ENABLE); //使能串口

  //使能接收中斷

  USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//開啟中斷

  //設置中斷優先級

  NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//搶占優先級3

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子優先級3

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能

  NVIC_Init(&NVIC_InitStructure); //根據指定的參數初始化VIC寄存器

  ////////////////////////////////////////////////////////////////////////////////////////////////////////

  //定時器7定為10ms中斷,檢測如果10ms內接收到的數據為同一個數據包中的數據,如果超過10ms

  就算這次接收完成。

  TIM7_Int_Init(1000-1,7200-1); //10ms中斷

  USART3_RX_STA=0; //清零

  TIM_Cmd(TIM7,DISABLE); //關閉定時器7

  }

  2.串口3中斷函數

  void USART3_IRQHandler(void)

  {

  u8 res;

  if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)//接收到數據

  {

  res =USART_ReceiveData(USART3);

  if((USART3_RX_STA&(1<<15))==0)//接收完的一批數據,還沒有被處理,則不再接收其他數據

  {

  if(USART3_RX_STA //還可以接收數據

  {

  TIM_SetCounter(TIM7,0); //計數器清空,定時器7開始下一次定時

  if(USART3_RX_STA==0) //使能定時器7的中斷

  {

  TIM_Cmd(TIM7,ENABLE);//使能定時器7

  }

  USART3_RX_BUF[USART3_RX_STA++]=res; //記錄接收到的值

  }else

  {

  USART3_RX_STA|=1<<15; //強制標記接收完成

  }

  }

  }

  }

  3. 串口2的printf函數

  //串口3,printf 函數

  //確保一次發送數據不超過USART3_MAX_SEND_LEN字節

  void u3_printf(char* fmt,...)

  {

  u16 i,j;

  va_list ap;

  va_start(ap,fmt);

  vsprintf((char*)USART3_TX_BUF,fmt,ap);

  va_end(ap);

  i=strlen((const char*)USART3_TX_BUF); //此次發送數據的長度

  for(j=0;j //循環發送數據

  {

  while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //循環發送,直到發送完畢

  USART_SendData(USART3,USART3_TX_BUF[j]);

  }

  }

  4.串口3printf函數的引用

  u3_printf("%s",p); //發送該數據到WIFI模塊

  u3_printf("%s\r\n",cmd); //發送命令

  二。timer.c中定時器7的設置

  1. 初始化

  //通用定時器7中斷初始化

  //這里時鐘選擇為APB1的2倍,而APB1為42M

  //arr:自動重裝值。

  //psc:時鐘預分頻數

  //定時器溢出時間計算方法:Tout=((arr+1)*(psc+1))/Ft us.

  //Ft=定時器工作頻率,單位:Mhz

  //通用定時器中斷初始化

  //這里始終選擇為APB1的2倍,而APB1為36M

  //arr:自動重裝值。

  //psc:時鐘預分頻數

  void TIM7_Int_Init(u16 arr,u16 psc)

  {

  NVIC_InitTypeDef NVIC_InitStructure;

  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);//TIM7時鐘使能

  //定時器TIM7初始化

  TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的 值

  TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鐘頻率除數的預分頻值

  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設置時鐘分割:TDTS =

Tck_tim

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式

  TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure);

//根據指定的參數初始化TIMx的時間基數單位

  TIM_ITConfig(TIM7,TIM_IT_Update,ENABLE ); //使能指定的TIM7中斷,允許更新中斷

  TIM_Cmd(TIM7,ENABLE);//開啟定時器7

  NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//搶占優先級0

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子優先級2

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能

  NVIC_Init(&NVIC_InitStructure); //根據指定的參數初始化VIC寄存器

  }

  二。定時器7的中斷函數

  //定時器7中斷服務程序

  void TIM7_IRQHandler(void)

  {

  if (TIM_GetITStatus(TIM7, TIM_IT_Update) != RESET)//是更新中斷

  {

  USART3_RX_STA|=1<<15; //標記接收完成

  TIM_ClearITPendingBit(TIM7, TIM_IT_Update ); //清除TIM7更新中斷標志

  TIM_Cmd(TIM7, DISABLE); //關閉TIM7

  }

  }

分享些資料便于后期的學習參考

(stm32串口應用)

http://www.makeru.com.cn/live/1392_1164.html?s=45051

PWM脈寬調制技術

http://www.makeru.com.cn/live/4034_2146.html?s=45051

基于STM32講解串口操作

http://www.makeru.com.cn/live/1758_490.html?s=45051

通過Z-stack協議棧實現串口透傳

http://www.makeru.com.cn/live/1758_330.html?s=45051

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 有一次做一個東西,為了盡量不占用CPU的處理數據時間,所以就使用DMA接收串口的數據,但是呢問題來了.,,,,,怎...
    楊奉武閱讀 3,197評論 0 1
  • # STM32之串口DMA接收不定長數據 ## 引言 在使用stm32或者其他單片機的時候,會經常使用到串口通訊,...
    杰杰T_T閱讀 552評論 0 0
  • 姓名:周崇杰 學號:16140120059 專業:機械設計制造及其自動化 轉載自:http://blog.csd...
    CJbaby閱讀 3,527評論 0 3
  • 我的二十到三十歲是荒廢的,甚至可以說前三十年我都渾渾噩噩,自己浪費的時間,也不要可惜了,昨日之日不可追,我仍...
    無敵風火輪向前沖鴨閱讀 139評論 0 0
  • java8 之后使用CompletableFuture來異步執行任務的場景越來越多,這個時候debug調試就是個問...
    黃云斌huangyunbin閱讀 9,136評論 0 0