7.4 arm作业
C代码
led.h
#ifndef __LED_H__
#define __LED_H__
/*LD1 - LED1 - PE10LD2 - LED2 - PF10LD3 - LED3 - PE8KEY1 - KEY1 - PF9KEY2 - KEY2 - PF7KEY3 - 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]写入0b01GPIOE->MODER &= (~(0x3 << 20));GPIOE->MODER |= (0x1 << 20);// 3、将PE10引脚配置为推挽输出模式 - 向GPIOE_OTYPER[10]写入0b0GPIOE->OTYPER &= (~(0x1 << 10));// 4、将PE10引脚配置为低速输出模式 - 向GPIOE_OSPEEDR[21:20]写入0b00GPIOE->OSPEEDR &= (~(0x3 << 20));// 5、将PE10引脚配置为不外接上/下拉电阻 - 向GPIOE_PUPDR[21:20]写入0b00GPIOE->PUPDR &= (~(0x3 << 20));
}// LED1点亮函数
void LED1_On(void)
{// 向PE10引脚输出高电平信号 - 向GPIOE_ODR[10]写入0b1GPIOE->ODR |= (0x1 << 10);}// LED1熄灭函数
void LED1_Off(void)
{// 向PE10引脚输出低电平信号 - 向GPIOE_ODR[10]写入0b0GPIOE->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]写入0b01GPIOF->MODER &= (~(0x3 << 20));GPIOF->MODER |= (0x1 << 20);// 3、将PF10引脚配置为推挽输出模式 - 向GPIOF_OTYPER[10]写入0b0GPIOF->OTYPER &= (~(0x1 << 10));// 4、将PF10引脚配置为低速输出模式 - 向GPIOF_OSPEEDR[21:20]写入0b00GPIOF->OSPEEDR &= (~(0x3 << 20));// 5、将PF10引脚配置为不外接上/下拉电阻 - 向GPIOF_PUPDR[21:20]写入0b00GPIOF->PUPDR &= (~(0x3 << 20));
}// LED2点亮函数
void LED2_On(void)
{// 向PF10引脚输出高电平信号 - 向GPIOF_ODR[10]写入0b1GPIOF->ODR |= (0x1 << 10);}// LED2熄灭函数
void LED2_Off(void)
{// 向PF10引脚输出低电平信号 - 向GPIOF_ODR[10]写入0b0GPIOF->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]写入0b01GPIOE->MODER &= (~(0x3 << 16));GPIOE->MODER |= (0x1 << 16);// 3、将PE8引脚配置为推挽输出模式 - 向GPIOE_OTYPER[8]写入0b0GPIOE->OTYPER &= (~(0x1 << 8));// 4、将PE8引脚配置为低速输出模式 - 向GPIOE_OSPEEDR[17:16]写入0b00GPIOE->OSPEEDR &= (~(0x3 << 16));// 5、将PE8引脚配置为不外接上/下拉电阻 - 向GPIOE_PUPDR[17:16]写入0b00GPIOE->PUPDR &= (~(0x3 << 16));
}// LED3点亮函数
void LED3_On(void)
{// 向PE8引脚输出高电平信号 - 向GPIOE_ODR[8]写入0b1GPIOE->ODR |= (0x1 << 8);}// LED3熄灭函数
void LED3_Off(void)
{// 向PE8引脚输出低电平信号 - 向GPIOE_ODR[8]写入0b0GPIOE->ODR &= (~(0x1 << 8));
}void FAN_Init(void)
{// 1、使能GPIOE组外设控制器的时钟 - 向RCC_MP_AHB4ENSETR[4]写入0b1*RCC_MP_AHB4ENSETR |= (0x1 << 4);// 2、引脚配置为输出模式 - 写入0b01GPIOE->MODER &= (~(0x3 << 18));GPIOE->MODER |= (0x1 << 18);// 3、引脚配置为推挽输出模式 - 写入0b0GPIOE->OTYPER &= (~(0x1 << 9));// 4、引脚配置为低速输出模式 -写入0b00GPIOE->OSPEEDR &= (~(0x3 << 18));// 5、引脚配置为不外接上/下拉电阻 - 写入0b00GPIOE->PUPDR &= (~(0x3 << 18));
}void FAN_On(void)
{// 引脚输出高电平信号 - 写入0b1GPIOE->ODR |= (0x1 << 9);
}void FAN_Off(void)
{// 引脚输出低电平信号 - 写入0b0GPIOE->ODR &= (~(0x1 << 9));
}void BUZZER_Init(void)
{// 1、使能GPIOB组外设控制器的时钟 - 向RCC_MP_AHB4ENSETR[1]写入0b1*RCC_MP_AHB4ENSETR |= (0x1 << 1);// 2、引脚配置为输出模式 - 写入0b01GPIOB->MODER &= (~(0x3 << 12));GPIOB->MODER |= (0x1 << 12);// 3、引脚配置为推挽输出模式 - 写入0b0GPIOB->OTYPER &= (~(0x1 << 6));// 4、引脚配置为低速输出模式 -写入0b00GPIOB->OSPEEDR &= (~(0x3 << 12));// 5、引脚配置为不外接上/下拉电阻 - 写入0b00GPIOB->PUPDR &= (~(0x3 << 12));
}void BUZZER_On(void)
{// 引脚输出高电平信号 - 写入0b1GPIOB->ODR |= (0x1 << 6);
}void BUZZER_Off(void)
{// 引脚输出低电平信号 - 写入0b0GPIOB->ODR &= (~(0x1 << 6));
}void MOTOR_Init(void)
{// 1、使能GPIOE组外设控制器的时钟 - 向RCC_MP_AHB4ENSETR[4]写入0b1*RCC_MP_AHB4ENSETR |= (0x1 << 5);// 2、引脚配置为输出模式 - 写入0b01GPIOF->MODER &= (~(0x3 << 12));GPIOF->MODER |= (0x1 << 12);// 3、引脚配置为推挽输出模式 - 写入0b0GPIOF->OTYPER &= (~(0x1 << 6));// 4、引脚配置为低速输出模式 -写入0b00GPIOF->OSPEEDR &= (~(0x3 << 12));// 5、引脚配置为不外接上/下拉电阻 - 写入0b00GPIOF->PUPDR &= (~(0x3 << 12));
}void MOTOR_On(void)
{// 引脚输出高电平信号 - 写入0b1GPIOF->ODR |= (0x1 << 6);
}void MOTOR_Off(void)
{// 引脚输出低电平信号 - 写入0b0GPIOF->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]写入0b1ldr r0, =0x50000a28 @ 准备一片0x50000a28地址ldr r1, [r0] @ r1寄存器中保存了0x50000a28这片地址中的值orr r1, r1, #(0x1 << 4) @ 将r0寄存器中的值第4位置1str r1, [r0] @ 将r1寄存器中的写回到0x50000a28@ 2、将PE10引脚配置为输出模式 - 向GPIOE_MODER[21:20]写入0b01ldr r0, =0x50006000ldr r1, [r0]and r1, r1, #(~(0x3 << 20))orr r1, r1, #(0x1 << 20)str r1, [r0]@ 3、将PE10引脚配置为推挽输出模式 - 向GPIOE_OTYPER[10]写入0b0ldr r0, =0x50006004ldr r1, [r0]and r1, r1, #(~(0x1 << 10))str r1, [r0]@ 4、将PE10引脚配置为低速输出模式 - 向GPIOE_OSPEEDR[21:20]写入0b00ldr r0, =0x50006008ldr r1, [r0]and r1, r1, #(~(0x3 << 20))str r1, [r0]@ 5、将PE10引脚配置为不外接上/下拉电阻 - 向GPIOE_PUPDR[21:20]写入0b00ldr r0, =0x5000600cldr r1, [r0]and r1, r1, #(~(0x3 << 20))str r1, [r0]/*********************while(1)中执行逻辑*************************/func:@ 向PE10引脚输出高电平信号 - 向GPIOE_ODR[10]写入0b1ldr r0, =0x50006014ldr r1, [r0]orr r1, r1, #(0x1 << 10)str r1, [r0]bl delay_1s@ 向PE10引脚输出低电平信号 - 向GPIOE_ODR[10]写入0b0ldr r0, =0x50006014ldr r1, [r0]and r1, r1, #(~(0x1 << 10))str r1, [r0]bl delay_1sb func/*********************LED2初始化操作*************************/@ 1、使能GPIOE组外设控制器的时钟 - 向RCC_MP_AHB4ENSETR[4]写入0b1ldr r0, =0x50000a28 @ 准备一片0x50000a28地址ldr r1, [r0] @ r1寄存器中保存了0x50000a28这片地址中的值orr r1, r1, #(0x1 << 5) @ 将r0寄存器中的值第4位置1str r1, [r0] @ 将r1寄存器中的写回到0x50000a28@ 2、将PE10引脚配置为输出模式 - 向GPIOE_MODER[21:20]写入0b01ldr r0, =0x50007000ldr r1, [r0]and r1, r1, #(~(0x3 << 20))orr r1, r1, #(0x1 << 20)str r1, [r0]@ 3、将PE10引脚配置为推挽输出模式 - 向GPIOE_OTYPER[10]写入0b0ldr r0, =0x50007004ldr r1, [r0]and r1, r1, #(~(0x1 << 10))str r1, [r0]@ 4、将PE10引脚配置为低速输出模式 - 向GPIOE_OSPEEDR[21:20]写入0b00ldr r0, =0x50007008ldr r1, [r0]and r1, r1, #(~(0x3 << 20))str r1, [r0]@ 5、将PE10引脚配置为不外接上/下拉电阻 - 向GPIOE_PUPDR[21:20]写入0b00ldr r0, =0x5000700cldr r1, [r0]and r1, r1, #(~(0x3 << 20))str r1, [r0]/*********************while(1)中执行逻辑*************************/func:@ 向PE10引脚输出高电平信号 - 向GPIOE_ODR[10]写入0b1ldr r0, =0x50007014ldr r1, [r0]orr r1, r1, #(0x1 << 10)str r1, [r0]bl delay_1s@ 向PE10引脚输出低电平信号 - 向GPIOE_ODR[10]写入0b0ldr r0, =0x50007014ldr r1, [r0]and r1, r1, #(~(0x1 << 10))str r1, [r0]bl delay_1sb func/*********************LED3初始化操作*************************/@ 1、使能GPIOE组外设控制器的时钟 - 向RCC_MP_AHB4ENSETR[4]写入0b1ldr r0, =0x50000a28 @ 准备一片0x50000a28地址ldr r1, [r0] @ r1寄存器中保存了0x50000a28这片地址中的值orr r1, r1, #(0x1 << 4) @ 将r0寄存器中的值第4位置1str r1, [r0] @ 将r1寄存器中的写回到0x50000a28@ 2、将PE10引脚配置为输出模式 - 向GPIOE_MODER[21:20]写入0b01ldr r0, =0x50006000ldr r1, [r0]and r1, r1, #(~(0x3 << 16))orr r1, r1, #(0x1 << 16)str r1, [r0]@ 3、将PE10引脚配置为推挽输出模式 - 向GPIOE_OTYPER[10]写入0b0ldr r0, =0x50006004ldr r1, [r0]and r1, r1, #(~(0x1 << 8))str r1, [r0]@ 4、将PE10引脚配置为低速输出模式 - 向GPIOE_OSPEEDR[21:20]写入0b00ldr r0, =0x50006008ldr r1, [r0]and r1, r1, #(~(0x3 << 16))str r1, [r0]@ 5、将PE10引脚配置为不外接上/下拉电阻 - 向GPIOE_PUPDR[21:20]写入0b00ldr r0, =0x5000600cldr r1, [r0]and r1, r1, #(~(0x3 << 16))str r1, [r0]/*********************while(1)中执行逻辑*************************/func:@ 向PE10引脚输出高电平信号 - 向GPIOE_ODR[10]写入0b1ldr r0, =0x50006014ldr r1, [r0]orr r1, r1, #(0x1 << 8)str r1, [r0]bl delay_1s@ 向PE10引脚输出低电平信号 - 向GPIOE_ODR[10]写入0b0ldr r0, =0x50006014ldr r1, [r0]and r1, r1, #(~(0x1 << 8))str r1, [r0]bl delay_1sb funcstop:b stop@ 大概 1s的延时函数
delay_1s:mov r3, #0x10000000mm:cmp r3, #0subne r3, r3, #1bne mmmov pc, lr.end