实训day2_2|完成一些小任务功能

读芯片手册

主要是读地址,层层递进

  1. 首先查阅GEC-M4原理图的pdf,找出芯片对应的引脚标号
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  1. 查阅芯片手册,层层递进找到对应的基地址(RCC寄存器和GPIO寄存器)
    在这里插入图片描述
    在这里插入图片描述

任务案例

例一

查阅芯片手册和原理图,实现功能:

四个按键对应控制四个灯,按下亮,松开灭

代码如下:

#include "stm32f4xx.h"

#define RCC_BASEADDR 0x40023800		//RCC外设基地址
#define RCC_AHB1ENR		*(int *)(RCC_BASEADDR+0x30)		//AHB1基地址

#define GPIOA_BASEADDR 0x40020000 //GPIOA外设基地址
#define GPIOA_MODER		*(int *)(GPIOA_BASEADDR+0x00)	//模式寄存器
#define GPIOA_OTYPER	*(int *)(GPIOA_BASEADDR+0x04)	//输出寄存器
#define GPIOA_OSPEEDR	*(int *)(GPIOA_BASEADDR+0x08)	//速度寄存器
#define GPIOA_PUPDR		*(int *)(GPIOA_BASEADDR+0x0C)	//上下拉寄存器
#define GPIOA_ODR		*(int *)(GPIOA_BASEADDR+0x14)	//输出数据寄存器
#define GPIOA_IDR		*(int *)(GPIOA_BASEADDR+0x10) //输入数据寄存器

#define GPIOE_BASEADDR 0x40021000	//GPIOE外设基地址
#define GPIOE_MODER		*(int *)(GPIOE_BASEADDR+0x00)	//模式寄存器
#define GPIOE_OTYPER	*(int *)(GPIOE_BASEADDR+0x04)	//输出寄存器
#define GPIOE_OSPEEDR	*(int *)(GPIOE_BASEADDR+0x08)	//速度寄存器
#define GPIOE_PUPDR		*(int *)(GPIOE_BASEADDR+0x0C)	//上下拉寄存器
#define GPIOE_ODR		*(int *)(GPIOE_BASEADDR+0x14)	//输出数据寄存器
#define GPIOE_IDR		*(int *)(GPIOE_BASEADDR+0x10) //输入数据寄存器


#define GPIOF_BASEADDR 0x40021400	//GPIOF外设基地址
#define GPIOF_MODER		*(int *)(GPIOF_BASEADDR+0x00)	//模式寄存器
#define GPIOF_OTYPER	*(int *)(GPIOF_BASEADDR+0x04)	//输出寄存器
#define GPIOF_OSPEEDR	*(int *)(GPIOF_BASEADDR+0x08)	//速度寄存器
#define GPIOF_PUPDR		*(int *)(GPIOF_BASEADDR+0x0C)	//上下拉寄存器
#define GPIOF_ODR		*(int *)(GPIOF_BASEADDR+0x14)	//输出数据寄存器


int main(void)
{

	/*开启时钟AHB1*/
	RCC_AHB1ENR |= (0x1 << 0);    //GPIOA
	RCC_AHB1ENR |= (0x1 << 4);		//GPIOE
	RCC_AHB1ENR |= (0x1 << 5);		//GPIOF

	/*配置输出输入模式*/
	//GPIOA
	GPIOA_MODER &= ~(0x3<<2*0);  //key0
	//GPIOF
	GPIOF_MODER &= ~(0x3 << 2*8);		//beep
	GPIOF_MODER |= (0x1 << 2*8);
	GPIOF_MODER &= ~(0x3 << 2*9);		//led0
	GPIOF_MODER |= (0x1 << 2*9);
	GPIOF_MODER &= ~(0x3 << 2*10);		//led1
	GPIOF_MODER |= (0x1 << 2*10);
	
	
	//GPIOE
	GPIOE_MODER &= ~(0x3 << 2*13);		//led2
	GPIOE_MODER |= (0x1 << 2*13);
	GPIOE_MODER &= ~(0x3 << 2*14);		//led3
	GPIOE_MODER |= (0x1 << 2*14);
	GPIOE_MODER &= ~(0x3 << 2*2);     //key1
	GPIOE_MODER &= ~(0x3 << 2*3);     //key2
	GPIOE_MODER &= ~(0x3 << 2*4);     //key3

	/*配置输出模式为推挽输出*/
	//GPIOF
	GPIOF_OTYPER &= (0x1<<1*8);  //beep
	GPIOF_OTYPER &= (0x1 << 1*9);		//led0
	GPIOF_OTYPER &= (0x1 << 1*10);		//led1
	//GPIOE
	GPIOE_OTYPER &= (0x1 << 1*13);		//led2
	GPIOE_OTYPER &= (0x1 << 1*14);		//led3

	/*输出速度25M中速*/
	//GPIOF
	GPIOF_OSPEEDR &= ~(0x3<<2*8);  //beep
	GPIOF_OSPEEDR	|= (0x1<<2*8);
	GPIOF_OSPEEDR &= ~(0x3 << 2*9);		//led0
	GPIOF_OSPEEDR |= (0x1 << 2*9);
	GPIOF_OSPEEDR &= ~(0x3 << 2*10);	//led1
	GPIOF_OSPEEDR |= (0x1 << 2*10);
	//GPIOE
	GPIOE_OSPEEDR &= ~(0x3 << 2*13);		//led2
	GPIOE_OSPEEDR |= (0x1 << 2*13);
	GPIOE_OSPEEDR &= ~(0x3 << 2*14);		//led3
	GPIOE_OSPEEDR |= (0x1 << 2*14);

	/*设置上下拉模式*/
	//GPIOA
	GPIOA_PUPDR &= ~(0x3<<2*0);  //key0
	//GPIOF
	GPIOF_PUPDR &= ~(0x3<<2*8);   //beep
	GPIOF_PUPDR |= (0x1<<2*8);
	GPIOF_PUPDR &= ~(0x3 << 2*9);		//led0
	GPIOF_PUPDR |= (0x1 << 2*9);
	GPIOF_PUPDR &= ~(0x3 << 2*10);		//led1
	GPIOF_PUPDR |= (0x1 << 2*10);
	//GPIOE
	GPIOE_PUPDR &= ~(0x3 << 2*13);		//led2
	GPIOE_PUPDR |= (0x1 << 2*13);
	GPIOE_PUPDR &= ~(0x3 << 2*14);		//led3
	GPIOE_PUPDR |= (0x1 << 2*14);
	GPIOE_PUPDR &= ~(0x3 << 2*2);    //key1
	GPIOE_PUPDR &= ~(0x3 << 2*3);    //key2
	GPIOE_PUPDR &= ~(0x3 << 2*4);    //key3

	/*高电平*/
	GPIOF_ODR &= ~(0x1<<1*8);
	GPIOF_ODR |= (0x1 <<1*9);
	GPIOF_ODR |= (0x1 <<1*10);
	GPIOE_ODR |= (0x1 <<1*13);
	GPIOE_ODR |= (0x1 <<1*14);
	/*低电平*/
	/*GPIOF_ODR &=~ (0x1 <<1*9);
	GPIOF_ODR &=~ (0x1 <<1*10);
	GPIOE_ODR &=~ (0x1 <<1*13);
	GPIOE_ODR &=~ (0x1 <<1*14);*/
	while (1)
	{
		if((GPIOA_IDR &(0x1<<1*0))==0) GPIOF_ODR &=~ (0x1 <<1*9);
		else GPIOF_ODR |= (0x1 <<1*9);
		if((GPIOE_IDR &(0x1<<1*2))==0) GPIOF_ODR &= ~(0x1 <<1*10);
		else GPIOF_ODR |= (0x1 <<1*10);
		if((GPIOE_IDR &(0x1<<1*3))==0) GPIOE_ODR &= ~(0x1 <<1*13);
		else GPIOE_ODR |= (0x1 <<1*13);
		if((GPIOE_IDR &(0x1<<1*4))==0) GPIOE_ODR &= ~(0x1 <<1*14);
		else GPIOE_ODR |= (0x1 <<1*14);
		daley(100);
	}

	return 0;
}

例二

实现流水灯等花样显示,并且实现蜂鸣器发声。

代码如下:

#include "stm32f4xx.h"


typedef struct
{
	unsigned int MODER;
	unsigned int OTYPER;
	unsigned int OSPEEDR;
	unsigned int PUPDR;
	unsigned int IDR;
	unsigned int ODR;
} GPIO_Type;

//外设基地址
#define GPIOA_BASEADDR 0x40020000 //GPIOA
#define GPIOE_BASEADDR 0x40021000	//GPIOE
#define GPIOF_BASEADDR 0x40021400	//GPIOF




#define GPIOa ((GPIO_Type *)GPIOA_BASEADDR)
#define GPIOe ((GPIO_Type *)GPIOE_BASEADDR)
#define GPIOf ((GPIO_Type *)GPIOF_BASEADDR)



#define RCC_BASEADDR 0x40023800		//RCC外设基地址
#define RCC_AHB1ENR		*(unsigned int *)(RCC_BASEADDR+0x30)		//AHB1基地址


void delay_ms(int ms)
{
	int i,j;
	for(i=0; i<ms; i++)
	{
		for(j=0; j<10000; j++);
	}
}


void config()
{
	/*开启时钟AHB1*/
	RCC_AHB1ENR |= (0x1 << 0);		//GPIOA
	RCC_AHB1ENR |= (0x1 << 4);		//GPIOE
	RCC_AHB1ENR |= (0x1 << 5);		//GPIOF


	/*配置为输出模式*/
	//GPIOF
	GPIOf->MODER &= ~(0x3 << 2*8);		//beep
	GPIOf->MODER |= (0x1 << 2*8);

	GPIOf->MODER &= ~(0x3 << 2*9);		//led0
	GPIOf->MODER |= (0x1 << 2*9);
	GPIOf->MODER &= ~(0x3 << 2*10);		//led1
	GPIOf->MODER |= (0x1 << 2*10);

	//GPIOE
	GPIOe->MODER &= ~(0x3 << 2*13);		//led2
	GPIOe->MODER |= (0x1 << 2*13);
	GPIOe->MODER &= ~(0x3 << 2*14);		//led3
	GPIOe->MODER |= (0x1 << 2*14);

	/*配置为输入模式*/
	GPIOa->MODER &= ~(0x3 << 2*0);		//key1
	GPIOe->MODER &= ~(0x3 << 2*2);		//key2
	GPIOe->MODER &= ~(0x3 << 2*3);		//key3
	GPIOe->MODER &= ~(0x3 << 2*4);		//key4


	/*配置输出模式为推挽输出*/
	//GPIOF
	GPIOf->OTYPER &= (0x1 << 1*8);		//beep

	GPIOf->OTYPER &= (0x1 << 1*9);		//led0
	GPIOf->OTYPER &= (0x1 << 1*10);		//led1
	//GPIOE
	GPIOe->OTYPER &= (0x1 << 1*13);		//led2
	GPIOe->OTYPER &= (0x1 << 1*14);		//led3


	/*输出速度25M中速*/
	//GPIOF
	GPIOf->OSPEEDR &= ~(0x3 << 2*8);		//beep
	GPIOf->OSPEEDR |= (0x1 << 2*8);

	GPIOf->OSPEEDR &= ~(0x3 << 2*9);		//led0
	GPIOf->OSPEEDR |= (0x1 << 2*9);
	GPIOf->OSPEEDR &= ~(0x3 << 2*10);	//led1
	GPIOf->OSPEEDR |= (0x1 << 2*10);
	//GPIOE
	GPIOe->OSPEEDR &= ~(0x3 << 2*13);		//led2
	GPIOe->OSPEEDR |= (0x1 << 2*13);
	GPIOe->OSPEEDR &= ~(0x3 << 2*14);		//led3
	GPIOe->OSPEEDR |= (0x1 << 2*14);



	/*设置上下拉模式为上拉*/
	//GPIOF
	GPIOf->PUPDR &= ~(0x3 << 2*9);		//beep
	GPIOf->PUPDR |= (0x1 << 2*9);

	GPIOf->PUPDR &= ~(0x3 << 2*9);		//led0
	GPIOf->PUPDR |= (0x1 << 2*9);
	GPIOf->PUPDR &= ~(0x3 << 2*10);		//led1
	GPIOf->PUPDR |= (0x1 << 2*10);
	//GPIOE
	GPIOe->PUPDR &= ~(0x3 << 2*13);		//led2
	GPIOe->PUPDR |= (0x1 << 2*13);
	GPIOe->PUPDR &= ~(0x3 << 2*14);		//led3
	GPIOe->PUPDR |= (0x1 << 2*14);

	/*设置上下拉模式为保留*/
	GPIOa->PUPDR &= ~(0x3 << 2*0);		//key1
	GPIOa->PUPDR |= (0x3 << 2*0);
	GPIOe->PUPDR &= ~(0x3 << 2*2);		//key2
	GPIOe->PUPDR |= (0x3 << 2*2);
	GPIOe->PUPDR &= ~(0x3 << 2*3);		//key3
	GPIOe->PUPDR |= (0x3 << 2*3);
	GPIOe->PUPDR &= ~(0x3 << 2*4);		//key4
	GPIOe->PUPDR |= (0x3 << 2*4);
}



int main(void)
{

	int a;

	config();

	while(1)
	{
		/*高电平*/
		GPIOf->ODR |= (0x1 <<1*9);
		GPIOf->ODR |= (0x1 <<1*10);
		GPIOe->ODR |= (0x1 <<1*13);
		GPIOe->ODR |= (0x1 <<1*14);


		//key1		蜂鸣器响四下
		if(GPIOa->IDR == (GPIOa->IDR & (~(0x1 <<1*0))))
		{

			for(a=0; a<4; a++)
			{
				GPIOe->IDR |= (0x1 <<1*4);

				GPIOf->ODR |= (0x1 <<1*8);
				delay_ms(100);
				GPIOf->ODR &=~ (0x1 <<1*8);
				delay_ms(100);
				delay_ms(100);
				delay_ms(100);
				delay_ms(100);
				delay_ms(100);
				delay_ms(100);
				delay_ms(100);
				delay_ms(100);
				delay_ms(100);
			}


		}



		//key2		亮暗交替闪烁
		if(GPIOe->IDR == (GPIOe->IDR& (~(0x1 <<1*2))))
		{
			//GPIOE_IDR |= (0x1 <<1*2);


			for(a=0; a<4; a++)
			{

				/*低电平*/
				GPIOf->ODR &=~ (0x1 <<1*9);
				GPIOf->ODR &=~ (0x1 <<1*10);
				GPIOe->ODR &=~ (0x1 <<1*13);
				GPIOe->ODR &=~ (0x1 <<1*14);
				delay_ms(100);
				delay_ms(100);
				delay_ms(100);
				delay_ms(100);
				/*高电平*/
				GPIOf->ODR |= (0x1 <<1*9);
				GPIOf->ODR |= (0x1 <<1*10);
				GPIOe->ODR |= (0x1 <<1*13);
				GPIOe->ODR |= (0x1 <<1*14);
				delay_ms(100);
				delay_ms(100);
				delay_ms(100);
				delay_ms(100);
			}
		}
		//key3		流水灯
		if(GPIOe->IDR == (GPIOe->IDR& (~(0x1 <<1*3))))
		{
			//GPIOE_IDR |=(0x1 <<1*3);

			/*低电平*/
			GPIOf->ODR &=~ (0x1 <<1*9);
			delay_ms(100);
			GPIOf->ODR &=~ (0x1 <<1*10);
			delay_ms(100);
			GPIOe->ODR &=~ (0x1 <<1*13);
			delay_ms(100);
			GPIOe->ODR &=~ (0x1 <<1*14);
			delay_ms(100);

			/*高电平*/
			GPIOf->ODR |= (0x1 <<1*9);
			delay_ms(100);
			GPIOf->ODR |= (0x1 <<1*10);
			delay_ms(100);
			GPIOe->ODR |= (0x1 <<1*13);
			delay_ms(100);
			GPIOe->ODR |= (0x1 <<1*14);
			delay_ms(100);

		}



		//key4		第一、三灯亮,第二、四灯暗,然后交替闪烁
		if(GPIOe->IDR == (GPIOe->IDR& (~(0x1 <<1*4))))
		{
			//GPIOE_IDR |= (0x1 <<1*2);


			for(a=0; a<4; a++)
			{

				GPIOf->ODR |= (0x1 <<1*9);
				GPIOf->ODR &=~ (0x1 <<1*10);
				GPIOe->ODR |= (0x1 <<1*13);
				GPIOe->ODR &=~ (0x1 <<1*14);
				delay_ms(100);
				delay_ms(100);
				delay_ms(100);
				delay_ms(100);

				GPIOf->ODR &=~ (0x1 <<1*9);
				GPIOf->ODR |= (0x1 <<1*10);
				GPIOe->ODR &=~ (0x1 <<1*13);
				GPIOe->ODR |= (0x1 <<1*14);
				delay_ms(100);
				delay_ms(100);
				delay_ms(100);
				delay_ms(100);
			}
		}

	}


	return 0;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值