一、led函数
需求:输出低电平 点亮
输出高电平 熄灭

(一) 查led引脚

查原理图可得,LED1~4对应的引脚是PE2~PE5,即GPIOE的port2~port5
(二) led初始化
开时钟

我们查一下数据手册,发现GPIOE对应的时钟总线是RCC的APB2ENR寄存器
于是再去翻参考手册,发现该寄存器GPIOE对应的位数是第六位

翻参考手册,发现该寄存器GPIOE对应的位数是第六位
于是我们把相应的位置1,即可开启GPIOE的时钟
RCC->APB2ENR |= (0X1<<6); //开启GPIOE的时钟
设置引脚模式
开启时钟后,我们要设置一下led1对应的GPIOE的PE2引脚
查阅参考手册,寄存器的0~7端口由CRL*地位寄存器管理
记忆技巧:低位引脚CRL(low),高位引脚CRH(high)

CRL每四位管理一个引脚,PE2对应的位为8-11位,需要给引脚输出低电平,所以我们要设置模式为通用推挽输出,速度50MHZ,即8-11位设置为0011
操作手法:
首先将8-11清零
(0XF<<8)其中 管led灯的 有4位 0xF == 1111 <<8 是要把8-11位清0
然后再将8,9位 置1 即可
(0x3<<8) 其中 0x3 是为了设置模式 为0x3== 0011 <<8 作用相同为了把8-11位 设置成0011
****清零操作***

***置1操作***

输出电平
输出,需要操作输出寄存器ODR
记忆技巧:输出寄存器ODR(output) 输入寄存器IDR(intut)
查阅参考手册

由图可知,若想给PE2引脚输出一个低电平,把第二位清零即可
GPIOE ->ODR &=~ (0X01<<2);//第二位清零,输出低电平,灯亮
*技巧:操作ODR寄存器时,操作哪一位就移几位
这是时候对于PE2引脚的操作流程就写完了,完整代码如下
//开时钟
RCC->APB2ENR |= (0X1<<6);
//设置引脚模式
GPIOE->CRL &=~(0XF<<8);//CRL 8-11位清零
GPIOE->CRL |=(0X03<<8);//8-11位0011 通用推免输出
//点灯
GPIOE ->ODR &=~ (0X01<<2);//第二位清零,输出低电平,灯亮
至于PE3,PE4,PE5,操作基本相同,只需要修改操作的位即可
完整代码如下
//PE3
GPIOE->CRL &=~(0XF<<12);//CRL 12-15位清零
GPIOE->CRL |=(0X03<<12);//通用推免输出
GPIOE ->ODR &=~ (0X01<<3);//点灯
//PE4
GPIOE->CRL &=~(0XF<<16);//CRL 16-20位清零
GPIOE->CRL |=(0X03<<16);//通用推免输出
GPIOE ->ODR &=~ (0X01<<4);//点灯
//PE5
GPIOE->CRL &=~(0XF<<20);//CRL 20-24位清零
GPIOE->CRL |=(0X03<<20);//通用推免输出
GPIOE ->ODR &=~ (0X01<<5);//点灯
关灯,只需要把输出寄存器ODR的第2,3,4,5位全部设置为高电平即可
GPIOE->ODR |= (0xF << 2);
*置高 PE2~PE5(1为高电平,高电平关灯) 关闭这四个灯 F正好表示四位 然后移两位就是PE2-PE5
(三) 封装led函数
寄存器操作难免有些累
把他封装成一个个函数会省很多事情
首先,初始化led函数,需要完成开时钟和设置引脚模式,开关灯操作单独封装
代码如下
void led_config(void)
{
//开时钟
RCC->APB2ENR |= (0X1<<6);
//设置引脚模式
//PE2
GPIOE->CRL &=~(0XF<<8);//CRL 8-11位清零
GPIOE->CRL |=(0X03<<8);//8-11位0011 通用推免输出
//PE3
GPIOE->CRL &=~(0XF<<12);//CRL 12-15位清零
GPIOE->CRL |=(0X03<<12);//通用推免输出
//PE4
GPIOE->CRL &=~(0XF<<16);//CRL 16-20位清零
GPIOE->CRL |=(0X03<<16);//通用推免输出
//PE5
GPIOE->CRL &=~(0XF<<20);//CRL 20-24位清零
GPIOE->CRL |=(0X03<<20);//通用推免输出
}
用PE2开灯举例子,
GPIOE ->ODR &=~ (0X01<<2);
该代码存在两个变量更换端口时,这两个值会变。所以封装时,把他俩当参数传进去就可以实现开灯操作
GPIOE是一个结构体,在标准库中已有定义

所以我们设置一下参数即可
#define led1port GPIOE //PE2
#define led2port GPIOE //PE3
#define led3port GPIOE //PE4
#define led4port GPIOE //PE5
#define led1pin 1<<2
#define led2pin 1<<3
#define led3pin 1<<4
#define led4pin 1<<5
封装后的开关灯代码如下
//开灯函数
void led_on(GPIO_TypeDef * port,uint16_t pin)
{
port->ODR &=~ (pin);
}
//关灯函数
void led_off(GPIO_TypeDef * port,uint16_t pin)
{
port->ODR |= (pin);
}
封装后
led_on(led1port,led1pin); 如此可实现对led1的开灯操作,见名知意,关灯函数同理
led头文件如下
#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h"
#include "delay.h"
void led_config(void);
void led_on(GPIO_TypeDef * port,uint16_t pin);
void led_off(GPIO_TypeDef * port,uint16_t pin);
#define led1port GPIOE //PE2
#define led2port GPIOE //PE3
#define led3port GPIOE //PE4
#define led4port GPIOE //PE5
#define led1pin 1<<2
#define led2pin 1<<3
#define led3pin 1<<4
#define led4pin 1<<5
#endif
二、延时函数
讲解略,直接上代码
#include "delay.h"
void delay_1us(void)
{
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
}
//us延时函数
void delay_us(uint32_t t)
{
for(uint32_t i =0;i<t;i++)
{
delay_1us();
}
}
//ms函数
void delay_ms(uint32_t t)
{
t=1000*t;
for(uint32_t i =0;i<t;i++)
{
delay_1us();
}
}
三、beep函数
beep函数用于操作蜂鸣器
高电平响
低电平停

(一) 查beep引脚

由图可知beep对应单片机的PC0引脚,即GPIOC的第0位引脚
(二) beep初始化
开时钟
可参考led开时钟分析
RCC->APB2ENR |= (0X1<<4); //开启控制GPIOC的时钟
设置引脚模式
设置PC0引脚模式
参考GPIOE->CRL可知PC0被前四位管理
GPIOC->CRL &=~(0XF<<0);//CRL 0-4位清零
GPIOC->CRL |=(0X03<<0);//设置模式为通用推挽
输出电平
GPIOC ->ODR |= (0X01<<0); //设置输出位为1高电平,高电平beep响
GPIOC ->ODR |= (0X01<<0); //设置输出位为0低电平,高电平beep停
*蜂鸣器操作和led操作相反,设置时要注意
(三) 封装beep函数
封装原理和led相同
代码如下
void beep_config(void)//初始化蜂鸣器
{
//开时钟
RCC->APB2ENR |= (0X1<<4); //开启控制GPIOC的时钟
//设置模式
GPIOC->CRL &=~(0XF<<0);//CRL 0-4位清零
GPIOC->CRL |=(0X03<<0);//设置模式为通用推挽
}
void beep_on(GPIO_TypeDef * port,uint16_t pin) //开蜂鸣器函数
{
port->ODR |= (pin);
}
void beep_off(GPIO_TypeDef * port,uint16_t pin) //关蜂鸣器函数
{
port->ODR &=~ (pin);
}
beep函数头文件如下
#ifndef __BEEP_H
#define __BEEP_H
#include "stm32f10x.h"
void beep_config(void);
void beep_off(GPIO_TypeDef * port,uint16_t pin);
void beep_on(GPIO_TypeDef * port,uint16_t pin);
#define beepport GPIOC
#define beeppin 0X01<<0
#endif
标准库函数应用
1.初始化
该段参考STM32固件库使用手册
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_XX; //设置引脚XX
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //10MHZ为速度
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //IN_FLOATING为模式
GPIO_Init(GPIOX, &GPIO_InitStructure); //初始化GPIOX
2.设置I/O电平
GPIO_SetBits / GPIO_ResetBits
GPIO_SetBits(GPIOA, GPIO_Pin_10 | GPIO_Pin_15); //设置GPIOA的10,15引脚为高电平
GPIO_ResetBits(GPIOB, GPIO_Pin_9 | GPIO_Pin_12); //设置GPIOA的9,12引脚为低电平
SetBits---设为高电平
ResetBits---设为低电平
GPIO_WriteBit
GPIO_WriteBit(GPIOA, GPIO_Pin_15, Bit_SET); //前两个参数 同SetBits,最后一个参数是把电平设置为0或1
四、 relay函数
(一) 查引脚
需求:输出高电平,吸合
输出低电平,断开


从原理图上看relay对应GPIOA的第11个引脚
(二) relay初始化
开时钟

翻参考手册,发现该寄存器GPIOA对应的位数是第2位
于是我们把相应的位置1,即可开启GPIOA的时钟
RCC->APB2ENR |= (0X1<<2); //开启GPIOA的时钟
设置引脚模式

设置PA11引脚模式 为通用推挽
CRH高位寄存器管理8~15号引脚
GPIOA->CRH &=~(0XF<<12);//CRL 0-4位清零
GPIOA->CRH |=(0X03<<12);//设置模式为通用推挽
输出电平
继电器高电平吸合,低电平松开
继电器不好观察效果,可以在主函数一关一开,能听见声音
//封装函数
//开继电器函数
void relay_on(GPIO_TypeDef * port,uint16_t pin)
{
port->ODR &=~ (pin);
}
//关继电器
void relay_off(GPIO_TypeDef * port,uint16_t pin)
{
port->ODR |= (pin);
}
头文件代码如下
#ifndef __RELAY_H
#define __RELAY_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
void relay_config(void);
void relay_off(GPIO_TypeDef * port,uint16_t pin);
void relay_on(GPIO_TypeDef * port,uint16_t pin);
#define relayport GPIOA
#define relaypin 0X1<<11
#endif
五、RGB函数
(一) 查引脚


从原理图可知控制RGB彩灯的引脚是GPIOA的PA6,PA7,PA8三个引脚
设置引脚模式
PA6,PA7属于CRL地位寄存器

PA8属于CRH高位寄存器

原理都相同
//PA6,PA7
GPIOA->CRL &=~(0XFF<<24);//CRL 0-4位清零
GPIOA->CRL |=(0X033<<24);//设置模式为通用推挽
//PA8
GPIOA->CRH &=~(0XF<<0);//CRL 0-4位清零
GPIOA->CRH |=(0X03<<0);//设置模式为通用推挽
输出电平
void rgb_on(GPIO_TypeDef * port,uint16_t pin)
{
port->ODR &=~ (pin); //低电平点亮
}
void rgb_off(GPIO_TypeDef * port,uint16_t pin)
{
port->ODR |= (pin); //高电平熄灭
}
头文件如下
#ifndef __RGB_H
#define __RGB_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
void rgb_config(void);
void rgb_off(GPIO_TypeDef * port,uint16_t pin);
void rgb_on(GPIO_TypeDef * port,uint16_t pin);
#define rgbport GPIOA
#define rgbpin 0X07<<6
#endif

1133

被折叠的 条评论
为什么被折叠?



