×
单片机 > 单片机程序设计 > 详情

TQ210天嵌开发板S5PV210 LED闪烁程序C语言代码记录

发布时间:2021-09-14 发布时间:
|

之前也学习过LDE闪烁程序,一般通过如下方式实现:


主要思想是通过操作寄存器地址的方式操作寄存器,这种实现方式的优点就是简单容易理解,但是具有一定的局限性,一般在较大的工程中不会这样实现,因为通过直接操作地址的方式实现,必定会频繁查询数据手册,查询相应寄存器地址,还有就是程序中会出现大量地址,可读性差不利于程序移植和优化。


通过学习,了解了一种通用的程序设计方式,特此记录


先说下大概思想:


1)引入GPIO基地址概念,建立GPIO结构体,这样每一个GPIO都可以通过”基地址+偏移地址“的思想查找到,避免了频繁操作地址的弊端。

2)位操作思想,不能为了实现某一个功能,影响其他功能,因此位操作的实现方式成为了程序设计中优先考虑的因素。


下面说下具体细节实现:


主要步骤如下(此处针对我使用的开发板TQ210,具体实现是一样的):

1.通过查询开发板原理图得到两个LED的引脚分别为: GPC0_3、GPC0_4

2.查询GPIO的基地址为:0xE0200000

3.设置功能寄存器GPC0CON为输出 :因为输出为0001=Output

4.则32位的2进制值为:xxxx xxxx xxxx 0001 0001 xxxx xxxx xxxx

5.设置完模式为输出:仍需设置到底是低电平输出,还是高电平输出。

6.设置组控制器:GPC0DAT 为高点亮LED


则32位的2进制值为:xxxx xxxx xxxx 0001 0001 xxxx xxxx xxxx

设置组控制器:GPC0DAT 为低熄灭LED

则32位的2进制值为:xxxx xxxx xxxx 0000 0000 xxxx xxxx xxxx

(x代表未知,即保留其原有的状态)


具体程序分为以下几个程序:

1.start.S汇编文件 主要功能跳到C语言main函数

2.main.c 主程序 调用 led相关程序 延时程序等

3.map.lds 链接脚本文件 控制程序文件顺序

4.Makefie文件

5.led.c led.h LED相关设置

6.cpu_io.h 地址赋值等相关操作

7.gpio.h gpio结构体等


具体程序代码如下:


start.S


.global _start

.global main


_start :

bl main

loop:

b loop

.end


main.c


//main.c

#include "led.h"

#include "cpu_io.h"


static void mydelay()

{

volatile unsigned int i=0xfffff;

while(i--);


}

void led_test()

{


led_init();

while(1)

{

led_blink(1);

mydelay();

led_blink(0);

mydelay();

}

}


int main()

{

led_test();

return 0;

}


led.c


#include "gpio.h"

#include "led.h"

#include "cpu_io.h"


void led_init(void)

{

struct s5pv210_gpio *gpio_base=(struct s5pv210_gpio *) S5PV210_GPIO_BASE;

unsigned int var;

var =_REG(&gpio_base->gpio_c0.con);

var &=~(0xFF<

var |= (0x11<

writel(var,&gpio_base->gpio_c0.con); //11000

}


void led_blink(int status)

{

struct s5pv210_gpio *gpio_base=(struct s5pv210_gpio *) S5PV210_GPIO_BASE;

unsigned int var ;

if(status)

{

var = _REG(&gpio_base->gpio_c0.dat);

var &=~0x18; //00011000

writel(var,&gpio_base->gpio_c0.dat);

}

else

{

var = _REG(&gpio_base->gpio_c0.dat);

var |=0x18;

writel(var,&gpio_base->gpio_c0.dat);

}


}


map.lds


OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm","elf32-littlearm")

OUTPUT_ARCH(arm)

ENTRY(_start)

SECTIONS

{

. =0x0;

. =ALIGN(4);

.text :

{

start.o

*(.text)

}

. =ALIGN(4);

.rodata :

{

*(.rodata)

}

. =ALIGN(4);

.data :

{

*(.data)

}

. =ALIGN(4);

.bss :

{

*(.bss)

}

}


led.h


#ifndef LED_H

#define LED_H

void led_init(void);

void led_blink(int status);

#endif



gpio.h


#ifndef _ASM_ARCH_GPIO_H

#define _ASM_ARCH_GPIO_H


struct s5pc1xx_gpio_bank{

unsigned int con;

unsigned int dat;

unsigned int pull;

unsigned int drv;

unsigned int pdn_con;

unsigned int pdn_pull;

unsigned char res1[8];

};

struct s5pv210_gpio{

struct s5pc1xx_gpio_bank gpio_a0;

struct s5pc1xx_gpio_bank gpio_a1;

struct s5pc1xx_gpio_bank gpio_b;

struct s5pc1xx_gpio_bank gpio_c0;

struct s5pc1xx_gpio_bank gpio_c1;

struct s5pc1xx_gpio_bank gpio_d0;

struct s5pc1xx_gpio_bank gpio_d1;

struct s5pc1xx_gpio_bank gpio_e0;

struct s5pc1xx_gpio_bank gpio_e1;

struct s5pc1xx_gpio_bank gpio_f0;

struct s5pc1xx_gpio_bank gpio_f1;

struct s5pc1xx_gpio_bank gpio_f2;

struct s5pc1xx_gpio_bank gpio_f3;

struct s5pc1xx_gpio_bank gpio_g0;

struct s5pc1xx_gpio_bank gpio_g1;

struct s5pc1xx_gpio_bank gpio_g2;

struct s5pc1xx_gpio_bank gpio_g3;

struct s5pc1xx_gpio_bank gpio_i;

struct s5pc1xx_gpio_bank gpio_j0;

struct s5pc1xx_gpio_bank gpio_j1;

struct s5pc1xx_gpio_bank gpio_j2;

struct s5pc1xx_gpio_bank gpio_j3;

struct s5pc1xx_gpio_bank gpio_j4;

};

#define S5PV210_GPIO_BASE (0xE0200000)

#endif


cpu_io.h


#ifndef _S5PV210_CPU_H

#define _S5PV210_CPU_H



#define _REG(x) (*(volatile unsigned int *)(x))


#define readb(a) (*(volatile unsigned char *)(a))

#define readw(a) (*(volatile unsigned short *)(a))

#define readl(a) (*(volatile unsigned int *)(a))



#define writeb(v, a) (*(volatile unsigned char *)(a) = v)

#define writew(v, a) (*(volatile unsigned short *)(a) = v)

#define writel(v, a) (*(volatile unsigned int *)(a) = v)


#endif



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
用Atmega 16单片机驱动字符型液晶显示芯片