久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7657|回復: 3
打印 上一主題 下一主題
收起左側

Nucleo-F303RE UART中斷發送數據

[復制鏈接]
跳轉到指定樓層
樓主
首先感謝各位朋友們的幫助,白天在論壇里問的關于UART中斷發送數據丟失問題的帖子。晚上有查了代碼,看了HAL庫代碼和幫助文檔,還有串口工具等問題,最終把問題解決了,把心得給大家分享一下。
關于問題,詳細描述,可以看我的帖子:
【Nucleo-F303RE開發】關于UART中斷發送丟失數據問題請教

------------------------------------------------------------------
今天寫了一個UART的HAL庫中斷發送數據的程序,本來要發送兩個字符串,但是串口發送時只輸出了1個字符串,請問大家程序出了什么問題,請高手幫助解答。
如圖主程序:
每2秒循環發送2個字符串:

但是串口接收的數據只有一個字符串:

主函數我把CUBEMX自動生成的注釋給刪掉,看著短一些:
#include "stm32f3xx_hal.h"

UART_HandleTypeDef huart2;

#define TXBUFFERSIZE1                             COUNTOF(TxBuffer1)
#define TXBUFFERSIZE2                             COUNTOF(TxBuffer2)

#define COUNTOF(__BUFFER__)   (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))

static __IO ITStatus UartReady = RESET;
uint8_t TxBuffer1[] = "第一個字符串";
uint8_t TxBuffer2[] = “第二個字符串";


void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);

int main(void)
{

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();
  MX_USART2_UART_Init();
  while (1)
  {
    HAL_UART_Transmit_IT(&huart2, (uint8_t *)TxBuffer1, TXBUFFERSIZE1);
    while (UartReady != SET)
    {
      ;
    }
    UartReady = RESET;
   
    HAL_UART_Transmit_IT(&huart2, (uint8_t *)TxBuffer2, TXBUFFERSIZE2);
    while (UartReady != SET)
    {
      ;
    }
    UartReady = RESET;
   

    HAL_Delay(2000);

  }

}

void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInit;

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);

  __SYSCFG_CLK_ENABLE();

}

void MX_USART2_UART_Init(void)
{

  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED ;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  HAL_UART_Init(&huart2);

}

void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __GPIOA_CLK_ENABLE();

  /*Configure GPIO pin : PA5 */
  GPIO_InitStruct.Pin = GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
  UartReady = SET;
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  UartReady = SET;
}

---------------------------------------------------
一、解決:
其實我寫的代碼本身沒有太大問題,問題出現在我用的串口工具。
1、白天描述的UART連續發2個字符串,但只顯示1個字符串。

其實2個字符串都已經發送,但是串口沒有顯示出來而已,我把顯示方式切換到十六進制數時,就可以看到數據要比顯示的多,是第一個和第二個字符串都有。

應該問題出現在那個00上,每一個字符串結束標示符,我程序中發送時,是吧整個字符串,連同結束標識一塊都發送出去了,而這個串口調試助手在這里可能顯示有問題。
我把程序改成這樣,每次發送字符串時,串口中斷發送字符串長度為原來長度減1.

結果重新運行,就可以顯示2個字符串了。

2、其實換一個串口調試助手也可以看到此類問題:

結論,看來一個好的調試工具非常重要。

二、總結
接下來總結一下HAL庫中串口UART中斷發送數據的編程方法,給朋友們一起共享一下:
第一步:填充串口結構體變量huart2,使用HAL_UART_Init()函數初始化串口
  1. huart2.Instance = USART2;
  2.   huart2.Init.BaudRate = 115200;
  3.   huart2.Init.WordLength = UART_WORDLENGTH_8B;
  4.   huart2.Init.StopBits = UART_STOPBITS_1;
  5.   huart2.Init.Parity = UART_PARITY_NONE;
  6.   huart2.Init.Mode = UART_MODE_TX;
  7.   huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  8.   huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  9.   huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED ;
  10.    huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  11.   HAL_UART_Init(&huart2);
復制代碼
第二步:在需要發送數據時調用HAL_UART_Transmit_IT()函數啟動發送數據。
HAL_UART_Transmit_IT(&huart2, (uint8_t *)TxBuffer1, TXBUFFERSIZE1 - 1);

第三步:串口自動啟動發送中斷,當每次中斷時,自動進入中斷USART2_IRQHandler()函數,調用庫中的HAL_UART_IRQHandler()函數,這個函數不用大家編寫,由庫已經寫好。
  1.     void USART2_IRQHandler(void)
  2.     {
  3.       HAL_UART_IRQHandler(&huart2);
  4.     }
復制代碼
第四步:當串口中斷發送完所有需要發送的數據時,自動調用HAL_UART_TxCpltCallback()這個串口發送完成的回調函數。在這里大家寫上自己的串口發送完畢的處理事件,當然我這里將自定義的標志置位。
  1.     void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
  2.     {
  3.       UartReady = SET;
  4.     }
復制代碼
第五步:在主函數中,啟動發送數據HAL_UART_Transmit_IT()函數后,要判斷數據是否發送完成,即UartReady標志,當發現置1即知道數據發送完畢,之后清標志位,就可以進行下一次發送了。
  1.        while (UartReady != SET)
  2.         {
  3.           ;
  4.         }
  5.         UartReady = RESET;
復制代碼

最后把我修改后的程序上傳上來:
UART_LED.rar (6.74 MB, 下載次數: 24)
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:185641 發表于 2017-4-2 18:58 | 只看該作者
這個需要看看
回復

使用道具 舉報

板凳
ID:280567 發表于 2018-1-29 17:15 | 只看該作者
謝謝分享~
回復

使用道具 舉報

地板
ID:602141 發表于 2019-8-20 22:01 | 只看該作者
正在學習中,感謝分享!!
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美高清性xxxxhd | 91国内在线观看 | 青青草视频网 | av中文字幕在线 | 国产高清视频在线观看 | 99视频免费| 国产激情视频 | 情侣av | 黄色片在线网站 | 一区二区三区国产精品 | 欧美日本韩国一区二区 | 亚洲国产激情 | 黄色av一区 | 欧美最猛性xxxxx亚洲精品 | 亚洲激情在线视频 | 国产精品久久久久久福利一牛影视 | 亚洲精品在线看 | 日韩国产精品一区二区三区 | 亚洲毛片在线观看 | 九色国产 | 天天操天天操 | 欧美a级成人淫片免费看 | 亚洲人成在线播放 | 天天夜夜操 | 国产一级在线观看 | 伊人成人免费视频 | 亚洲精品一区二三区不卡 | 亚洲精品18| 精品一区二区三区四区 | 麻豆久久久久久久 | 激情一区二区三区 | 国产亚洲一级 | 日韩成人在线网址 | 99re66在线观看精品热 | 黄a网站| 成人免费视频观看视频 | 亚洲五码久久 | 成人免费淫片aa视频免费 | 国产高清在线精品 | 一区二区三区四区av | 国产精品日韩欧美一区二区 |