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 卡中

6.裸机C语言控制LED的更多相关文章

  1. Cubieboard2裸机开发之(三)C语言操作LED

    前言 前面通过汇编语言点亮LED,代码虽然简单,但并不是很直观.这次使用熟悉的C语言来控制LED,但是需要注意的地方有两点,第一,要想使用C语言,首先需要在调用C语言代码之前设置好堆栈:第二,调用C语 ...

  2. STM32 用c语言控制4个LED灯从左向右无限流动

    在用c语言写LED流水灯的前提条件是配置好其他环境,这里我就不说环境了, 想让LED灯无限循环时,首先要想到的是无限循环函数,我这里利用的是for函数 无限循环. #include "stm ...

  3. 嵌入式Linux学习入门:控制LED灯

    记录自己linux学习过程,让自己能够一直坚持下去 1.原理图分析: nLED_1, nLED_2, nLED_4, 给低电平则对应LED灯亮,高电平则对应LED灯灭, S3C2440芯片GPF4-G ...

  4. [ZigBee] 16、Zigbee协议栈应用(二)——基于OSAL的无线控制LED闪烁分析(下)

    说在前面:上一篇介绍了无线LED闪烁实现的OSAL部分,本篇介绍如何实现无线数据收发及数据处理: 上一篇是用SI跟着流程查看源码,我个人认为以架构的思维去了解代码能让人更清晰 ::ZMain.c程序入 ...

  5. [ZigBee] 13、ZigBee基础阶段性回顾与加深理解——用定时器1产生PWM来控制LED亮度(七色灯)

    引言:PWM对于很多软件工程师可能又熟悉又陌生,以PWM调节LED亮度为例,其本质是在每个周期都偷工减料一些,整体表现出LED欠压亮度不同的效果.像大家看到的七色彩灯其原理也类似,只是用3路PWM分别 ...

  6. 树莓派 LED+蜂鸣+声音传感器+红外模块组合打造声控/红外控制LED

    昨天搞了控制LED,玩了第一个,剩下的就感觉很简单了,这里记录一下 先来几张照片 玩了蜂蜜模块才发现规律,一般这种模块,都会有三个针脚,VCC(3.3V或5V供电输出针脚).GNC(对应GPIO针脚的 ...

  7. (三)开关检测来控制LED灯的亮灭

    开关检测案例一: 具体电路图如下: K1--K4闭合,控制 D1—D4 亮灭 产生的问题: 1.关于 R8 R9 R7 R10 的阻值选择问题,倘若太大的话,  比如10K 不管开关断开还是闭合,好像 ...

  8. arduino 红外遥控器控制LED灯

    /* 日期:2016.9.1 功能:红外遥控器控制LED灯 开,关,闪烁,呼吸 元件: 跳线公公头 * 5 led 220欧电阻 红外接收管,红外遥控 接线: 红外灯面向自己从左到右分别接 IO3 , ...

  9. 上位机控制led

    使用库函数,调试的结果在标红程序上,int main(void){  u8 a;                  u8 t;        u8 len;                u16 ti ...

随机推荐

  1. PyQt(Python+Qt)学习随笔:desktop的frameGeometry、frameSize、availableGeometry,screenGeometry

    frameGeometry:返回窗口相对于父窗口的几何形状的大小,包括窗口的框架,当窗口是顶级窗口时,返回的实际上是屏幕的大小: frameSize:返回窗口的几何形状的大小,包括窗口的框架,当窗口是 ...

  2. [BJDCTF 2nd]xss之光

    [BJDCTF 2nd]xss之光 进入网址之后发现存在.git泄露,将源码下载下来,只有index.php文件 <?php $a = $_GET['yds_is_so_beautiful']; ...

  3. anaconda 配置虚拟环境

    工作时有时候会遇到不同版本的问题,比如深度学习tensorflow 1.14版本 和 2.0版本,或者cpu版本和gpu版本,那么这个时候建立虚拟环境就很方便了 anaconda命令行下 1) act ...

  4. web前端页面常见优化方法

    (1)减少http请求,尽量减少向服务器的请求数量 (2)避免重定向 (3)利用缓存:使用外联式引用CSS.JS,在实际应用中使用外部文件可以提高页面速度,因为JavaScript和CSS文件都能在浏 ...

  5. 把java编译成exe和安装包

    由于某些项目甲方迟迟不结算尾款,这就很烦,只能想一些办法 我们知道java,python之类的代码是没有隐私可言的,那么怎么办,总要发给甲方验收,这就要做一些操作来确保自己的利益. 通过在源代码里加上 ...

  6. I/O-外部设备

    目录 输入设备 输出设备 显示器 阴极射线管(CRT)显示器 字符显示器 图形显示器 图像显示器 打印机 小结 外存储器 磁盘存储器 磁盘设备的组成 存储区域 硬盘存储器 磁盘的性能指标 磁盘地址 硬 ...

  7. AWT06-事件处理

    在AWT中,用户的所有操作都要由事件处理来完成.Frame和组件本身没有处理事件的能力. 1.GUI事件处理机制 定义:在某个组件上发生某种操作时,自动触发某段代码. 事件处理涉及4个重要概念: 事件 ...

  8. 百度网站统计和CNZZ网站统计对比

    一,前言 百度统计和cnzz统计是目前市面上比较流行的两种web统计工具,接下来将对两个统计工具做初步的体验测评 百度网站统计相关介绍:全球最大的中文网站流量分析平台,帮助企业收集网站访问数据,提供流 ...

  9. Springboot之登录模块探索(含Token,验证码,网络安全等知识)

    简介 登录模块很简单,前端发送账号密码的表单,后端接收验证后即可~ 淦!可是我想多了,于是有了以下几个问题(里面还包含网络安全问题): 1.登录时的验证码 2.自动登录的实现 3.怎么维护前后端登录状 ...

  10. 怎样用Python自制好看的指数估值图

    对于以定投指数的方式理财的朋友,最需要关注的指标便是各个指数的估值,在指数低估时买入,高估时卖出,那如何制作一张估值图来跟踪指数的估值情况呢?本文就从0到1介绍如何用 Matplotlib 画一张漂亮 ...