stm32cubeMX學習十四、遊戲搖桿模組的使用(基於野火STM32F103ZET6開發板)
本程式編寫基於秉火霸道STM32F103ZET6執行環境。
今天來玩一個PS2遊戲搖桿模組,也被稱為Joystick,根據模組提供的手冊,下面來了解下工作原理以及如何來應用。
看到這裡我們就明白了,x,y是模擬量,而z是一個二值資料,在這裡,可以利用STM32的ADC控制器來讀取X,Y的輸出,Z軸就很簡單了,把它當作普通按鍵就可以了。
一、開啟CubeMX進行基礎配置
1.1、配置外部時鐘
1.2、配置偵錯程式
1.3、配置串列埠除錯,預設即可
1.4、配置ADC
關於ADC輸入通道在STM32F103ZET6這款MCU裡的分配表
設定資料右對齊、使能掃描和連續轉換,間斷轉換模式關閉,使能通道,這裡選擇兩個通道,分別是通道6和通道7,設定好兩個通道的轉換週期,預設為最大。
使能DMA,這樣可以為CPU減負。
設定ADC1的DMA1通道1,外設到記憶體方向,迴圈模式,地址自增及資料寬度。
1.5、配置Z軸輸入IO
1.6、生成基本工程
二、增加軟體邏輯
//定義printf的重定向函式fputc,滿足串列埠除錯列印
int fputc(int ch, FILE* file)
{
return HAL_UART_Transmit(&huart2, (uint8_t*)&ch, 1, 100);
}
//透過DMA通道轉換得到的值
uint32_t JOY_VALUE[2];
//儲存轉換計算後的電壓值
__IO float ADC_VOL_VALUE[2];
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
#define LEFT_UP 4
#define LEFT_DOWN 5
#define RIGHT_UP 6
#define RIGHT_DONW 7
#define ENTER 8
#define UNKNOW_KEY 99
//獲取搖桿鍵值
uint8_t GET_KEY_VALUE(int x, int y, int z)
{
if((0 == x) && (y > 100 && y < 255))
return UP;
else if((255 == x) && (y > 0 && y < 255))
return DOWN ;
else if((x > 0 && x < 255) && (255 == y))
return LEFT ;
else if((x > 0 && x < 255) && (0 == y))
return RIGHT ;
else if((0 == x) && (255 == y))
return LEFT_UP ;
else if((255 == x) && (255 == y))
return LEFT_DOWN ;
else if((0 == x) && (0 == y))
return RIGHT_UP ;
else if((255 == x) && (0 == y))
return RIGHT_DONW ;
else if(x > 0 && y > 0 && 0 == z)
return ENTER ;
return UNKNOW_KEY ;
}
以上的GET_KEY_VALUE是經過動手實踐得出的6個方向的數值以及確定返回的鍵值的對映。
主函式實現:
int main(void)
{
/* USER CODE BEGIN 1 */
int JOY_X, JOY_Y, JOY_Z ;
uint8_t key_value ;
/* USER CODE END 1 */
/* MCU Configuration————————————————————————————*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick。 */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
HAL_ADC_Start_DMA(&hadc1, JOY_VALUE, 2);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//3。3V位AD轉換的參考電壓值,STM32的AD轉換為12bit,所以2^12=4096
//故當輸入參考電壓為3。3V時,AD轉換的結果為4096
//取12bit數值
ADC_VOL_VALUE[0] = (float)(JOY_VALUE[0] & 0xFFF) * 3。3 / 4096 ;
ADC_VOL_VALUE[1] = (float)(JOY_VALUE[1] & 0xFFF) * 3。3 / 4096 ;
printf(“x:%。2fv y:%。2fv\n”, ADC_VOL_VALUE[0], ADC_VOL_VALUE[1]);
//只取8位有效資料
JOY_X = JOY_VALUE[0] & 0xFF;
JOY_Y = JOY_VALUE[1] & 0xFF;
JOY_Z = HAL_GPIO_ReadPin(JOY_Z_GPIO_Port, JOY_Z_Pin);
key_value = GET_KEY_VALUE(JOY_X, JOY_Y, JOY_Z);
printf(“x:%d y:%d z:%d\n”, JOY_X, JOY_Y, JOY_Z);
switch(key_value)
{
case UP :
printf(“上\n”);
break ;
case DOWN :
printf(“下\n”);
break ;
case LEFT :
printf(“左\n”);
break ;
case RIGHT :
printf(“右\n”);
break ;
case LEFT_UP:
printf(“左上\n”);
break ;
case LEFT_DOWN:
printf(“左下\n”);
break ;
case RIGHT_UP:
printf(“右上\n”);
break ;
case RIGHT_DONW :
printf(“右下\n”);
break ;
case ENTER :
printf(“確認\n”);
break ;
default:
break ;
}
HAL_Delay(200);
}
/* USER CODE END 3 */
}
三、實驗結果
當沒有撥動搖桿時:
當撥動檔杆向左時:
當按下確認時候,Z軸輸出為0