1.volatile关键字
2.定义寄存器地址
#include<reg51.h>
#define P2 *((volatile unsigned char*)0x80)
#define CCM_CCGR0 *((unsigned int *)0x020C4068)
#define CCM_CCGR1 *((unsigned int *)0x020C406C)
#define CCM_CCGR2 *((unsigned int *)0x020C4070)
#define CCM_CCGR3 *((unsigned int *)0x020C4074)
#define CCM_CCGR4 *((unsigned int *)0x020C4078)
#define CCM_CCGR5 *((unsigned int *)0x020C407C)
#define CCM_CCGR6 *((unsigned int *)0x020C4080)
#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 *((unsigned int *)0x020E0068)
#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 *((unsigned int *)0x020E02F4)
#define GPIO1_DR *((unsigned int *)0x0209C000)
#define GPIO1_GDIR *((unsigned int *)0x0209C004)
3.代码编写
void clock_init(void)
{
CCM_CCGR0 = 0xFFFFFFFF;
CCM_CCGR1 = 0xFFFFFFFF;
CCM_CCGR2 = 0xFFFFFFFF;
CCM_CCGR3 = 0xFFFFFFFF;
CCM_CCGR4 = 0xFFFFFFFF;
CCM_CCGR5 = 0xFFFFFFFF;
CCM_CCGR6 = 0xFFFFFFFF;
}
void led_init(void)
{
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 = 0x05;
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 = 0x10B0;
GPIO1_GDIR |= (1 << 3);
}
void led_on(void)
{
GPIO1_DR &= ~(1 << 3);
}
void led_off(void)
{
GPIO1_DR |= (1 << 3);
}
void led_delay(unsigned int time)
{
while (time--);
}
4.优化Makefile
COMPLITER = arm-linux-gnueabihf-
CC = $(COMPLITER)gcc
LD = $(COMPLITER)ld
OBJCOPY = $(COMPLITER)objcopy
OBJDUMP = $(COMPLITER)objdump
OBJS = start.o main.o
TARGET = led
%.o : %.S
(CC) -c ^ -o $@ -g
%.o : %.c
(CC) -c ^ -o $@ -g
(TARGET).bin : (OBJS)
(LD) -Ttext 0x87800000 ^ -o $(TARGET).elf
(OBJCOPY) -O binary -S -g (TARGET).elf $@
(OBJDUMP) -D (TARGET).elf > $(TARGET).dis
clean:
rm (OBJS) (TARGET).elf (TARGET).bin (TARGET).dis -f
load:
./imxdownload $(TARGET).bin /dev/sdb
5.优化寄存器访问方式
struct GPIO_t
{
unsigned int DR;
unsigned int DGIR;
unsigned int PSR;
unsigned int ICR1;
unsigned int ICR2;
unsigned int IMR;
unsigned int ISR;
unsigned int EDGE_SEL;
};
#define GPIO1 (*((struct GPIO_t *)0x0209C000))
1.SDK文件存放位置
路径:IMAX6ULL/SDK/
(1).SDK(Software development tools)移植
(2).完整开发工具就是一个IDE, 集代码编写、编译、下载于一体的集成开发环境, 类似于keil这种工具,要是用这个需要额外购买一些设备如下载器、编程器、仿真器
(3).所以只用它的头文件。
2.构建新工程
1.新建文件夹led_sdk
2.拷贝led_c内的start.S main.c Makefile到新工程
3.拷贝SDK目录下的所有头文件到新工程
4.介绍头文件
GPIO_Type
3.利用SDK编写点灯程序
void clock_init(void)
{
CCM->CCGR0 = 0xFFFFFFFF;
CCM->CCGR1 = 0xFFFFFFFF;
CCM->CCGR2 = 0xFFFFFFFF;
CCM->CCGR3 = 0xFFFFFFFF;
CCM->CCGR4 = 0xFFFFFFFF;
CCM->CCGR5 = 0xFFFFFFFF;
CCM->CCGR6 = 0xFFFFFFFF;
}
void led_init(void)
{
IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0);
IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0x10B0);
GPIO1->GDIR |= (1 << 3);
}
void led_on(void)
{
GPIO1->DR &= ~(1 << 3);
}
void led_off(void)
{
GPIO1->DR |= (1 << 3);
}
void led_flicker(void)
{
GPIO1->DR ^= (1 << 3);
}
4.将LED单独提取到LED模块
5.编写BEEP蜂鸣器裸机驱动
S8550 PNP型三极管(开关),基极高电平导通
6.BSP(板级支持包)工程管理
1.project :存放必要程序
main.c start.S
2.imx6ull :存放NXP提供的i.mx6ull头文件
cc.h core_ca7.h fsl_common.h fsl_iomuxc.h MCIMX6Y2.h
3.bsp :存放硬件外设相关功能模块
led.c led.h beep.c beep.h
4.Makefile: 需要遍目录
7.链接脚本
1.链接脚本: imx6ull.lds
2.链接主要在链接阶段,为连接器提供蓝图;
3.启动代码需要在进入C语言第一条指令前,将.bss .COMMON段初始化清0
SECTIONS
{
. = 0x87800000;
.text :
{
obj/start.o
*(.text)
}
.rodata ALIGN(4) : {*(.rodata*)}
.data ALIGN(4) : {*(.data)}
__bss_start = .;
.bss ALIGN(4) : {*(.bss) *(.COMMON)}
__bss_end = .;
}
蜂鸣器
main.c====================================================================
//蜂鸣器复用寄存器
#define IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER1 (*((volatile unsigned int *)0x0229000Cu))
//蜂鸣器电气寄存器
#define IOMUXC_SNVS_SW_PAD_CTL_PAD_SNVS_TAMPER1 (*((volatile unsigned int *)0x02290050u))
//蜂鸣器方向寄存器
#define GPIO5_GDIR (*((volatile unsigned int *)0x020AC004))
//蜂鸣器输出寄存器
#define GPIO5_DR (*((volatile unsigned int *)0x020AC000))
void beep_init(void)
{
//初始化复用 101 GPIO5_IO01
IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER1 = 0x5;
//初始化电气
IOMUXC_SNVS_SW_PAD_CTL_PAD_SNVS_TAMPER1 = 0x10B0;
//初始化方向
GPIO5_GDIR |= (1 << 1);
return;
}
void beep_on(void)
{
GPIO5_DR &= ~(1 << 1);
}
void beep_delay(unsigned int t)
{
while(t--);
}
void beep_off(void)
{
GPIO5_DR |= (1 << 1);
}
void main(void)
{
beep_init();
while(1)
{
beep_on();
beep_delay(0x3FFFF);
beep_off();
beep_delay(0x3FFFF);
}
}
=========================================================================
.s======================================================================
.global _start
_start:
ldr pc, =_reset_handler
ldr pc, =_undef_handler
ldr pc, =_software_handler
ldr pc, =_prefect_handler
ldr pc, =_data_handler
nop
ldr pc, =_irq_handler
ldr pc, =_fiq_handler
_undef_handler:
b _undef_handler
_software_handler:
b _software_handler
_prefect_handler:
b _prefect_handler
_data_handler:
b _data_handler
_irq_handler:
b _irq_handler
_fiq_handler:
b _fiq_handler
_reset_handler:
cpsid i //关掉IRQ的中断开关
cpsid f //关掉FIQ的中断开关
cps #0x12 //切换到10010
ldr sp, =0x82000000 //定义栈顶指针
cps #0x1F //切换到11111
ldr sp, =0x84000000 //定义栈顶指针
cpsie i
b main
finish:
b finish
=========================================================================