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
    +关注

    关注

    237

    文章

    22621

    浏览量

    647462
  • Linux
    +关注

    关注

    87

    文章

    11030

    浏览量

    207266
  • 函数
    +关注

    关注

    3

    文章

    4142

    浏览量

    61553

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

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

收藏 人收藏

    评论

    相关推荐

    【Vision Board创客营连载体验】利用 OpenMV 实现 AprilTag 跟踪以及通过串口通讯控制 Arduino 驱动 LED

    作为下位机接收坐标信息并将信息转化为 LED 矩阵坐标,再通过 FastLED 库实现对 WS2812b 带的 LED 操控。 开发现况 由于手头上的 WS2812b
    发表于 05-31 00:01

    请问STM32L4如何利用STM32CubeMX实现EXTI控制LED?

    STM32L4利用STM32CubeMX如何实现EXTI控制LED?
    发表于 04-09 08:07

    求购两个LED呼吸控制

    某宝某多买了几个控制器发现LED的亮度变化在低占空比的时候,变化很明显,而在高占空比的时候反而变化很小,导致呼吸表现呼吸不均匀的现象,我想要的是控制器能做到
    发表于 01-31 21:54

    ADUC7061如何使用C语言实现EEPROM功能?

    我使用ADUC7061做的信号采集,现在客户需要实现EEPROM功能来保存3-5个数据,请问如何使用C语言实现?不使用外部EEPROM 专用IC。
    发表于 01-12 06:56

    幻彩LED带芯片:SM16703SP单点单控 断点续传

    幻彩LED带芯片SM16703SP3是一款单点单控断点续传的芯片,它采用了先进的技术,可以实现灯光的变化和控制。这款芯片不仅仅可以提供各种丰富多彩的灯光效果,还有断点续传功能,
    发表于 12-18 14:45

    利用onenet平台远程控制开发板的LED

    电子发烧友网站提供《利用onenet平台远程控制开发板的LED 灯.pdf》资料免费下载
    发表于 10-20 11:33 0次下载
    <b class='flag-5'>利用</b>onenet平台远程<b class='flag-5'>控制</b>开发板的<b class='flag-5'>LED</b> 灯

    太阳能LED如何实现节能和低功耗?

    用单片机控制LED组循环显示,用了一个星期就没电了,加上太阳能板能到两个星期,该如何实现节能和低功耗勒?
    发表于 10-19 06:29

    国产教学实验箱_操作教程:2-2 LED控制实验

    StarterWare开发环境下的LED控制。 二、实验原理 1、StarterWare StarterWare是一个免费的软件开发包,为ARM和DSP TI处理器提供OS平台(无操作系统平台)支持。包括设备抽象层
    发表于 10-08 14:12

    经典C语言接口与实现:创建可重用软件的技术

    C语言接口与实现(创建可重用软件的技术)概念清晰、内容新颖、实例详尽,是一本有关设计、实现和有效使用C
    发表于 09-25 06:42

    STM8 C语言精品编程100例

    本文档的主要内容详细介绍的是STM8C语言精品编程100例的PDF电子书免费下载。实例说明本例要实现三个LED同时闪烁,实现1秒钟闪亮,1秒
    发表于 09-21 07:01

    利用单片机实现数码管显示4乘4键盘矩阵按键的C语言程序

    使用单片机实现数码管显示4乘4键盘矩阵按键的C语言程序
    发表于 09-20 08:29

    OpenHarmony:如何使用HDF驱动控制LED

    开发 GPIO应用程序开发 2、硬件设计RGB LED整体硬件电路如下图所示,硬件电路中包含了三个GPIO控制管脚控制RGB LED
    发表于 09-05 14:10

    怎么采用C语言编程序通过单片机的I/O端口点亮一个LED灯?

    怎么采用C语言编程序通过单片机的I/O端口点亮一个LED灯?  C语言是一门非常重要的编程语言,被广泛应用于各种领域。在单片机领域,C语言
    的头像 发表于 09-02 17:05 2957次阅读

    【紫光同创国产FPGA教程】【PGC1/2KG第二章】LED 流水灯实验例程

    流水灯 三:实验要求 流水灯:8 个 LED 以 0.5s 间隔接替闪烁 四:实验原理 相比上一个 LED 闪烁的实现,只需要改变 LED 的状态。将 8 个
    发表于 08-09 11:58

    ARM C语言扩展规范

    ARM C语言扩展(ACLE)规范指定源语言扩展和实现C/C++编译器可以
    发表于 08-02 06:27