史上最全的LED点灯程序,你都掌握了吗?

摘要:你点亮过多少板子的LED灯呢?有很多小伙伴留言说讲一下STM32、FPGA、Liunx他们之间有什么不同。不同点很多,口说无凭,今天就来点亮一下STM32、FPGA和Liunx板子的LED灯,大家大致看一下点灯流程点灯环境以及点灯流程,就能大概的了解一下三者的区别,可以有选择的去学习!

一、使用STM32点亮LED灯

STM32从字面上来理解ST是意法半导体,M是Microelectronics的缩写,32 表示32位,合起来理解,STM32就是指ST公司开发的32位微控制器。在如今的32 位控制器当中,STM32可以说是最璀璨的新星,它受宠若娇,大受工程师和市场的青睐,无芯能出其右。首先使用STM32电亮一个led灯,大家现在回过头来看是不是非常的简单。

STM32初始化流程

1、使能指定GPIO的时钟。

2、初始化GPIO,比如输出功能、上拉、速度等等。

3、STM32有的IO可以作为其它外设引脚,也就是IO复用,如果要将IO作为其它外设引脚使用的话就需要设置 IO 的复用功能。

4、最后设置GPIO输出高电平或者低电平。

1、新建工程

2、代码编写

//LED IO初始化
void LED_Init(void)
{      GPIO_InitTypeDef  GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟//GPIOF9,F10初始化设置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;//LED0和LED1对应IO口GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIO GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10);//GPIOF9,F10设置高,灯灭
}

3、编译代码

4、配置下载器

烧录代码

二、使用FPGA点亮LED灯

FPGA(Field Programmable Gate Array,简称 FPGA),译文:现场可编程门阵列,一种主要以数字电路为主的集成芯片,于1985年由Xilinx创始人之一 Ross Freeman发明,属于可编程逻辑器件PLD(Programmable Logic Device)的一种。真正意义上的第一颗FPGA芯片XC2064为Xilinx所发明,这个时间差不多比著名的摩尔定律晚20年左右,但是FPGA一经发明,后续的发展速度之快,超出大多数人的想象。

计数器是在FPGA设计中最常用的一种时序逻辑电路,根据计数器的计数值我们可以精确的计算出FPGA内部各种信号之间的时间关系,每个信号何时拉高、何时拉低、拉高多久、拉低多久都可以由计数器实现精确的控制。而让计数器计数的是由外部晶振产生的时钟,所以可以比较精准的控制具体需要计数的时间。计数器一般都是从0开始计数,计数到我们需要的值或者计数满溢出后清零,并可以进行不断的循环。

本例我们让计数器计数1s时间间隔,来实现led灯每隔1s闪烁一次的效果。

LED灯硬件原理图流水灯实验管脚分配

1、模块框图

模块框图输入输出信号描述

2、RTL代码的编写

开始RTL代码的编写,RTL代码编写出的模块叫RTL模块(后文中也称功能模块、可综合模块)。之所以叫RTL代码是因为用Verilog HDL在Resistances Transistors Logic(寄存器传输级逻辑)来描述硬件电路,RTL代码能够综合出真实的电路以实现我们设计的功能,区别于不可综合的仿真代码。

`timescale  1ns/1ns
//带标志信号的计数器
module  counter
#(parameter   CNT_MAX = 25'd24_999_999
)
(input   wire    sys_clk     ,   //系统时钟50Mhzinput   wire    sys_rst_n   ,   //全局复位output  reg     led_out         //输出控制led灯
);reg     [24:0]  cnt;       //经计算得需要25位宽的寄存器才够500ms
reg             cnt_flag;//cnt:计数器计数,当计数到CNT_MAX的值时清零
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt <= 25'b0;else    if(cnt < CNT_MAX)cnt <= cnt + 1'b1;elsecnt <= 25'b0;
//cnt_flag:计数到最大值产生的标志信号
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_flag <= 1'b0;else    if(cnt == CNT_MAX - 1'b1)cnt_flag <= 1'b1;elsecnt_flag <= 1'b0;
//led_out:输出控制一个LED灯,每当计数满标志信号有效时取反
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)led_out <= 1'b0;else    if(cnt_flag == 1'b1)led_out <= ~led_out;
endmodule

3、代码的分析和综合

4、 查看RTL视图

5、Testbench代码的编写

`timescale  1ns/1ns
module  tb_counter();//wire  define
wire            led_out     ;//reg   define
reg             sys_clk     ;
reg             sys_rst_n   ;//初始化系统时钟、全局复位
initial beginsys_clk    = 1'b1;sys_rst_n <= 1'b0;#20sys_rst_n <= 1'b1;
end//sys_clk:模拟系统时钟,每10ns电平翻转一次,周期为20ns,频率为50Mhz
always #10 sys_clk = ~sys_clk;initial begin$timeformat(-9, 0, "ns", 6);$monitor("@time %t: led_out=%b", $time, led_out);
end//------------- counter_inst --------------
counter
#(.CNT_MAX    (25'd24     ) 
)
counter_inst
(.sys_clk    (sys_clk    ),  //input     sys_clk.sys_rst_n  (sys_rst_n  ),  //input     sys_rst_n.led_out    (led_out    )   //output    led_out
);
endmodule

6、ModelSim仿真波形

7、上板验证

程序下载完毕后,会看到板卡LED0不断闪烁,时间间隔为1秒。


三、使用I.MX6ULL IO点亮LED

嵌入式linux学习者大体可以分为两类,一类是进阶用户,主要指已经有大量mcu工作经验的开发者, 他们希望进阶到更有难度,薪资更高的mpu开发中去。另一类则是学生用户,主要是刚开始接触嵌入式开发的大学生群体。

I.MX应用处理器包括I.MX8、I.MX7、I.MX6及I.MX28系列,被广泛应用于工业控制、汽车电子领域,久经市场考验。而且它的产品线非常丰富,用户熟悉其中一款产品后就能非常方便地迁移至不同的平台。

一般拿到一款全新的芯片,第一个要做的事情的就是驱动其GPIO,控制其GPIO输出高低电平,我们学习I.MX6U也一样的,先来学习一下I.MX6U的GPIO。在学习I.MX6U的GPIO之前,我们可以对比一下STM32的GPIO初始化(如果没有学过 STM32 就不用回顾了),我们以最常见的STM32F103为例来看一下STM32的GPIO初始化,示例代码如下:

void LED_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能 PB 端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //PB5 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO 口速度GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化 GPIOB.5GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高
}

STM32初始化流程

1、使能指定GPIO的时钟。

2、初始化 GPIO,比如输出功能、上拉、速度等等。

3、STM32 有的 IO 可以作为其它外设引脚,也就是 IO 复用,如果要将 IO 作为其它外设引脚使用的话就需要设置 IO 的复用功能。

4、最后设置GPIO输出高电平或者低电平。

I.MX6U的GPIO一共有5组:GPIO1、GPIO2、GPIO3、GPIO4和GPIO5,其中GPIO1有32个IO,GPIO2有22个IO,GPIO3有29个IO、GPIO4有29个IO,GPIO5最少,只有12个IO,这样一共有124个GPIO

I.MX6ULL IO初始化流程

1、使能时钟,CCGR0—CCGR6这7个寄存器控制着6ULL所有外设时钟的使能。为了简单,设置CCGR0~CCGR6这7个寄存器全部为0XFFFFFFFF,相当于使能所有外设时钟。

2、IO复用,将寄存器IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03bit3~0设置为0101=5,这样GPIO1_IO03就复用为GPIO

3、寄存器IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03是设置GPIO1_IO03的电气属性。包括压摆率、速度、驱动能力、开漏、上下拉等。

4、配置GPIO功能,设置输入输出。设置GPIO1_DR寄存器bit3为1,也就是设置为输出模式。设置GPIO1_DR寄存器的bit3,为1表示输出高电平,为0表示输出低电平。

汇编由一条一条指令构成,指令就涉及到汇编指令。

Int a,b;
a=b;

假设a地址为0X20,b地址为0x30

LDR R0, =0X30
LDR R1, [R0]
LDR R0, =0X20
STR R1, [R0]

我们在使用汇编编写驱动的时候最常用的就是LDRSTR这两个指令。

1、新建工程

新建工程文件夹

新建裸机驱动文件夹
新建LED灯文件夹

2、在VSCode中编写代码

ubuntu中我们使用的是VScode编辑器来写代码,跟在windows中新建项目一样,新建项目、保存工作区,然后编写代码。

3、编写代码

.global _start  /* 全局标号 */_start:/* 1、使能所有时钟 ldf如果用大写就全部用大写,如果小写就全部用小写*/ldr r0, =0X020C4068 //将寄存器CCGR0地址0X020C4068 存放到 寄存器R0 中ldr r1, =0XFFFFFFFF //把寄存器x地址0Xffffffff存放到 寄存器r1 中str r1, [r0]//把寄存器r1中的值(0XFFFFFFFF) 写入到寄存器r0里面的值作为地址的内存里面ldr r0, =0X020C406C/*将寄存器CCGR1地址(0X020C4068) 存放到 寄存器R0 中*/str r1, [r0]ldr r0, =0X020C4070   /* CCGR2 */str r1, [r0]ldr r0, =0X020C4074   /* CCGR3 */str r1, [r0]ldr r0, =0X020C4078   /* CCGR4 */str r1, [r0]ldr r0, =0X020C407C   /* CCGR5 */str r1, [r0]ldr r0, =0X020C4080   /* CCGR6 */str r1, [r0]/* 2、设置GPIO1_IO03复用为GPIO1_IO03 */ldr r0, =0X020E0068 /* 将寄存器SW_MUX_GPIO1_IO03_BASE加载到r0中 */ldr r1, =0X5  /* 设置寄存器SW_MUX_GPIO1_IO03_BASE的MUX_MODE为5 */str r1,[r0]/* 3、配置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 低转换率*/ldr r0, =0X020E02F4 /*寄存器SW_PAD_GPIO1_IO03_BASE */ldr r1, =0X10B0str r1,[r0]/* 4、设置GPIO1_IO03为输出 */ldr r0, =0X0209C004 /*寄存器GPIO1_GDIR */ldr r1, =0X0000008  str r1,[r0]/* 5、打开LED0* 设置GPIO1_IO03输出低电平*/ldr r0, =0X0209C000 /*寄存器GPIO1_DR */ldr r1, =0  str r1,[r0]/** 描述:loop死循环*/
loop:b loop     
.global _start @全局标号
/**/

4、编译代码

使用如下三条命令来编译代码

arm-linux-gnueabihf-gcc -g -c leds.s -o led.o
arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
编译、链接、格式转换

最终生成了led.o led.elf led.bin三个文件

5、烧写代码

STM32中代码烧写到内部FLASH。IMX6ULL支持SD卡、EMMC、NAND、nor、SPI flash等启动。裸机例程选择烧写到SD卡里面。在ubuntu下向SD卡烧写裸机bin文件。烧写不是将bin文件拷贝到SD卡中,而是将bin文件烧写到SD卡绝对地址上。而且对于I.MX而言,不能直接烧写bin文件,比如先在bin文件前面添加头部。完成这个工作,需要使用正点原子提供的imxdownload软件。

利用FileZilla Client软件将imxdownload软件发送到工程目录下

烧写的三个命令

ls /dev/sd* -l
chmod 777 imxdownload 
./imxdownload led.bin /dev/sdb

Imxdownload使用方法,确定要烧写的SD卡文件,需要使用ls /dev/sd* -l命令来检测SD是哪一个文件,我的是/dev/sdb

插拔SD卡可以看到两个的区别

给予imxdownload可执行权限:Chmod 777 imxdownload

烧写:./imxdownload led.bin /dev/sdb

向SD卡烧写完成

Imxdownlaod会向led.bin添加一个头部,生成新的load.imx文件,这个load.imx文件就是最终烧写到SD卡里面去的。

这里要注意的是如果烧写的速度在几十MB/S左右的话,那么可能意味着烧写失败了。而且是因为SD卡没找到而导致烧写失败,这个问题只能重启 ubuntu解决。

之后就可以从读卡器中把SD拔下来,然后插入到开发板中,将拨码开关拔止SD卡模式,供电之后,蓝色LED亮,红色LED灭,两秒钟之后红色LED亮。

最后你觉得哪个板子点灯最简单呢?

End


推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈

关注公众号,后台回复「1024」获取学习资料网盘链接。

欢迎点赞,关注,转发,在看,您的每一次鼓励,我都将铭记于心~

嵌入式Linux

微信扫描二维码,关注我的公众号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/465748.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

修复远程过程调用 (RPC) 时发生的各种问题KB908521

当系统出现RPC通讯问题时可以尝安装KB908521进行修复。安装本更新程序可以解决当您在 Microsoft Windows Server 2003 和 Microsoft Windows XP 中的客户端/服务器通信中使用远程过程调用 (RPC) 时发生的各种问题。http://www.microsoft.com/downloads/details.aspx?FamilyID7…

B站硬核up主稚晖君:对于3年以上软件开发工程师,我有这些建议!

稚晖君&#xff0c;何许人也&#xff1f;本硕就读于电子科技大学华为AI架构师热爱硬件开发B站硬核UP主“栈溢出”工程师加入“华为天才少年计划”或许当你看到这一堆Title的时候并不觉得有什么特别&#xff0c;那么接下来看看他的一些作品。作品1&#xff1a;B站最强小电视这条…

Python 实现微信小程序的用户登录

小程序可以通过官方提供的登录能力来获取用户身份的标示&#xff0c;具体文档可以参考 这里&#xff0c;通过流程时序可以看到&#xff0c;对于需要和前端配合的服务端开发&#xff0c;主要实现的就是通过小程序提供的 code 换取用户的 openid 和 session_key&#xff0c;并用换…

硬件基础 —— 电容

硬件基础 —— 电容1、电容基本知识&#xff08;记忆元件&#xff09;电容器是一种能储存电荷的容器。电容器对直流电阻力无穷大&#xff0c;即电容器具有通交隔直的作用。电容器对交流电的阻力受交流电频率影响&#xff0c;即相同容量的电容器对不同频率的交流电呈现不同的容抗…

python 学习笔记一

有关 dictionary、tuple、和 list Tuple 是不可变的 list。一旦创建了一个 tuple&#xff0c;就不能以任何方式改变它。如t ("a", "b", "mpilgrim", "z", "example") List 是 Python 中使用最频繁的数据类型。如&#xff1…

同事说rar压缩有风险,让我用zip压缩文件

在现在最常见的压缩文件有zip、rar、7z三种&#xff0c;它们都有各自的优点和缺点。我们用一句话来概括一下&#xff1a;7z压缩率最高&#xff0c;RAR安全性高&#xff0c;ZIP使用范围广。文件压缩打包是最为常见的一种分享方式了&#xff0c;而众多的压缩格式中zip仍然是主流。…

JAVA实现概率计算(数字不同范围按照不同几率产生随机数)

程序中经常遇到随机送红包之类的情景&#xff0c;这个随机还得指定概率&#xff0c;比如10%的机率可以得到红包。那么java怎么实现一个简单的概率计算了&#xff0c;见如下例子&#xff1a; int randomInt RandomUtils.nextInt(1,101); if(randomInt < 10){ //100里面1个数…

硬件基础 —— 二极管

硬件基础 —— 二极管1、二极管基础知识PN结&#xff1a;P区空穴&#xff0c;N区电子。由于浓度差原理&#xff0c;会产生扩散运动&#xff08;N到P运动&#xff09;。在电场作用下&#xff0c;载流电子作漂移运动&#xff0c;方向与扩散运动方向相反直到PN结电流为零&#xff…

AKI-H8串口通信

串口通信是一种通信接口简写SCI&#xff0c;它可是实现异步和同步两种传输模式。可以思考一下同步和异步的区别。 所谓同步就是接收方和发送方使用的是同一个时钟&#xff0c;步调一致的处理数据。典型的就是CPU和内存&#xff0c;通过总线存取数据。特点就是快&#xff0c;发送…

字节取消大小周,部分员工:心疼,每个月少拿 1W 块

如图&#xff0c;是脉脉最近的一个热帖&#xff0c;头条昨天全员发邮件取消了大小周&#xff0c;原本是一件好事&#xff0c;减轻大家的工作压力&#xff0c;努力向 workbalance 靠拢&#xff0c;可是看着风向好像不太对&#xff0c;我们继续看下 TOP 的几个回复。下面是反对头…

高通LCD的pwm背光驱动

发生异常的现象&#xff1a; msm8953 lcd在快速亮灭的情况下背光概率性休眠不灭&#xff1b;测量高通pwm&#xff0c;发现正常的时候pwm的管脚LCM_BL_PWM为低电平&#xff0c;失败的时候为高电平&#xff1b; 根据原理图&#xff1a; mpp是什么&#xff1f; mpp是基于电源pmic的…

为什么一个字节定义成8位?

今天给大家分享一个小小知识点&#xff0c;为什么一个字节定义成8位呢&#xff1f;一些人没有回答到点子上。这件事得追溯计算机历史&#xff0c;源于IBM360操作系统和图灵奖得主&#xff08;Fred&#xff09;Brooks Jr。布鲁克斯被问到“您认为自己最大的技术成就是什么&#…

测试一下新的签名

测试一下新的签名看看是否漂亮

硬件基础 —— 光耦

光耦1、工作原理以光为媒介传递电信号。对输入和输出信号有良好的隔离作用&#xff08;光耦隔离&#xff09;。光耦一般由三个部分组成&#xff1a;光的发射、光的接收和信号放大。输入的电信号驱动发光二极管&#xff0c;被光探测器接收而产生光电流&#xff0c;再经过进一步放…

【51nod】1934 受限制的排列

题解 这题还要判无解真是难受…… 我们发现我们肯定能确定1的位置&#xff0c;1左右的两个区间是同理的可以确定出最小值的位置 我们把区间最小值看成给一个区间1&#xff0c;构建出笛卡尔树&#xff0c;就求出了每一次取最小值和最小值左右的区间大小 然后就相当于左右子树的排…

红外感应自动出水水龙头的电路原理

红外感应自动出水的水龙头&#xff0c;生活中很常见&#xff1a;可以用以下的电路方案实现&#xff0c;供电采用USB的5V&#xff1a;只要手靠近“红外线靠近检测模块”&#xff0c;直流水泵就会开启供水&#xff1a;其中这种直流水泵长这样&#xff1a;当“红外线靠近检测模块”…

推荐一些国产开源项目

推荐一些国产开源项目EasyjfEasyjf是一个国产的开源社区&#xff0c;开源项目众多&#xff0c;都做的一般般&#xff0c;但是要支持下&#xff01;http://www.easyjf.com/精仿DZ论坛 LForum 写在前面的话&#xff1a;一 直以来&#xff0c;我都对Web充满了兴趣。曾在04年就开始…

Linux面试最高频的5个基本问题

CPU利用率和CPU负载的区别是什么提到CPU利用率&#xff0c;就必须理解时间片。什么是CPU时间片&#xff1f;我们现在所使用的Windows、Linux、Mac OS都是“多任务操作系统”&#xff0c;就是说他们可以“同时”运行多个程序&#xff0c;比如一边打开Chrome浏览器浏览网页还能一…

用iptables实现G1手机cmwap代理上http网站[转]

2019独角兽企业重金招聘Python工程师标准>>> 折腾了几天&#xff0c;总算有点阶段性成果&#xff1a; 证实可以用iptables实现通过cmwap的代理上HTTP协议的网站。 首先&#xff0c;android系统的实现是有缺陷的。在接入apn中指定的proxy并不会被系统所用。好似只有浏…

equals与==的区别

使用比较原生类型如&#xff1a;boolean、int、char等等&#xff0c;使用equals()比较对象。 1、是判断两个变量或实例是不是指向同一个内存空间。 equals是判断两个变量或实例所指向的内存空间的值是不是相同。 2、是指对内存地址进行比较。 equals()是对字符串的内容进行比较…