ECE STM32开发 LED

实验报告

一、实验目的

  • 了解函数库的结构和功能,学习使用STM32的固件函数库。
  • 了解外设寄存器结构体,学习采用指针方式和驱动例程配置GPIO。
  • 了解按键模块原理,学习使用按键控制LED灯亮和灭。

二、实验步骤

1.对两个按键的时钟、端口和引脚进行定义,对LED的时钟、端口和引脚进行定义。

2.定义按键按下为1,按键断开为0。

3.定义按键状态检测函数Key_Scan。若检测到按键按下,则使用while语句持续检测按键状态,直到按键释放,按键释放后该函数返回1;若没有检测到按键按下,则返回0.

4.主程序

a)设置计数器变量count,用来根据按键按下次数改变的发光颜色

b)定义一个GPIO初始结构体GPIO_InitStructure

c)使用库函数RCC_APB2PeriphClockCmd进行时钟使能

d)初始化GPIO对LED端口的写状态,模式为推挽输出,速率为10MHz

e)初始化GPIO对按键端口的读状态,模式为浮空输入,速率为10MHz

f)初始化写端口的初始输出值为1

g)按下按键1时,使用switch语句和计数器判断发光颜色。考虑到循环发光,因此发红光时让绿灯和蓝灯熄灭,红灯亮起;发绿光时只需让红灯熄灭,绿灯亮起;发蓝光时只需让绿灯熄灭,蓝灯亮起;发白光时让红灯和绿灯亮起。其中灯亮原理为令端口引脚为低电平则有电流通过,灯灭原理为令端口引脚为高电平则无电流通过。

一开始的写法为:

if (Key_Scan(KEY1_GPIO_PORT, KEY1_GPIO_PIN) == KEY_ON) {
			switch (count % 4) {
                          /*...*/
            }
            count++;
            count %= 4;
}          

但是发现这种写法会有计数器溢出的可能,因此改为:

if (Key_Scan(KEY1_GPIO_PORT, KEY1_GPIO_PIN) == KEY_ON) {
			switch (count) {
                       /*...*/
            }
            count++;
            count %= 4;
}          

h)按下按键2时,计数器归零,所有灯熄灭

三、附录

#include "stm32f10x.h"

#define KEY1_GPIO_CLK  RCC_APB2Periph_GPIOA//按键1时钟
#define KEY1_GPIO_PORT GPIOA//按键1端口
#define KEY1_GPIO_PIN  GPIO_Pin_0//按键1引脚

#define KEY2_GPIO_CLK  RCC_APB2Periph_GPIOC//按键2时钟
#define KEY2_GPIO_PORT GPIOC//按键2端口
#define KEY2_GPIO_PIN  GPIO_Pin_13//按键2引脚

#define LED_GPIO_CLK  RCC_APB2Periph_GPIOB//LED时钟
#define LED_GPIO_PORT GPIOB//LED端口

#define LEDG_GPIO_PIN GPIO_Pin_0//绿灯引脚
#define LEDB_GPIO_PIN GPIO_Pin_1//蓝灯引脚
#define LEDR_GPIO_PIN GPIO_Pin_5//红灯引脚

#define KEY_ON  1//按键按下
#define KEY_OFF 0//按键断开

//定义按键状态检测函数
uint8_t Key_Scan(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
	if (GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON) {
		while (GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON);
		return KEY_ON;
	}
	else
		return KEY_OFF;
}

int main(void)
{
	//设置计数器
	unsigned int count = 0;

	//GPIO初始类型定义
	GPIO_InitTypeDef GPIO_InitStructure;

	//时钟使能
	RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK | KEY2_GPIO_CLK | LED_GPIO_CLK, ENABLE);

	//初始化GPIO对LED端口的写状态
	GPIO_InitStructure.GPIO_Pin = LEDR_GPIO_PIN | LEDG_GPIO_PIN | LEDB_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(LED_GPIO_PORT, &GPIO_InitStructure);

	//初始化GPIO对按键1端口的读状态
	GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);

	//初始化GPIO对按键2端口的读状态
	GPIO_InitStructure.GPIO_Pin = KEY2_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);

	//初始化写端口的初始输出值
	GPIO_WriteBit(LED_GPIO_PORT, LEDR_GPIO_PIN | LEDG_GPIO_PIN | LEDB_GPIO_PIN, Bit_SET);

	while (1)
	{
		if (Key_Scan(KEY1_GPIO_PORT, KEY1_GPIO_PIN) == KEY_ON) {//按下按键1
			switch (count) {//红、绿、蓝、白光循环
			case 0://红:绿灭蓝灭红亮
				GPIO_ResetBits(LED_GPIO_PORT, LEDG_GPIO_PIN);
				GPIO_WriteBit(LED_GPIO_PORT, LEDG_GPIO_PIN, Bit_SET);
				GPIO_ResetBits(LED_GPIO_PORT, LEDB_GPIO_PIN);
				GPIO_WriteBit(LED_GPIO_PORT, LEDB_GPIO_PIN, Bit_SET);
				GPIO_ResetBits(LED_GPIO_PORT, LEDR_GPIO_PIN);
				GPIO_WriteBit(LED_GPIO_PORT, LEDR_GPIO_PIN, Bit_RESET);
				break;
			case 1://绿:红灭绿亮
				GPIO_ResetBits(LED_GPIO_PORT, LEDR_GPIO_PIN);
				GPIO_WriteBit(LED_GPIO_PORT, LEDR_GPIO_PIN, Bit_SET);
				GPIO_ResetBits(LED_GPIO_PORT, LEDG_GPIO_PIN);
				GPIO_WriteBit(LED_GPIO_PORT, LEDG_GPIO_PIN, Bit_RESET);
				break;
			case 2://蓝:绿灭蓝亮
				GPIO_ResetBits(LED_GPIO_PORT, LEDG_GPIO_PIN);
				GPIO_WriteBit(LED_GPIO_PORT, LEDG_GPIO_PIN, Bit_SET);
				GPIO_ResetBits(LED_GPIO_PORT, LEDB_GPIO_PIN);
				GPIO_WriteBit(LED_GPIO_PORT, LEDB_GPIO_PIN, Bit_RESET);
				break;
			case 3://白:红亮绿亮
				GPIO_ResetBits(LED_GPIO_PORT, LEDR_GPIO_PIN);
				GPIO_WriteBit(LED_GPIO_PORT, LEDR_GPIO_PIN, Bit_RESET);
				GPIO_ResetBits(LED_GPIO_PORT, LEDG_GPIO_PIN);
				GPIO_WriteBit(LED_GPIO_PORT, LEDG_GPIO_PIN, Bit_RESET);
				break;
			}
			count++;//计数器加一
			count %= 4;
		}
		if (Key_Scan(KEY2_GPIO_PORT, KEY2_GPIO_PIN) == KEY_ON) {//按下按键2
			count = 0;//计数器归零
			//灯全灭
			GPIO_ResetBits(LED_GPIO_PORT, LEDR_GPIO_PIN);
			GPIO_WriteBit(LED_GPIO_PORT, LEDR_GPIO_PIN, Bit_SET);
			GPIO_ResetBits(LED_GPIO_PORT, LEDG_GPIO_PIN);
			GPIO_WriteBit(LED_GPIO_PORT, LEDG_GPIO_PIN, Bit_SET);
			GPIO_ResetBits(LED_GPIO_PORT, LEDB_GPIO_PIN);
			GPIO_WriteBit(LED_GPIO_PORT, LEDB_GPIO_PIN, Bit_SET);
		}
	}
}
/************************************END OF FILE*************************************/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值