STM32CubeMx學習之——基於藍橋杯物聯網開發板實現AD轉換和OLED顯示外加串口的綜合小例程

STM32CubeMx學習之——基於藍橋杯物聯網開發板實現AD轉換和OLED顯示外加串口的綜合小例程

本實驗主要是利用OLED顯示AD轉換的結果和利用OLED字庫顯示漢字,外加串口通信做輔助調試。

OLED上電不顯示任何信息,通過串口向上位機發送字符“S”時,則OLED第一行顯示“AD量化值:XXXX”,第二行顯示“AD電壓值:X.XX”。向上位機發送字符“E”時,OLED第一行顯示“AD採集結束”。
其次上位機通過串口助手可以看到AD轉換的值,其顯示格式與上此實驗一致。

1、利用STM32CubeMx配置外設及創建工程代碼

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

2、程序配置(重要!)

在這裏插入圖片描述
將官網的這三個.c文件複製到創建好工程文件的Src文件夾下

在這裏插入圖片描述
將官網的這兩個.h文件複製到創建好工程文件的Inc文件夾下,然後打開工程。

在這裏插入圖片描述
將剛纔複製過去的三個.c文件添加到工程中

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

3、部分代碼參考

/* USER CODE BEGIN PV */
uint8_t Rx_buf = 0;	//串口接收數據變量,用來存儲串口發送的數據位
uint8_t Rx_Flag = 0;	//串口接收數據標誌位,用做開啓AD採集的開始和停止
uint8_t string[50];	//sprintf函數數據緩衝數組
float ADC_Volt = 0;	//用來接收AD量化值的變量
uint16_t ADC_Value = 0;	//用來存儲AD量化值轉換爲電壓值的變量
/* USER CODE END PV */
/* USER CODE BEGIN 0 */
/**
* @brief 串口2發送AD採集數據信息。
  * @param None
  * @retval None
  */
void USART2_Send_ADStart(void)
{
	sprintf((char *)string, "ADC_Value:%4d, ADC_Volt:%.2f\r\n", ADC_Value, ADC_Volt);	//
	HAL_UART_Transmit(&huart2, string, sizeof(string), 10000);
}

/**
* @brief 串口2發送AD採集結束信息。
  * @param None
  * @retval None
  */
void USART2_Send_ADStop(void)
{
	sprintf((char *)string, "AD採集結束\r\n");
	HAL_UART_Transmit(&huart2, string, sizeof(string), 10000);
}

/**
* @brief OLED上電顯示初始化函數。
  * @param None
  * @retval None
  */
void OLED_Display_Init(void)
{
	OLED_PowerControl(ENABLE);	//控制OLED引腳(PB5)使能,也即是給OLED上電
	HAL_Delay(200);	//延時200ms
	OLED_Init();	//OLED初始化
	OLED_Clear();	//OLED清屏
}

/**
* @brief OLED顯示字符函數,主要用來顯示第一行和第二行的文字信息。這裏要注意一個漢字所佔的是4個字節,高度和寬度各佔2個字節
  * @param None
  * @retval None
  */
void OLED_Display_ADStart_Chinese(void)
{
	sprintf((char *)string, "AD");
	OLED_ShowString(2, 0, string, 16);	//這裏顯示字符的大小尺寸是16,也就是一個字符佔2個字節,寬度佔一個字節,高度佔兩個字節
	sprintf((char *)string, "AD");
	OLED_ShowString(2, 2, string, 16);
	
	OLED_ShowCHinese(18, 0, 0);	//顯示漢字“量”
	OLED_ShowCHinese(34, 0, 1);	//顯示漢字“化”
	OLED_ShowCHinese(50, 0, 2);	//顯示漢字“值”
	OLED_ShowCHinese(18, 2, 3);	//顯示漢字“電”
	OLED_ShowCHinese(34, 2, 4);	//顯示漢字“壓”
	OLED_ShowCHinese(50, 2, 5);	//顯示漢字“值”
	
	sprintf((char *)string, ":%4d", ADC_Value);	//這裏的ADC_Value的佔位符要寫成4位整形格式,不然顯示到OLED屏幕上的數值在小於1000的時候會刷新不正確!!!
	OLED_ShowString(68, 0, string, 16);
	sprintf((char *)string, ":%.2fV", ADC_Volt);
	OLED_ShowString(68, 2, string, 16);
}

/**
* @brief OLED顯示AD採集結束信息。
  * @param None
  * @retval None
  */
void OLED_Display_ADStop_Chinese(void)
{
	sprintf((char *)string, "AD");
	OLED_ShowString(2, 0, string, 16);
	OLED_ShowCHinese(18, 0, 6);	//顯示漢字“採”
	OLED_ShowCHinese(34, 0, 7);	//顯示漢字“集”
	OLED_ShowCHinese(50, 0, 8);	//顯示漢字“結”
	OLED_ShowCHinese(66, 0, 9);	//顯示漢字“束”
	sprintf((char *)string, "      ");	//清除第一行的顯示AD量化值
	OLED_ShowString(82, 0, string, 16);
	sprintf((char *)string, "                ");	//清屏第二行
	OLED_ShowString(0, 2, string, 16);
}

/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart2, &Rx_buf, 1);	//開啓串口2中斷
OLED_Display_Init();	//OLED上電初始化函數
/* USER CODE END 2 */
 /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
	//如果開發板串口2接收開始AD轉換的字符,則開啓AD轉換,向上位機發送AD轉換的數據,並且OLED顯示AD轉換的數據
	if(Rx_Flag == 1)
	{
		HAL_ADC_Start_IT(&hadc);	//打開AD轉換
		USART2_Send_ADStart();	//串口2向上位機發送AD轉化的數據
		OLED_Display_ADStart_Chinese();	//OLED顯示AD轉換的文字信息
		HAL_Delay(1000);	//延遲1S,這裏延時的目的是爲了,串口向上位機發送數據的時候慢一點,也可不加
	}
	//如果開發板串口2接收開始AD轉換結束的字符,則關閉AD轉換,向上位機發送AD轉換關閉的文字,並且OLED顯示AD採集結束
	else if(Rx_Flag == 2)
	{
		HAL_ADC_Stop_IT(&hadc);	//關閉AD轉換
		USART2_Send_ADStop();	//串口2向上位機發送AD採集結束的文字信息
		OLED_Display_ADStop_Chinese();	//OLED顯示AD採集結束的文字信息
		HAL_Delay(1000);	//延遲1S,這裏延時的目的是爲了,串口向上位機發送數據的時候慢一點,也可不加
	}
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
/* USER CODE BEGIN 4 */
/**
  * @brief ADC開始採集數據的回調函數。
  * @param hadc:ADC通道
  * @retval None
  */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
	ADC_Value = HAL_ADC_GetValue(hadc);	//返回ADC轉換的電壓量化值
	ADC_Volt = ADC_Value * 3.3 / 4096;	//將量化值轉換爲電壓值
}

/* USER CODE BEGIN 4 */
/**
  * @brief 串口2接收數據的回調函數。
  * @param huart:串口通道
  * @retval None
  */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == USART2)
	{
		if(Rx_buf == 'S')
		{
			Rx_Flag = 1;	//如果接收到的字符爲‘S’,則標誌位爲1,在主函數中進行判斷,以此打開AD轉換
		}
		else if(Rx_buf == 'E')
		{
			Rx_Flag = 2; //如果接收到的字符爲‘E’,則標誌位爲2,在主函數中進行判斷,以此關閉AD轉換
		}
		
		HAL_UART_Receive_IT(&huart2, &Rx_buf, 1);	//重新開啓串口2中斷
	}
}
/* USER CODE END 4 */
/**
  * @brief OLED屏幕顯示一組漢字。
  * @param x 橫向選擇位置;
					 y 縱向選擇位置;
					 no 需要顯示的漢字標號;

  * @retval None
  */
void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no)
{      			    
	uint8_t t,adder=0;
	OLED_SetPos(x,y);	
	for(t=0;t<16;t++)
	{
		OLED_Write(TYPE_DATA, Hzk[2*no][t]);
		adder+=1;
	}	
	OLED_SetPos(x,y+1);	
	for(t=0;t<16;t++)
	{	
		OLED_Write(TYPE_DATA, Hzk[2*no+1][t]);
		adder+=1;
	}
}

最後一定要注意,想要OLED顯示漢字,就一定要加上上面這個顯示漢字的函數!!!

4、實驗現象

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

5、結束語

這次的實驗主要是想讓OLED顯示漢字來着,其他內容全部都是之前實驗的內容。串口也不必要開,只是我用作調程序,就沒有再刪掉了。官網提供的程序中沒有顯示漢字的函數,這裏我從其他地方找的漢字顯示函數,然後稍稍修改了下。想要顯示漢字一定要注意加上這個函數,如果不想麻煩找,評論留下郵箱,我把上面用到的三個.c文件和兩個.h文件私發郵箱。還有就是在使用取字模軟件的時候,要進行一下取字模設置,這裏我用的取字模軟件是PCtoLCD2002,要把“取模方式”改成“列行式”,“取模走向”選擇“逆向”,“點陣格式”選擇“陰碼”。可能不同的取模軟件配置不太一樣,應該也都大同小異,注意一下就好。
還要注意在OLED_Display_ADStart_Chinese這個函數的ADC_Value的佔位符要寫成4位整形格式,不然顯示到OLED屏幕上的數值在小於1000的時候會刷新不正確!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章