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

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

3天内不再提示

如何利用C语言控制LED灯的实现

嵌入式开发爱好者 来源:嵌入式开发爱好者 作者:嵌入式开发爱好者 2022-11-30 09:58 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

第一:C语言板控制LED灯简介

实际工作中很少会使用到汇编去编写嵌入式驱动,毕竟汇编太难,写出来也不好理解,大部分情况下都使用C语言去编写。只是在开始部分用汇编初始化一下C语言环境,比如初始化DDR、设置堆栈指针SP等。当这些工作都做完以后就可以进入C语言环境,也就是运行C语言代码,一般都是进入main函数。所以都是进入main函数,有两部分文件要做:

1、汇编文件

汇编文件只是用来完成C语言环境搭建的。

2、C语言文件

C语言文件就是完成我们的业务层代码的,其实就是我们实际要完成的功能。其实STM32也是这样的,只是我们在开发STM32的时候没有想到这一点,以STM32中启动文件startup_stm32f10x_hd.s这个汇编文件就是完成C语言环境搭建的,当然还有一些其他处理,比如中断向量表等。

第二:实验程序实现

在STM32中,启动文件startup_hd.s就是完成C语言环境搭建的,当然还有一些其他的处理。

 Stack_Size EQU 0x00000400
                 AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
 __initial_sp
;HeapConfiguration
;HeapSize(inBytes)<0x0-0xFFFFFFFF:8>
;


Heap_SizeEQU0x00000200


  AREAHEAP,NOINIT,READWRITE,ALIGN=3
  __heap_base
  Heap_MemSPACEHeap_Size
__heap_limit
//省略掉部分代码
Reset_Handler PROC
    EXPORT Reset_Handler [WEAK]
  IMPORT__main
   IMPORTSystemInit
   LDRR0,=SystemInit
   BLXR0
   LDRR0,=__main
BXR0
ENDP

代码分析:设置栈的大小,这里设置为0X400=1024字节。下面遇到的__initial_sp就是初始化SP指针。设置堆的大小,复位中断服务函数,STM32复位完成以后会执行中断服务函数。调用SystemInit()函数来完成其他初始化工作,会调用__main是库函数实现。

.global _start /* 全局标号 */
_start:
/* 进入 SVC 模式 */
mrsr0,cpsr
bicr0,r0,#0x1f/*将r0的低5位清零,也就是cpsr的M0~M4*/
orrr0,r0,#0x13/*r0或上0x13,表示使用SVC模式*/
msrcpsr,r0//将r0的数据写入到cpsr_c中
ldr sp, =0X80200000 /* 设置栈指针 */
bmain/*跳转到main函数*/

这里我们可以设置处理器运行于SVC模式下,处理器模式的设置是通过修改CPSR程序状态寄存器来完成的。上面编写的start.s文件中却没有初始化DDR3的代码,但是却将SVC模式下的SP指针设置到了DDR3的地址范围中,这不会出问题吗?肯定不会的,DDR3肯定还是要初始化的,DCD数据包含了DDR配置参数,内部的Boot ROM会读取DCD数据中的参数完成DDR初始化的。

第三:C语言实验控制程序

C语言部分有两个文件件 main.c 和 main.h,main.h 里面主要是定义的寄存器地址,在 main.h里面输入代码:

#ifndef __MAIN_H
#define __MAIN_H
//CCM相关寄存器地址
#define CCM_CCGR0 *((volatile unsigned int *)0X020C4068)
#define CCM_CCGR1 *((volatile unsigned int *)0X020C406C)
#defineCCM_CCGR2*((volatileunsignedint*)0X020C4070)
#defineCCM_CCGR3*((volatileunsignedint*)0X020C4074)
#defineCCM_CCGR4*((volatileunsignedint*)0X020C4078)
#defineCCM_CCGR5*((volatileunsignedint*)0X020C407C)
#defineCCM_CCGR6*((volatileunsignedint*)0X020C4080)
//相关寄存器地址
#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)
#defineGPIO1_ICR1*((volatileunsignedint*)0X0209C00C)
#defineGPIO1_ICR2*((volatileunsignedint*)0X0209C010)
#defineGPIO1_IMR*((volatileunsignedint*)0X0209C014)
#defineGPIO1_ISR*((volatileunsignedint*)0X0209C018)
#defineGPIO1_EDGE_SEL*((volatileunsignedint*)0X0209C01C)


#endif

在main.h中以宏定义的形式定义要使用到所有的寄存器,后面的数字就是其地址信息,比如CCM_CCGR0 寄存器的地址就是 0X020C4068,这个很简单,很好理解。main.c函数的具体实现。

#include"main.h"
//使能外设的所有时钟
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;
}

//初始化LED对应的GPIO时钟
void led_init(void)
{
/* 1、初始化 IO 复用, 复用为 GPIO1_IO03 */
     SW_MUX_GPIO1_IO03 = 0x5;
     
//配置GPIO1_IO03属性
  SW_PAD_GPIO1_IO03 = 0X10B0;
  
//初始化GPIO,GPIO_IO03设置为输出
GPIO1_GDIR=0X0000008;

//设置GPIO1_IO03输出低电平,打开LED0
GPIO1_DR=0x0;
}

//打开对应的LED灯
void led_on(void)
{
  //将GPIO1_DR 的 bit3 清零 
  GPIO1_DR &= ~(1<<3);
}

//关闭LED灯
void led_off(void)
{
    GPIO1_DR |= (1<<3);
}

//短暂的延时函数
void delay_short(volatile unsigned int n)
{
while(--){}
}

//延时大约1ms的函数
void delay(volatile unsigned int n)
{
    while(n--)
    {
delay_short(0x7ff);
    }
}

int main(void)
{
    clk_enable(); /* 使能所有的时钟 */
    led_init();/*初始化led*/
    
    while(1)/*死循环*/
{
   led_off();/*关闭LED*/
   delay(500);/*延时大约500ms*/
  
   led_on();/*打开LED*/
   delay(500);/*延时大约500ms*/
}


    return0;
}

利用Makefile文件可以进行编译,将对应的可执行文件,放到开发板上,可以看到LED大概500ms闪烁一次。

总结:利用C语言实现底层驱动的控制,要注意可执行程序放的位置,以及如何链接编译等。

审核编辑:郭婷


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

    关注

    243

    文章

    24433

    浏览量

    687249
  • Linux
    +关注

    关注

    88

    文章

    11627

    浏览量

    217888
  • 函数
    +关注

    关注

    3

    文章

    4406

    浏览量

    66812

原文标题:Linux系统中利用C语言控制LED灯的实现

文章出处:【微信号:嵌入式开发爱好者,微信公众号:嵌入式开发爱好者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    C语言特性

    的执行效率和资源利用率有着严苛的要求。C 语言生成的代码简洁紧凑,能够在有限的硬件条件下快速运行,满足嵌入式系统对性能的高要求。例如,在智能家居设备的控制芯片中,
    发表于 11-24 07:01

    FZH120C 存储器交换LED显示控制的驱动芯片 用来驱动点阵 LED

    型号:FZH120C厂商:深圳市方中禾科技有限公司(Premier Chip Limited)FZH120C是一种存储器交换LED显示控制的驱动芯片,可以选择多重的ROW/COM模式(
    发表于 11-21 09:18

    C语言在嵌入式开发中的应用

    稳定性控制系统(VSC)等关键部件的开发,C 语言都发挥着至关重要的作用。 以工业自动化生产线中的运动控制系统为例,C
    发表于 11-21 08:09

    LuatOS中PWM实现LED亮度调节与呼吸的实战教程

    PWM在LED亮度调节和呼吸效果实现方面有着广泛应用。在LuatOS环境中,如何高效运用PWM功能是开发者需要掌握的关键。本实战教程将通过具体案例,引导开发者快速上手,轻松实现
    的头像 发表于 11-11 19:05 7058次阅读
    LuatOS中PWM<b class='flag-5'>实现</b><b class='flag-5'>LED</b>亮度调节与呼吸<b class='flag-5'>灯</b>的实战教程

    2.4 A 三通道闪光 LED 驱动器,带 I<sup>2</sup>C 控制接口 skyworksinc

    电子发烧友网为你提供()2.4 A 三通道闪光 LED 驱动器,带 I2C 控制接口相关产品参数、数据手册,更有2.4 A 三通道闪光
    发表于 07-30 18:30
    2.4 A 三通道闪光<b class='flag-5'>灯</b> <b class='flag-5'>LED</b> 驱动器,带 I<sup>2</sup><b class='flag-5'>C</b> <b class='flag-5'>控制</b>接口 skyworksinc

    LED珠来料检验

    珠是LED灯具最核心的原物料,直接决定了灯具的性能和可靠性。大多LED照明厂商出于投资回报比的考量,并未采购专业的微观结构检测设备,也缺乏材料学科的专业技术人员。LED
    的头像 发表于 07-24 11:30 1350次阅读
    <b class='flag-5'>LED</b><b class='flag-5'>灯</b>珠来料检验

    LED植物生长的原理是什么

    LED植物生长基于植物光合作用对特定光谱的需求,通过人工光源精准调控光质、光强和光周期,优化植物生长。其核心原理是利用LED芯片对光谱进行精确匹配,光强与光周期可控,适应不同应用场景
    的头像 发表于 06-30 17:23 1064次阅读
    <b class='flag-5'>LED</b>植物生长<b class='flag-5'>灯</b>的原理是什么

    【BPI-CanMV-K230D-Zero开发板体验】+控制与Python编程

    ,在学习Python编程的基础上通过GPIO来实现LED控制。 在开发板上,仅有的2个可供GPIO控制的器件是RGB_
    发表于 06-27 17:33

    深入理解C语言C语言循环控制

    C语言编程中,循环结构是至关重要的,它可以让程序重复执行特定的代码块,从而提高编程效率。然而,为了避免程序进入无限循环,C语言提供了多种循环控制
    的头像 发表于 04-29 18:49 1728次阅读
    深入理解<b class='flag-5'>C</b><b class='flag-5'>语言</b>:<b class='flag-5'>C</b><b class='flag-5'>语言</b>循环<b class='flag-5'>控制</b>

    使用单片机驱动多组LED实现呼吸效果电路

    各位大佬,请教下,当前我需要使用单片机驱动控制20路并联LED,需要PWM驱动实现呼吸的效果,目前我是直接使用三极管驱动,这种电路会有什
    发表于 04-11 14:24

    S32G2如何利用C语言开发IPCF?

    S32G2 应该如何利用 C语言在 A 核上开发 IPCF 程序,是否有相关的 SDK 可用?或者我需要将 ipc-shm 等封装到一个 C 库中,有没有相关的文档或示例?
    发表于 03-27 06:49

    零知开源——使用 GPIO 模拟时序驱动 WS2812B LED

    利用零知增强版的GPIO 模拟时序        在本教程中,我们将探讨如何使用 零知增强版的 GPIO 接口来模拟 WS2812B LED 带的信号传输时序,从而实现对单色或多彩
    的头像 发表于 02-20 15:43 2087次阅读
    零知开源——使用 GPIO 模拟时序驱动 WS2812B <b class='flag-5'>LED</b> <b class='flag-5'>灯</b>带

    智慧杆公司 智慧路灯智慧路灯软件,网关,led显示屏,单控制器等多功能

    智慧杆公司 智慧路灯智慧路灯软件,网关,led显示屏,单控制器等多功能
    的头像 发表于 02-07 09:40 949次阅读
    智慧<b class='flag-5'>灯</b>杆公司 智慧路灯智慧路灯软件,网关,<b class='flag-5'>led</b>显示屏,单<b class='flag-5'>灯</b><b class='flag-5'>控制</b>器等多功能

    贴片NTC热敏电阻在LED照明中的应用

    ,因此需要进行有效的温度控制,来保持LED的亮度稳定且寿命持久。解决办法是将贴片NTC热敏电阻嵌入电路,与LED进行热耦合,利用NTC电阻
    的头像 发表于 12-29 09:34 1405次阅读
    贴片NTC热敏电阻在<b class='flag-5'>LED</b>照明中的应用

    擎耀解码智能汽车可替换LED前照控制运行组成原理方案

    智能汽车可替换LED前照控制运行的原理涉及多个方面,包括自适应前照系统(AFS)的工作原理、传感器的应用、步进电机的控制以及模糊
    的头像 发表于 12-10 16:04 906次阅读