之前也学习过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<<(4*3)); //1111 1111 0000 0000 0000
var |= (0x11<<(4*3)); //0001 0001 0000 0000 0000
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
上一篇:TQ210的裸机编程(一)点亮一个LED灯
下一篇:TQ210裸机编程(5)——系统时钟配置
推荐阅读最新更新时间:2024-10-29 15:59
设计资源 培训 开发板 精华推荐
- NCP114MXTCGEVB:CMOS 低压差稳压器,300 mA,3.3V,有源放电评估板
- LT1513 的典型应用 - SEPIC 恒流或可编程电流/恒压电池充电器
- TB6600步进电机驱动验证板
- LT1074,正负转换器
- AM1G-2418SZ 18V 1 瓦 DC-DC 转换器的典型应用
- DC2152A,用于 LTM4630A 双路 18A 或单路 36A 模块稳压器的演示板
- 具有 I2C 接口的 LTC2627CDE-1 双通道、12 位轨至轨 DAC 的典型应用
- 基于ACEPACK 2电源模块的工业驱动系统套件
- 基于STC15F104的遥控调光灯
- L7806C负输出电压电路的典型应用