0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用STM32、SFPGA和I.MX6ULL IO点亮LED灯

Q4MP_gh_c472c21 来源:果果小师弟 作者:果果小师弟 2022-03-12 09:24 次阅读

摘要:你点亮过多少板子的LED灯呢?有很多小伙伴要求讲一下STM32FPGA、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、新建工程

58273f7a-4ecb-11ec-9eda-dac502259ad0.png

2、代码编写

//LEDIO初始化
voidLED_Init(void)
{
GPIO_InitTypeDefGPIO_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;//100MHz
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOF,&GPIO_InitStructure);//初始化GPIO
GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);//GPIOF9,F10设置高,灯灭
}

3、编译代码

5837cea8-4ecb-11ec-9eda-dac502259ad0.png

4、配置下载

5876b906-4ecb-11ec-9eda-dac502259ad0.png

烧录代码

二、使用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闪烁一次的效果。

59a704fc-4ecb-11ec-9eda-dac502259ad0.pngLED灯硬件原理图
59b564e8-4ecb-11ec-9eda-dac502259ad0.png流水灯实验管脚分配

1、模块框图

59e5ddda-4ecb-11ec-9eda-dac502259ad0.png 模块框图
5a100268-4ecb-11ec-9eda-dac502259ad0.png输入输出信号描述

2、RTL代码的编写

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

`timescale1ns/1ns
//带标志信号的计数器
modulecounter
#(
parameterCNT_MAX=25'd24_999_999
)
(
inputwiresys_clk,//系统时钟50Mhz
inputwiresys_rst_n,//全局复位
outputregled_out//输出控制led灯
);

reg[24:0]cnt;//经计算得需要25位宽的寄存器才够500ms
regcnt_flag;

//cnt:计数器计数,当计数到CNT_MAX的值时清零
always@(posedgesys_clkornegedgesys_rst_n)
if(sys_rst_n==1'b0)
cnt<= 25'b0;
elseif(cnt< CNT_MAX)
         cnt <= cnt + 1'b1;
else
cnt<= 25'b0;
//cnt_flag:计数到最大值产生的标志信号
always@(posedgesys_clkornegedgesys_rst_n)
if(sys_rst_n==1'b0)
cnt_flag<= 1'b0;
elseif(cnt==CNT_MAX-1'b1)
cnt_flag<= 1'b1;
else
cnt_flag<= 1'b0;
//led_out:输出控制一个LED灯,每当计数满标志信号有效时取反
always@(posedgesys_clkornegedgesys_rst_n)
if(sys_rst_n==1'b0)
led_out<= 1'b0;
elseif(cnt_flag==1'b1)
led_out<= ~led_out;
endmodule

3、代码的分析和综合

5a4e31f0-4ecb-11ec-9eda-dac502259ad0.png

4、 查看RTL视图

5a60d08a-4ecb-11ec-9eda-dac502259ad0.png

5、Testbench代码的编写

`timescale1ns/1ns
moduletb_counter();


//wiredefine
wireled_out;

//regdefine
regsys_clk;
regsys_rst_n;

//初始化系统时钟、全局复位
initialbegin
sys_clk=1'b1;
sys_rst_n<= 1'b0;
#20
sys_rst_n<= 1'b1;
end

//sys_clk:模拟系统时钟,每10ns电平翻转一次,周期为20ns,频率为50Mhz
always#10sys_clk=~sys_clk;

initialbegin
$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),//inputsys_clk
.sys_rst_n(sys_rst_n),//inputsys_rst_n

.led_out(led_out)//outputled_out
);
endmodule

6、ModelSim仿真波形

5abf71bc-4ecb-11ec-9eda-dac502259ad0.png5aec22ca-4ecb-11ec-9eda-dac502259ad0.png

7、上板验证

5b37b0a0-4ecb-11ec-9eda-dac502259ad0.png5b77d194-4ecb-11ec-9eda-dac502259ad0.png

程序下载完毕后,会看到板卡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初始化,示例代码如下:

voidLED_Init(void)
{
GPIO_InitTypeDefGPIO_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.5
GPIO_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表示输出低电平。

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

Inta,b;
a=b;

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

LDRR0,=0X30
LDRR1,[R0]
LDRR0,=0X20
STRR1,[R0]

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

1、新建工程

新建工程文件夹:

5c6e1270-4ecb-11ec-9eda-dac502259ad0.png新建裸机驱动文件夹5c837598-4ecb-11ec-9eda-dac502259ad0.png新建LED灯文件夹

2、在VSCode中编写代码

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

5cd3208e-4ecb-11ec-9eda-dac502259ad0.png

3、编写代码

.global_start/*全局标号*/

_start:

/*1、使能所有时钟ldf如果用大写就全部用大写,如果小写就全部用小写*/
ldrr0,=0X020C4068//将寄存器CCGR0地址0X020C4068存放到寄存器R0中
ldrr1,=0XFFFFFFFF//把寄存器x地址0Xffffffff存放到寄存器r1中
strr1,[r0]//把寄存器r1中的值(0XFFFFFFFF)写入到寄存器r0里面的值作为地址的内存里面

ldrr0,=0X020C406C/*将寄存器CCGR1地址(0X020C4068)存放到寄存器R0中*/
strr1,[r0]

ldrr0,=0X020C4070/*CCGR2*/
strr1,[r0]

ldrr0,=0X020C4074/*CCGR3*/
strr1,[r0]

ldrr0,=0X020C4078/*CCGR4*/
strr1,[r0]

ldrr0,=0X020C407C/*CCGR5*/
strr1,[r0]

ldrr0,=0X020C4080/*CCGR6*/
strr1,[r0]

/*2、设置GPIO1_IO03复用为GPIO1_IO03*/
ldrr0,=0X020E0068/*将寄存器SW_MUX_GPIO1_IO03_BASE加载到r0中*/
ldrr1,=0X5/*设置寄存器SW_MUX_GPIO1_IO03_BASE的MUX_MODE为5*/
strr1,[r0]

/*3、配置GPIO1_IO03的IO属性
*bit16:0HYS关闭
*bit[15:14]:00默认下拉
*bit[13]:0kepper功能
*bit[12]:1pull/keeper使能
*bit[11]:0关闭开路输出
*bit[7:6]:10速度100Mhz
*bit[5:3]:110R0/6驱动能力
*bit[0]:0低转换率
*/
ldrr0,=0X020E02F4/*寄存器SW_PAD_GPIO1_IO03_BASE*/
ldrr1,=0X10B0
strr1,[r0]

/*4、设置GPIO1_IO03为输出*/
ldrr0,=0X0209C004/*寄存器GPIO1_GDIR*/
ldrr1,=0X0000008
strr1,[r0]

/*5、打开LED0
*设置GPIO1_IO03输出低电平
*/
ldrr0,=0X0209C000/*寄存器GPIO1_DR*/
ldrr1,=0
strr1,[r0]

/*
*描述:loop死循环
*/
loop:
bloop
.global_start@全局标号
/**/

4、编译代码

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

arm-linux-gnueabihf-gcc-g-cleds.s-oled.o
arm-linux-gnueabihf-ld-Ttext0X87800000led.o-oled.elf
arm-linux-gnueabihf-objcopy-Obinary-S-gled.elfled.bin
5cd3208e-4ecb-11ec-9eda-dac502259ad0.png编译、链接、格式转换

最终生成了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软件。

5d31d5e8-4ecb-11ec-9eda-dac502259ad0.png利用FileZilla Client软件将imxdownload软件发送到工程目录下

烧写的三个命令:

ls/dev/sd*-l
chmod777imxdownload
./imxdownloadled.bin/dev/sdb

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

5d86a73a-4ecb-11ec-9eda-dac502259ad0.png5dc7b1bc-4ecb-11ec-9eda-dac502259ad0.png插拔SD卡可以看到两个的区别

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

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

5dfb6426-4ecb-11ec-9eda-dac502259ad0.png向SD卡烧写完成

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

5e3e3332-4ecb-11ec-9eda-dac502259ad0.png

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

5e4dcc02-4ecb-11ec-9eda-dac502259ad0.png

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

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

原文标题:史上最全的LED点灯程序,你都掌握了吗?

文章出处:【微信公众号:嵌入式ARM】欢迎添加关注!文章转载请注明出处。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1600

    文章

    21284

    浏览量

    592880
  • led
    led
    +关注

    关注

    237

    文章

    22420

    浏览量

    645791
  • STM32
    +关注

    关注

    2239

    文章

    10665

    浏览量

    348518

原文标题:史上最全的LED点灯程序,你都掌握了吗?

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    i.MX6UL/i.MX6ULL开发常见问题】单独编译内核,uboot生成很多文件,具体用哪一个?

    i.MX6UL/i.MX6ULL开发常见问题》基于米尔电子 i.MX6UL/i.MX6ULL产品(V.10)2.3单独编译内核,uboot生成很多文件,具体用哪一个?答:内核编译出来
    发表于 07-01 17:50

    I.MX6ULL终结者开发板裸机仿真jlink调试

    I.MX6ULL‘终结者’开发板预留了JTAG仿真接口,并给出了开发文档,可以实现在JLINK仿真器条件下的单步跟踪、断点调试等功能,使得开发研究i.MX6ULL处理器的相关技术更加直观便利。
    发表于 07-07 10:56

    i.MX6ULL开发板硬件资源

    迅为i.MX6ULL 终结者开发板硬件资源非常丰富,几乎将 i.MX6ULL 芯片的所有资源都扩展引出到底板上了,底板提供了丰富的外设接口,开发板的尺寸是 190mm*125mm,充分考虑了人性化设计,整体显得十分大。
    发表于 12-29 06:18

    迅为i.MX6ULL终结者线程基础线程终止与回收解析

    迅为i.MX6ULL终结者线程基础线程终止与回收
    发表于 04-02 06:43

    i.MX6ULL核心板资源

    `STAMP-IMX6ULL-CM是浙江启扬智能科技有限公司推出的基于 NXP i.MX6ULL 处理器的产品;i.MX 6ULL 是 NXP 推出的 ARM Cortex-A7 系列
    发表于 07-12 17:50

    stm32f0717bt6i.mx6ull启动方式的区别是什么?

    stm32f0717bt6i.mx6ull启动方式的区别是什么?
    发表于 11-29 07:51

    介绍UART在i.mx6ull上的开发步骤

    F4的HAL库开发在之前文章已经提及,本篇文章将介绍UART在i.mx6ull上的开发步骤。由于此芯片的裸机开发在Linux下并使用ARM-Linux交叉编译生成可执行文件下载至板中进行运行,所以相像STM32开...
    发表于 12-16 06:34

    初识 i.MX6ULL 寄存器

    裸机开发_L1_汇编LED实验0. 本节目标1. 硬件层电路2. 初识 i.MX6ULL 寄存器2.1 i.MX6ULL 时钟控制寄存器2.2 i.MX6ULL
    发表于 12-20 07:13

    ARM裸机篇之i.MX6ULL处理器资料分享

    1、i.MX6ULL处理器启动过程i.MX6ULL是NXP基于ARM Cortex-A7内核的单核处理器家族,主频可以高900MHz。i.MX6ULL应用处理器包含了电源管理模块,可以降低外部电源
    发表于 04-14 16:42

    关于i.MX6ULL配置GPIO

    正如学习C语言时写的第一段代码都是“HelloWorld!”,接触一款新的处理器时往往是从点亮一个LED开始;而点亮一个LED,则需要操作这款芯片的GPIO外设。那么作为广受欢迎的
    发表于 08-05 10:37

    I.MX6ULL无法枚举USB2514是为什么?

    你好目前,I.MX6ULL开发存在一些问题。其中之一是OTG USB2无法正常挂载USB2514,无法正确枚举下游设备,只显示设备id。usb设计要注意什么。
    发表于 04-03 06:55

    I.MX6ULL UART传输问题求解

    I.MX6ULL UART传输问题
    发表于 04-21 08:09

    如何使用Linux版本在i.mx6ull上启用USB网络共享?

    我从 lf-5.10-y 分支为 i.mx6ull evk 构建了 Linux。我将我的 android 手机连接到 usb otg 端口并在我的手机上启用网络共享。但是我没有看到 USB0 接口
    发表于 05-09 08:06

    i.MX6ULL】驱动开发4——点亮LED(寄存器版)

    本篇主要介绍了如何通过操作寄存器来点亮i.MX6ULL开发板上的led,通过编写LED对应的驱动程序和应用程序,实现程序设计的分层。
    的头像 发表于 05-21 21:26 2644次阅读
    【<b class='flag-5'>i.MX6ULL</b>】驱动开发4——<b class='flag-5'>点亮</b><b class='flag-5'>LED</b>(寄存器版)

    基于i.MX6ULL点亮LED

    都说入门一款芯片的第一步是点亮LED,但是i.MX6ULL入门门槛比较高,特别是通过自学入门的,这个系列已经写了好久了,最近打算在项目不急的时候加快一下学习进度,现在就开始学习一下怎么点亮
    的头像 发表于 03-06 09:09 499次阅读