找回密码
 立即注册
搜索
0赞
赞赏
手机版
扫码打开手机版
把文字装进口袋

点亮STM32、FPGA和Liunx板子的LED灯

不好吃荤漳 2022-8-3 10:14:52
摘要:你点亮过多少板子的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、新建工程

                        2、代码编写

  1. //LEDIO初始化
  2. voidLED_Init(void)
  3. {
  4. GPIO_InitTypeDefGPIO_InitStructure;
  5. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//使能GPIOF时钟
  6. //GPIOF9,F10初始化设置
  7. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_10;//LED0和LED1对应IO口
  8. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;//普通输出模式
  9. GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出
  10. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//100MHz
  11. GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉
  12. GPIO_Init(GPIOF,&GPIO_InitStructure);//初始化GPIO
  13. GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);//GPIOF9,F10设置高,灯灭
  14. }
复制代码
                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代码能够综合出真实的电路以实现我们设计的功能,区别于不可综合的仿真代码。

  1. `timescale1ns/1ns
  2. //带标志信号的计数器
  3. modulecounter
  4. #(
  5. parameterCNT_MAX=25'd24_999_999
  6. )
  7. (
  8. inputwiresys_clk,//系统时钟50Mhz
  9. inputwiresys_rst_n,//全局复位
  10. outputregled_out//输出控制led灯
  11. );
  12. reg[24:0]cnt;//经计算得需要25位宽的寄存器才够500ms
  13. regcnt_flag;
  14. //cnt:计数器计数,当计数到CNT_MAX的值时清零
  15. always@(posedgesys_clkornegedgesys_rst_n)
  16. if(sys_rst_n==1'b0)
  17. cnt
复制代码
                3、代码的分析和综合

                        4、 查看RTL视图

                        5、Testbench代码的编写

  1. `timescale1ns/1ns
  2. moduletb_counter();
  3. //wiredefine
  4. wireled_out;
  5. //regdefine
  6. regsys_clk;
  7. regsys_rst_n;
  8. //初始化系统时钟、全局复位
  9. initialbegin
  10. sys_clk=1'b1;
  11. sys_rst_n
复制代码
                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初始化,示例代码如下:
  1. voidLED_Init(void)
  2. {
  3. GPIO_InitTypeDefGPIO_InitStructure;
  4. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能PB端口时钟
  5. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//PB5端口配置
  6. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
  7. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度
  8. GPIO_Init(GPIOB,&GPIO_InitStructure);//根据设定参数初始化GPIOB.5
  9. GPIO_SetBits(GPIOB,GPIO_Pin_5);//PB.5输出高
  10. }
复制代码
                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_IO03的bit3~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表示输出低电平。
                        汇编由一条一条指令构成,指令就涉及到汇编指令。
  1. Inta,b;
  2. a=b;
复制代码
                假设a地址为0X20,b地址为0x30。
  1. LDRR0,=0X30
  2. LDRR1,[R0]
  3. LDRR0,=0X20
  4. STRR1,[R0]
复制代码
                我们在使用汇编编写驱动的时候最常用的就是LDR和STR这两个指令。
                        1、新建工程

                        新建工程文件夹:
        新建裸机驱动文件夹新建LED灯文件夹                        2、在VSCode中编写代码

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

  1. .global_start/*全局标号*/
  2. _start:
  3. /*1、使能所有时钟ldf如果用大写就全部用大写,如果小写就全部用小写*/
  4. ldrr0,=0X020C4068//将寄存器CCGR0地址0X020C4068存放到寄存器R0中
  5. ldrr1,=0XFFFFFFFF//把寄存器x地址0Xffffffff存放到寄存器r1中
  6. strr1,[r0]//把寄存器r1中的值(0XFFFFFFFF)写入到寄存器r0里面的值作为地址的内存里面
  7. ldrr0,=0X020C406C/*将寄存器CCGR1地址(0X020C4068)存放到寄存器R0中*/
  8. strr1,[r0]
  9. ldrr0,=0X020C4070/*CCGR2*/
  10. strr1,[r0]
  11. ldrr0,=0X020C4074/*CCGR3*/
  12. strr1,[r0]
  13. ldrr0,=0X020C4078/*CCGR4*/
  14. strr1,[r0]
  15. ldrr0,=0X020C407C/*CCGR5*/
  16. strr1,[r0]
  17. ldrr0,=0X020C4080/*CCGR6*/
  18. strr1,[r0]
  19. /*2、设置GPIO1_IO03复用为GPIO1_IO03*/
  20. ldrr0,=0X020E0068/*将寄存器SW_MUX_GPIO1_IO03_BASE加载到r0中*/
  21. ldrr1,=0X5/*设置寄存器SW_MUX_GPIO1_IO03_BASE的MUX_MODE为5*/
  22. strr1,[r0]
  23. /*3、配置GPIO1_IO03的IO属性
  24. *bit16:0HYS关闭
  25. *bit[15:14]:00默认下拉
  26. *bit[13]:0kepper功能
  27. *bit[12]:1pull/keeper使能
  28. *bit[11]:0关闭开路输出
  29. *bit[7:6]:10速度100Mhz
  30. *bit[5:3]:110R0/6驱动能力
  31. *bit[0]:0低转换率
  32. */
  33. ldrr0,=0X020E02F4/*寄存器SW_PAD_GPIO1_IO03_BASE*/
  34. ldrr1,=0X10B0
  35. strr1,[r0]
  36. /*4、设置GPIO1_IO03为输出*/
  37. ldrr0,=0X0209C004/*寄存器GPIO1_GDIR*/
  38. ldrr1,=0X0000008
  39. strr1,[r0]
  40. /*5、打开LED0
  41. *设置GPIO1_IO03输出低电平
  42. */
  43. ldrr0,=0X0209C000/*寄存器GPIO1_DR*/
  44. ldrr1,=0
  45. strr1,[r0]
  46. /*
  47. *描述:loop死循环
  48. */
  49. loop:
  50. bloop
  51. .global_start@全局标号
  52. /**/
复制代码
                4、编译代码

                        使用如下三条命令来编译代码:
  1. arm-linux-gnueabihf-gcc-g-cleds.s-oled.o
  2. arm-linux-gnueabihf-ld-Ttext0X87800000led.o-oled.elf
  3. arm-linux-gnueabihf-objcopy-Obinary-S-gled.elfled.bin
复制代码
编译、链接、格式转换                        最终生成了led.oled.elfled.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软件发送到工程目录下                        烧写的三个命令:
  1. ls/dev/sd*-l
  2. chmod777imxdownload
  3. ./imxdownloadled.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亮。
                        最后,你觉得哪个板子点灯最简单呢?
       
                原文标题:史上最全的LED点灯程序!


                        文章出处:【微信公众号:凡亿PCB】欢迎添加关注!文章转载请注明出处。

审核编辑:汤梓红

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

使用道具 举报

您需要登录后才可以回帖 立即登录
感谢您的无私精神...
2022-8-4 13:38:55
我表示压力很大
2022-8-5 15:57:46
顶一个了
2022-8-6 12:44:52
这个不错,谢谢共享
2022-8-7 09:31:57
太赞了
2022-8-7 20:39:54
不错
2022-8-7 21:08:48
期待中......
2022-8-8 17:47:18
这个不错,谢谢共享
2022-8-9 14:25:48
顶起  很好的帖
2022-8-11 03:40:22
返回顶部