C代码
led.h
#ifndef __LED_H__
#define __LED_H__
/*
LD1 - LED1 - PE10
LD2 - LED2 - PF10
LD3 - LED3 - PE8
KEY1 - KEY1 - PF9
KEY2 - KEY2 - PF7
KEY3 - KEY3 - PF8
蜂鸣器 - TIM4_CH1 - PB6
风扇 - TIM1_CH1 - PE9
震动马达 - TIM16_CH1 - PF6
*/
typedef struct
{
unsigned int MODER;
unsigned int OTYPER;
unsigned int OSPEEDR;
unsigned int PUPDR;
unsigned int IDR; // 必须要写
unsigned int ODR;
}gpio_t;
#define RCC_MP_AHB4ENSETR ((unsigned int *)0x50000A28)
#define GPIOE ((gpio_t *)0x50006000)
#define GPIOF ((gpio_t *)0x50007000)
#define GPIOB ((gpio_t *)0x50003000)
// LED1初始化函数
void LED1_Init(void);
// LED1点亮函数
void LED1_On(void);
// LED1熄灭函数
void LED1_Off(void);
// LED2初始化函数
void LED2_Init(void);
// LED2点亮函数
void LED2_On(void);
// LED2熄灭函数
void LED2_Off(void);
// LED3初始化函数
void LED3_Init(void);
// LED3点亮函数
void LED3_On(void);
// LED3熄灭函数
void LED3_Off(void);
// FAN_init
void FAN_Init(void);
//FAN_on
void FAN_On(void);
//FAN_off
void FAN_Off(void);
// BUZZER_init
void BUZZER_Init(void);
//BUZZER_on
void BUZZER_On(void);
//BUZZER_off
void BUZZER_Off(void);
// MOTOR初始化函数
void MOTOR_Init(void);
// MOTOR点亮函数
void MOTOR_On(void);
// MOTOR熄灭函数
void MOTOR_Off(void);
#endif
led.c
#include "../include/led.h"
#include "led.h"
extern void delay_ms(unsigned int ms);
//====================LED1====================
// LED1初始化函数
void LED1_Init(void)
{
// 1、使能GPIOE组外设控制器的时钟 - 向RCC_MP_AHB4ENSETR[4]写入0b1
*RCC_MP_AHB4ENSETR |= (0x1 << 4);
// 2、将PE10引脚配置为输出模式 - 向GPIOE_MODER[21:20]写入0b01
GPIOE->MODER &= (~(0x3 << 20));
GPIOE->MODER |= (0x1 << 20);
// 3、将PE10引脚配置为推挽输出模式 - 向GPIOE_OTYPER[10]写入0b0
GPIOE->OTYPER &= (~(0x1 << 10));
// 4、将PE10引脚配置为低速输出模式 - 向GPIOE_OSPEEDR[21:20]写入0b00
GPIOE->OSPEEDR &= (~(0x3 << 20));
// 5、将PE10引脚配置为不外接上/下拉电阻 - 向GPIOE_PUPDR[21:20]写入0b00
GPIOE->PUPDR &= (~(0x3 << 20));
}
// LED1点亮函数
void LED1_On(void)
{
// 向PE10引脚输出高电平信号 - 向GPIOE_ODR[10]写入0b1
GPIOE->ODR |= (0x1 << 10);
}
// LED1熄灭函数
void LED1_Off(void)
{
// 向PE10引脚输出低电平信号 - 向GPIOE_ODR[10]写入0b0
GPIOE->ODR &= (~(0x1 << 10));
}
//==========================LED2========================
// LED2初始化函数
void LED2_Init(void){
// 1、使能GPIOF组外设控制器的时钟 - 向RCC_MP_AHB4ENSETR[4]写入0b1
*RCC_MP_AHB4ENSETR |= (0x1 << 5);
// 2、将PF10引脚配置为输出模式 - 向GPIOF_MODER[21:20]写入0b01
GPIOF->MODER &= (~(0x3 << 20));
GPIOF->MODER |= (0x1 << 20);
// 3、将PF10引脚配置为推挽输出模式 - 向GPIOF_OTYPER[10]写入0b0
GPIOF->OTYPER &= (~(0x1 << 10));
// 4、将PF10引脚配置为低速输出模式 - 向GPIOF_OSPEEDR[21:20]写入0b00
GPIOF->OSPEEDR &= (~(0x3 << 20));
// 5、将PF10引脚配置为不外接上/下拉电阻 - 向GPIOF_PUPDR[21:20]写入0b00
GPIOF->PUPDR &= (~(0x3 << 20));
}
// LED2点亮函数
void LED2_On(void)
{
// 向PF10引脚输出高电平信号 - 向GPIOF_ODR[10]写入0b1
GPIOF->ODR |= (0x1 << 10);
}
// LED2熄灭函数
void LED2_Off(void)
{
// 向PF10引脚输出低电平信号 - 向GPIOF_ODR[10]写入0b0
GPIOF->ODR &= (~(0x1 << 10));
}
//===========================LED3=============================
// LED3初始化函数
void LED3_Init(void)
{
// 1、使能GPIOE组外设控制器的时钟 - 向RCC_MP_AHB4ENSETR[4]写入0b1
*RCC_MP_AHB4ENSETR |= (0x1 << 4);
// 2、将PE8引脚配置为输出模式 - 向GPIOE_MODER[17:16]写入0b01
GPIOE->MODER &= (~(0x3 << 16));
GPIOE->MODER |= (0x1 << 16);
// 3、将PE8引脚配置为推挽输出模式 - 向GPIOE_OTYPER[8]写入0b0
GPIOE->OTYPER &= (~(0x1 << 8));
// 4、将PE8引脚配置为低速输出模式 - 向GPIOE_OSPEEDR[17:16]写入0b00
GPIOE->OSPEEDR &= (~(0x3 << 16));
// 5、将PE8引脚配置为不外接上/下拉电阻 - 向GPIOE_PUPDR[17:16]写入0b00
GPIOE->PUPDR &= (~(0x3 << 16));
}
// LED3点亮函数
void LED3_On(void)
{
// 向PE8引脚输出高电平信号 - 向GPIOE_ODR[8]写入0b1
GPIOE->ODR |= (0x1 << 8);
}
// LED3熄灭函数
void LED3_Off(void)
{
// 向PE8引脚输出低电平信号 - 向GPIOE_ODR[8]写入0b0
GPIOE->ODR &= (~(0x1 << 8));
}
void FAN_Init(void)
{
// 1、使能GPIOE组外设控制器的时钟 - 向RCC_MP_AHB4ENSETR[4]写入0b1
*RCC_MP_AHB4ENSETR |= (0x1 << 4);
// 2、引脚配置为输出模式 - 写入0b01
GPIOE->MODER &= (~(0x3 << 18));
GPIOE->MODER |= (0x1 << 18);
// 3、引脚配置为推挽输出模式 - 写入0b0
GPIOE->OTYPER &= (~(0x1 << 9));
// 4、引脚配置为低速输出模式 -写入0b00
GPIOE->OSPEEDR &= (~(0x3 << 18));
// 5、引脚配置为不外接上/下拉电阻 - 写入0b00
GPIOE->PUPDR &= (~(0x3 << 18));
}
void FAN_On(void)
{
// 引脚输出高电平信号 - 写入0b1
GPIOE->ODR |= (0x1 << 9);
}
void FAN_Off(void)
{
// 引脚输出低电平信号 - 写入0b0
GPIOE->ODR &= (~(0x1 << 9));
}
void BUZZER_Init(void)
{
// 1、使能GPIOB组外设控制器的时钟 - 向RCC_MP_AHB4ENSETR[1]写入0b1
*RCC_MP_AHB4ENSETR |= (0x1 << 1);
// 2、引脚配置为输出模式 - 写入0b01
GPIOB->MODER &= (~(0x3 << 12));
GPIOB->MODER |= (0x1 << 12);
// 3、引脚配置为推挽输出模式 - 写入0b0
GPIOB->OTYPER &= (~(0x1 << 6));
// 4、引脚配置为低速输出模式 -写入0b00
GPIOB->OSPEEDR &= (~(0x3 << 12));
// 5、引脚配置为不外接上/下拉电阻 - 写入0b00
GPIOB->PUPDR &= (~(0x3 << 12));
}
void BUZZER_On(void)
{
// 引脚输出高电平信号 - 写入0b1
GPIOB->ODR |= (0x1 << 6);
}
void BUZZER_Off(void)
{
// 引脚输出低电平信号 - 写入0b0
GPIOB->ODR &= (~(0x1 << 6));
}
void MOTOR_Init(void)
{
// 1、使能GPIOE组外设控制器的时钟 - 向RCC_MP_AHB4ENSETR[4]写入0b1
*RCC_MP_AHB4ENSETR |= (0x1 << 5);
// 2、引脚配置为输出模式 - 写入0b01
GPIOF->MODER &= (~(0x3 << 12));
GPIOF->MODER |= (0x1 << 12);
// 3、引脚配置为推挽输出模式 - 写入0b0
GPIOF->OTYPER &= (~(0x1 << 6));
// 4、引脚配置为低速输出模式 -写入0b00
GPIOF->OSPEEDR &= (~(0x3 << 12));
// 5、引脚配置为不外接上/下拉电阻 - 写入0b00
GPIOF->PUPDR &= (~(0x3 << 12));
}
void MOTOR_On(void)
{
// 引脚输出高电平信号 - 写入0b1
GPIOF->ODR |= (0x1 << 6);
}
void MOTOR_Off(void)
{
// 引脚输出低电平信号 - 写入0b0
GPIOF->ODR &= (~(0x1 << 6));
}
main.c
#include "include/led.h"
extern void printf(const char *fmt, ...);
void delay_ms(unsigned int ms)
{
int i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 1800; j++)
;
}
int main()
{
// LED1初始化
// LED1_Init();
// LED2_Init();
// LED3_Init();
// FAN_Init();
// BUZZER_Init();
MOTOR_Init();
while (1)
{
// LED1闪烁效果
// LED1_On();
// delay_ms(1000); // 延时函数,单位为ms
// LED1_Off();
// delay_ms(1000); // 延时函数,单位为ms
// LED2_On();
// delay_ms(1000);
// LED2_Off();
// delay_ms(1000);
// LED3_On();
// delay_ms(1000);
// LED3_Off();
// delay_ms(1000);
// FAN_On();
// BUZZER_On();
// delay_ms(1000);
// BUZZER_Off();
// delay_ms(1000);
MOTOR_On();
delay_ms(1000);
MOTOR_Off();
delay_ms(1000);
}
return 0;
}
汇编代码
start.s
/*
LED1灯接到PE10引脚,对应的总线为AHB4
操作对应的寄存器,只修改对应的位,其他位保持不变
LED2 LED3 灯 自己分析电路图\芯片手册\代码实现
*/
.text
.global _start
_start:
/*********************初始化操作*************************/
@ 1、使能GPIOE组外设控制器的时钟 - 向RCC_MP_AHB4ENSETR[4]写入0b1
ldr r0, =0x50000a28 @ 准备一片0x50000a28地址
ldr r1, [r0] @ r1寄存器中保存了0x50000a28这片地址中的值
orr r1, r1, #(0x1 << 4) @ 将r0寄存器中的值第4位置1
str r1, [r0] @ 将r1寄存器中的写回到0x50000a28
@ 2、将PE10引脚配置为输出模式 - 向GPIOE_MODER[21:20]写入0b01
ldr r0, =0x50006000
ldr r1, [r0]
and r1, r1, #(~(0x3 << 20))
orr r1, r1, #(0x1 << 20)
str r1, [r0]
@ 3、将PE10引脚配置为推挽输出模式 - 向GPIOE_OTYPER[10]写入0b0
ldr r0, =0x50006004
ldr r1, [r0]
and r1, r1, #(~(0x1 << 10))
str r1, [r0]
@ 4、将PE10引脚配置为低速输出模式 - 向GPIOE_OSPEEDR[21:20]写入0b00
ldr r0, =0x50006008
ldr r1, [r0]
and r1, r1, #(~(0x3 << 20))
str r1, [r0]
@ 5、将PE10引脚配置为不外接上/下拉电阻 - 向GPIOE_PUPDR[21:20]写入0b00
ldr r0, =0x5000600c
ldr r1, [r0]
and r1, r1, #(~(0x3 << 20))
str r1, [r0]
/*********************while(1)中执行逻辑*************************/
func:
@ 向PE10引脚输出高电平信号 - 向GPIOE_ODR[10]写入0b1
ldr r0, =0x50006014
ldr r1, [r0]
orr r1, r1, #(0x1 << 10)
str r1, [r0]
bl delay_1s
@ 向PE10引脚输出低电平信号 - 向GPIOE_ODR[10]写入0b0
ldr r0, =0x50006014
ldr r1, [r0]
and r1, r1, #(~(0x1 << 10))
str r1, [r0]
bl delay_1s
b func
/*********************LED2初始化操作*************************/
@ 1、使能GPIOE组外设控制器的时钟 - 向RCC_MP_AHB4ENSETR[4]写入0b1
ldr r0, =0x50000a28 @ 准备一片0x50000a28地址
ldr r1, [r0] @ r1寄存器中保存了0x50000a28这片地址中的值
orr r1, r1, #(0x1 << 5) @ 将r0寄存器中的值第4位置1
str r1, [r0] @ 将r1寄存器中的写回到0x50000a28
@ 2、将PE10引脚配置为输出模式 - 向GPIOE_MODER[21:20]写入0b01
ldr r0, =0x50007000
ldr r1, [r0]
and r1, r1, #(~(0x3 << 20))
orr r1, r1, #(0x1 << 20)
str r1, [r0]
@ 3、将PE10引脚配置为推挽输出模式 - 向GPIOE_OTYPER[10]写入0b0
ldr r0, =0x50007004
ldr r1, [r0]
and r1, r1, #(~(0x1 << 10))
str r1, [r0]
@ 4、将PE10引脚配置为低速输出模式 - 向GPIOE_OSPEEDR[21:20]写入0b00
ldr r0, =0x50007008
ldr r1, [r0]
and r1, r1, #(~(0x3 << 20))
str r1, [r0]
@ 5、将PE10引脚配置为不外接上/下拉电阻 - 向GPIOE_PUPDR[21:20]写入0b00
ldr r0, =0x5000700c
ldr r1, [r0]
and r1, r1, #(~(0x3 << 20))
str r1, [r0]
/*********************while(1)中执行逻辑*************************/
func:
@ 向PE10引脚输出高电平信号 - 向GPIOE_ODR[10]写入0b1
ldr r0, =0x50007014
ldr r1, [r0]
orr r1, r1, #(0x1 << 10)
str r1, [r0]
bl delay_1s
@ 向PE10引脚输出低电平信号 - 向GPIOE_ODR[10]写入0b0
ldr r0, =0x50007014
ldr r1, [r0]
and r1, r1, #(~(0x1 << 10))
str r1, [r0]
bl delay_1s
b func
/*********************LED3初始化操作*************************/
@ 1、使能GPIOE组外设控制器的时钟 - 向RCC_MP_AHB4ENSETR[4]写入0b1
ldr r0, =0x50000a28 @ 准备一片0x50000a28地址
ldr r1, [r0] @ r1寄存器中保存了0x50000a28这片地址中的值
orr r1, r1, #(0x1 << 4) @ 将r0寄存器中的值第4位置1
str r1, [r0] @ 将r1寄存器中的写回到0x50000a28
@ 2、将PE10引脚配置为输出模式 - 向GPIOE_MODER[21:20]写入0b01
ldr r0, =0x50006000
ldr r1, [r0]
and r1, r1, #(~(0x3 << 16))
orr r1, r1, #(0x1 << 16)
str r1, [r0]
@ 3、将PE10引脚配置为推挽输出模式 - 向GPIOE_OTYPER[10]写入0b0
ldr r0, =0x50006004
ldr r1, [r0]
and r1, r1, #(~(0x1 << 8))
str r1, [r0]
@ 4、将PE10引脚配置为低速输出模式 - 向GPIOE_OSPEEDR[21:20]写入0b00
ldr r0, =0x50006008
ldr r1, [r0]
and r1, r1, #(~(0x3 << 16))
str r1, [r0]
@ 5、将PE10引脚配置为不外接上/下拉电阻 - 向GPIOE_PUPDR[21:20]写入0b00
ldr r0, =0x5000600c
ldr r1, [r0]
and r1, r1, #(~(0x3 << 16))
str r1, [r0]
/*********************while(1)中执行逻辑*************************/
func:
@ 向PE10引脚输出高电平信号 - 向GPIOE_ODR[10]写入0b1
ldr r0, =0x50006014
ldr r1, [r0]
orr r1, r1, #(0x1 << 8)
str r1, [r0]
bl delay_1s
@ 向PE10引脚输出低电平信号 - 向GPIOE_ODR[10]写入0b0
ldr r0, =0x50006014
ldr r1, [r0]
and r1, r1, #(~(0x1 << 8))
str r1, [r0]
bl delay_1s
b func
stop:
b stop
@ 大概 1s的延时函数
delay_1s:
mov r3, #0x10000000
mm:
cmp r3, #0
subne r3, r3, #1
bne mm
mov pc, lr
.end