zoukankan      html  css  js  c++  java
  • 6.裸机C语言控制LED

    C语言版LED灯

    汇编完成C语言的环境配置

    C语言完成点亮LED灯

    程序编写

    1. 汇编程序start.S
    
    .global _start  		/* 全局标号 */
    
    /*
     * 描述:	_start函数,程序从此函数开始执行,此函数主要功能是设置C
     *		 运行环境。
     */
    _start:
    
    	/* 进入SVC模式 */
    	mrs r0, cpsr
    	bic r0, r0, #0x1f 	/* 将r0寄存器中的低5位清零,也就是cpsr的M0~M4 	*/
    	orr r0, r0, #0x13 	/* r0或上0x13,表示使用SVC模式					*/
    	msr cpsr, r0		/* 将r0 的数据写入到cpsr_c中 					*/
    
    	ldr sp, =0X80200000	/* 设置栈指针			 */
    	b main				/* 跳转到main函数 		 */
    
    
    

    开发板上的DDR3地址范围是0X80000000~0XA0000000(512MB) ,其 DDR3 起始地址是 0X80000000。由于 Cortex-A7 的堆栈是向下增长的,所以将 SP 指针设置为 0X80200000,因此 SVC 模式的栈大小 0X80200000-0X80000000=0X200000=2MB,2MB 的栈空间已经很大了,如果做裸机开发的话绰绰有余。

    然后跳转至main函数

    1. C程序

    main.h代码,宏定义所有用到的寄存器地址

    #ifndef __MAIN_H
    #define __MAIN_H
    /* 
     * CCM相关寄存器地址 
     */
    #define CCM_CCGR0 			*((volatile unsigned int *)0X020C4068)
    #define CCM_CCGR1 			*((volatile unsigned int *)0X020C406C)
    
    #define CCM_CCGR2 			*((volatile unsigned int *)0X020C4070)
    #define CCM_CCGR3 			*((volatile unsigned int *)0X020C4074)
    #define CCM_CCGR4 			*((volatile unsigned int *)0X020C4078)
    #define CCM_CCGR5 			*((volatile unsigned int *)0X020C407C)
    #define CCM_CCGR6 			*((volatile unsigned int *)0X020C4080)
    
    /* 
     * IOMUX相关寄存器地址 
     */
    #define SW_MUX_GPIO1_IO03 	*((volatile unsigned int *)0X020E0068)
    #define SW_PAD_GPIO1_IO03 	*((volatile unsigned int *)0X020E02F4)
    
    /* 
     * GPIO1相关寄存器地址 
     */
    #define GPIO1_DR 			*((volatile unsigned int *)0X0209C000)
    #define GPIO1_GDIR 			*((volatile unsigned int *)0X0209C004)
    #define GPIO1_PSR 			*((volatile unsigned int *)0X0209C008)
    #define GPIO1_ICR1 			*((volatile unsigned int *)0X0209C00C)
    #define GPIO1_ICR2 			*((volatile unsigned int *)0X0209C010)
    #define GPIO1_IMR 			*((volatile unsigned int *)0X0209C014)
    #define GPIO1_ISR 			*((volatile unsigned int *)0X0209C018)
    #define GPIO1_EDGE_SEL 		*((volatile unsigned int *)0X0209C01C)
    
    #endif
    
    

    main.c代码

    
    #include "main.h"
    
    /*
     * @description	: 使能I.MX6U所有外设时钟
     * @param 		: 无
     * @return 		: 无
     */
    void clk_enable(void)
    {
    	CCM_CCGR0 = 0xffffffff;
    	CCM_CCGR1 = 0xffffffff;
    	CCM_CCGR2 = 0xffffffff;
    	CCM_CCGR3 = 0xffffffff;
    	CCM_CCGR4 = 0xffffffff;
    	CCM_CCGR5 = 0xffffffff;
    	CCM_CCGR6 = 0xffffffff;
    }
    
    /*
     * @description	: 初始化LED对应的GPIO
     * @param 		: 无
     * @return 		: 无
     */
    void led_init(void)
    {
    	/* 1、初始化IO复用 */
    	SW_MUX_GPIO1_IO03 = 0x5;	/* 复用为GPIO1_IO03 */
    
    	/* 2、、配置GPIO1_IO03的IO属性	
    	 *bit 16:0 HYS关闭
    	 *bit [15:14]: 00 默认下拉
         *bit [13]: 0 kepper功能
         *bit [12]: 1 pull/keeper使能
         *bit [11]: 0 关闭开路输出
         *bit [7:6]: 10 速度100Mhz
         *bit [5:3]: 110 R0/6驱动能力
         *bit [0]: 0 低转换率
         */
    	SW_PAD_GPIO1_IO03 = 0X10B0;		
    
    	/* 3、初始化GPIO */
    	GPIO1_GDIR = 0X0000008;	/* GPIO1_IO03设置为输出 */
    
    	/* 4、设置GPIO1_IO03输出低电平,打开LED0 */
    	GPIO1_DR = 0X0;
    }
    
    /*
     * @description	: 打开LED灯
     * @param 		: 无
     * @return 		: 无
     */
    void led_on(void)
    {
    	/* 
    	 * 将GPIO1_DR的bit3清零	 
    	 */
    	GPIO1_DR &= ~(1<<3); 
    }
    
    /*
     * @description	: 关闭LED灯
     * @param 		: 无
     * @return 		: 无
     */
    void led_off(void)
    {
    	/*    
    	 * 将GPIO1_DR的bit3置1
    	 */
    	GPIO1_DR |= (1<<3);
    }
    
    /*
     * @description	: 短时间延时函数
     * @param - n	: 要延时循环次数(空操作循环次数,模式延时)
     * @return 		: 无
     */
    void delay_short(volatile unsigned int n)
    {
    	while(n--){}
    }
    
    /*
     * @description	: 延时函数,在396Mhz的主频下
     * 			  	  延时时间大约为1ms
     * @param - n	: 要延时的ms数
     * @return 		: 无
     */
    void delay(volatile unsigned int n)
    {
    	while(n--)
    	{
    		delay_short(0x7ff);
    	}
    }
    
    /*
     * @description	: mian函数
     * @param 	    : 无
     * @return 		: 无
     */
    int main(void)
    {
    	clk_enable();		/* 使能所有的时钟		 	*/
    	led_init();			/* 初始化led 			*/
    
    	while(1)			/* 死循环 				*/
    	{	
    		led_off();		/* 关闭LED   			*/
    		delay(500);		/* 延时大约500ms 		*/
    
    		led_on();		/* 打开LED		 	*/
    		delay(500);		/* 延时大约500ms 		*/
    	}
    
    	return 0;
    }
    
    

    编译链接

    makefile:

    objs := start.o main.o
    
    ledc.bin:$(objs)
    	arm-linux-gnueabihf-ld -Timx6ul.lds -o ledc.elf $^
    	arm-linux-gnueabihf-objcopy -O binary -S ledc.elf $@
    	arm-linux-gnueabihf-objdump -D -m arm ledc.elf > ledc.dis
    	
    %.o:%.s
    	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<
    	
    %.o:%.S
    	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<
    	
    %.o:%.c
    	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<
    	
    clean:
    	rm -rf *.o ledc.bin ledc.elf ledc.dis
    	
    	
    
    

    这里的imx6ul.lds是自己配置的SECTION映射:

    SECTIONS{
    	. = 0X87800000;
    	.text :
    	{
    		start.o 
    		main.o 
    		*(.text)
    	}
    	.rodata ALIGN(4) : {*(.rodata*)}     
    	.data ALIGN(4)   : { *(.data) }    
    	__bss_start = .;    
    	.bss ALIGN(4)  : { *(.bss)  *(COMMON) }    
    	__bss_end = .;
    }
    

    make后烧写

    chmod 777 imxdownload //给予 imxdownload 可执行权限,一次即可
    ./imxdownload ledc.bin /dev/sdd //烧写到 SD 卡中
    
  • 相关阅读:
    mysql 历史版本下载
    mysql 5.7 版本 You must reset your password using ALTER USER statement before executing this statement报错处理
    5.7 zip 版本的安装 以及遇到的坑
    mysql 5.6zip版本的卸载与5.7 zip 版本的安装
    mysql数据库的备份与还原
    本地Navicat连接docker里的mysql
    docker修改数据库密码
    docker 在push镜像到本地registry出现的500 Internal Server Error
    linux 没有界面内容显示不全解决办法
    json与map互相转换
  • 原文地址:https://www.cnblogs.com/zhaipanger/p/12913619.html
Copyright © 2011-2022 走看看