第九讲:模仿STM32驱动开发实验
?
前言:在02中我们学习的如何使用C语言的知识去编写代码,并且是直接定义寄存器地址的。你自己回想一下,stm32的库文件是这样的吗?当然不是,它是继续封装了地址,把寄存器封装为结构体使用,我们需要打开stm32库文件,关于寄存器地址定义的在#include "stm32f10x_it.h" 文件中
寄存器结构体封装-以GPIO寄存器为例
下面的5张图表示的就是寄存器封装的过程
?
?
?
?封装步骤:
? ? ? ? ? ? ? ? 1:把数据类型重定义一下,像stm32一样的
? ? ? ? ? ? ? ? 2:把所有的寄存器开始封装,根据结构体地址递增的特点,如果发现地址不连续,那么随便定义一个变量占就可以了,如果是多个就使用数组占
? ? ? ? ? ? ? ? 3:定义各个外设的基地址,如GPIO1的基地址
?????????????????
#define GPIO1_BASE (0x0209C000)
/*
* GPIO寄存器结构体
*/
typedef struct
{
volatile unsigned int DR;
volatile unsigned int GDIR;
volatile unsigned int PSR;
volatile unsigned int ICR1;
volatile unsigned int ICR2;
volatile unsigned int IMR;
volatile unsigned int ISR;
volatile unsigned int EDGE_SEL;
}GPIO_Type;
#define GPIO1 ((GPIO_Type *)GPIO1_BASE)
?.word表示的意思是占位的意思,类似于int也是占了2/4个字节的位置
?
?把起始和结束地址保存在寄存器中,这里涉及到了另外几个汇编-stmia、cmp、ble
这里的mov可以改成ldr吗?你可以尝试一下
/* 清BSS段 */
ldr r0, _bss_start
ldr r1, _bss_end
mov r2, #0
bss_loop:
stmia r0!, {r2} /* 向r0的地址写入0,然后r0寄存器保存的地址值加1 */
cmp r0, r1 /* 比较r0和r1,也就是__bss_start和__bss_end的值*/
ble bss_loop /* 如果小于等于的话就跳转到bss_loop继续清bss段*/
主要内容:移植的两个函数讲解
IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0);
IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0X10B0);
static inline void IOMUXC_SetPinMux(uint32_t muxRegister,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint32_t muxMode,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint32_t inputRegister,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint32_t inputDaisy,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint32_t configRegister,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint32_t inputOnfield)
static inline void IOMUXC_SetPinConfig(uint32_t muxRegister,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?uint32_t muxMode,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?uint32_t inputRegister,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?uint32_t inputDaisy,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?uint32_t configRegister,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?uint32_t configValue)
原型和使用你会发现我使用的只有两个形参,我们写错了吗?
#define IOMUXC_GPIO1_IO03_GPIO1_IO03 ? ? ? ? ? ? ? ? ? ? ? ? 0x020E0068U, 0x5U, 0x00000000U, 0x0U, 0x020E02F4U
Mux表示的是复用寄存器,config表示的是功能模式的(比如上下拉速度之类的)
其实是IOMUXC_GPIO1_IO03_GPIO1_IO03表示的是5个参数
?*((volatile uint32_t *)configRegister) = configValue;
配置输出和电平还是单独使用寄存器配置的
/* 3、初始化GPIO,设置GPIO1_IO03设置为输出 ?*/
? ? GPIO1->GDIR |= (1 << 3); ? ?
? ?
? ? /* 4、设置GPIO1_IO03输出低电平,打开LED0 */
? ? GPIO1->DR &= ~(1 << 3); ? ? ?
Makefile书写
这次的Makefile书写比上一次的又升级了?=的使用,其实我感觉有点多余了
CROSS_COMPILE ?= arm-linux-gnueabihf-
NAME ?= ledc
CC := $(CROSS_COMPILE)gcc
LD := $(CROSS_COMPILE)ld
OBJCOPY := $(CROSS_COMPILE)objcopy
OBJDUMP := $(CROSS_COMPILE)objdump
TEMP := -Wall -nostdlib -c -O2 -o
OBJS := start.o main.o
$(NAME).bin:$(OBJS)
$(LD) -Timx6ul.lds -o $(NAME).elf $^
$(OBJCOPY) -O binary -S $(NAME).elf $@
$(OBJDUMP) -D -m arm $(NAME).elf > $(NAME).dis
%.o:%.s
$(CC) $(TEMP) $@ $<
%.o:%.c
$(CC) $(TEMP) $@ $<
clean:
rm -rf *.o $(NAME).bin $(NAME).elf $(NAME).dis
?
目录
第九讲:模仿STM32驱动开发实验
寄存器结构体封装-以GPIO寄存器为例
?工程汇编文件书写
?C代码编写
Makefile编写
?第十讲NXP官方SDK使用
前言:
主要内容:移植的两个函数讲解
Makefile书写