STM32单片机外接扩展板D2、D3接开关S2和S3,D9、D10、D11接RGB三色LED灯,要求每次按下S2开关一次,三色灯按红、绿、蓝颜色变化,每次按下S3开关一次,三色灯按蓝、绿、红颜色变化,每次颜色变化时,通过串行口向计算机发送“按下按钮:SX,当前颜色是:X色
时间: 2023-06-24 07:08:26 浏览: 74
这个任务可以通过编写STM32单片机的程序来实现。建议使用HAL库来编写程序,以下是大致的思路:
1. 初始化GPIO口,将D2、D3、D9、D10、D11设置为输出模式,将D2、D3设置为输入模式,并使能内部上拉电阻。
2. 在主函数中,设置一个死循环,在循环中不断检测D2、D3的状态,当检测到D2被按下时,执行一个函数来控制三色灯的颜色变化,每次按下D2,颜色按红、绿、蓝颜色变化;当检测到D3被按下时,执行另一个函数来控制三色灯的颜色变化,每次按下D3,颜色按蓝、绿、红颜色变化。
3. 在控制三色灯颜色变化的函数中,使用HAL库提供的GPIO控制函数来控制RGB三色灯的颜色变化,并在每次变化时通过串口发送一条包含按下按钮和当前颜色的信息。
下面是伪代码实现:
```
#include "stm32f1xx_hal.h"
#include "stdio.h"
GPIO_InitTypeDef GPIO_InitStruct;
void SystemClock_Config(void);
void LED_Color_R(void)
{
HAL_GPIO_WritePin(D9_GPIO_Port, D9_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(D10_GPIO_Port, D10_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(D11_GPIO_Port, D11_Pin, GPIO_PIN_SET);
printf("按下按钮:S2,当前颜色是:红色\n");
}
void LED_Color_G(void)
{
HAL_GPIO_WritePin(D9_GPIO_Port, D9_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(D10_GPIO_Port, D10_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(D11_GPIO_Port, D11_Pin, GPIO_PIN_SET);
printf("按下按钮:S2,当前颜色是:绿色\n");
}
void LED_Color_B(void)
{
HAL_GPIO_WritePin(D9_GPIO_Port, D9_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(D10_GPIO_Port, D10_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(D11_GPIO_Port, D11_Pin, GPIO_PIN_RESET);
printf("按下按钮:S2,当前颜色是:蓝色\n");
}
void LED_Color_RB(void)
{
HAL_GPIO_WritePin(D9_GPIO_Port, D9_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(D10_GPIO_Port, D10_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(D11_GPIO_Port, D11_Pin, GPIO_PIN_SET);
printf("按下按钮:S3,当前颜色是:蓝色\n");
}
void LED_Color_RG(void)
{
HAL_GPIO_WritePin(D9_GPIO_Port, D9_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(D10_GPIO_Port, D10_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(D11_GPIO_Port, D11_Pin, GPIO_PIN_RESET);
printf("按下按钮:S3,当前颜色是:绿色\n");
}
void LED_Color_BR(void)
{
HAL_GPIO_WritePin(D9_GPIO_Port, D9_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(D10_GPIO_Port, D10_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(D11_GPIO_Port, D11_Pin, GPIO_PIN_RESET);
printf("按下按钮:S3,当前颜色是:红色\n");
}
int main(void)
{
HAL_Init();
SystemClock_Config();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = D2_Pin | D3_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = D9_Pin | D10_Pin | D11_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
while (1)
{
if (HAL_GPIO_ReadPin(D2_GPIO_Port, D2_Pin) == GPIO_PIN_RESET)
{
LED_Color_R();
HAL_Delay(500);
LED_Color_G();
HAL_Delay(500);
LED_Color_B();
HAL_Delay(500);
}
if (HAL_GPIO_ReadPin(D3_GPIO_Port, D3_Pin) == GPIO_PIN_RESET)
{
LED_Color_RB();
HAL_Delay(500);
LED_Color_RG();
HAL_Delay(500);
LED_Color_BR();
HAL_Delay(500);
}
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
```
以上代码中使用了HAL库提供的GPIO控制函数进行三色灯的颜色变化控制,使用了printf函数来通过串口发送当前按钮和颜色信息。其中,SystemClock_Config是用来配置系统时钟的函数。
需要注意的是,以上代码中的Delay函数需要使用HAL库中的实现方式,可以在stm32f1xx_hal.c文件中找到:
```
__weak void HAL_Delay(uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
/* Add a freq to guarantee minimum wait */
if (wait < HAL_MAX_DELAY)
{
wait += (uint32_t)(uwTickFreq);
}
while ((HAL_GetTick() - tickstart) < wait)
{
}
}
```