前言

在Cubieboard2裸机开发之(三)里用到了一个延时函数delay,它的延时时间是不精确的,因此为了能够精确延时,就需要定时器的配合。定时器可以精确延时的一个重要原因是它的计时时钟(或者说频率)是精确的,计时时钟越小,能实现的延时时间就越小。

A20的定时器模块比较强大,它不仅有6个普通的定时器,还有4个高速定时器,计时频率可达上百MHz,更重要的是它们操作起来非常简单、易懂。

一、目的

学习使用A20的普通定时器,实现精确延时。

二、源代码说明

start.S文件。首先禁止CPU的IRQ和FIQ,设置为管理模式,然后设置堆栈指针,最后调用C语言的main函数。

 /*
* (C) Copyright conan liang <lknlfy@163.com>
*
*/ /* global entry point */
.globl _start
_start: b reset reset:
/* disable IRQ & FIQ, set the cpu to SVC32 mode */
mrs r0, cpsr
and r1, r0, #0x1f
teq r1, #0x1a
bicne r0, r0, #0x1f
orrne r0, r0, #0x13
orr r0, r0, #0xc0
msr cpsr, r0
/* setup stack, so we can call C code */
ldr sp, =( * )
/* jump to main function */
bl main
loop:
b loop

main.c文件。首先初始化LED所在IO管脚,设置为输出功能,并且输出低电平,即一开始两个LED是熄灭的,接着初始化定时器0,包括设置它的时钟,工作模式等。

 #include "timer.h"
#include "io.h" /* reg define for IO of LEDs */
#define SUNXI_PIO_BASE (0x01C20800)
#define PH_CFG2 (SUNXI_PIO_BASE + 0x104)
#define PH_DAT (SUNXI_PIO_BASE + 0x10C) /* set two LEDs on */
static void set_led_on(void)
{
unsigned int tmp; /* PH20 and PH21 output 1 */
tmp = readl(PH_DAT);
tmp |= (0x1 << );
tmp |= (0x1 << );
writel(tmp, PH_DAT);
} /* set two LEDs off */
static void set_led_off(void)
{
unsigned int tmp; /* PH20 and PH21 output 0 */
tmp = readl(PH_DAT);
tmp &= ~(0x1 << );
tmp &= ~(0x1 << );
writel(tmp, PH_DAT);
} static void led_init(void)
{
unsigned int tmp; /* configure PH20 and PH21 output */
tmp = readl(PH_CFG2);
tmp &= ~(0x7 << );
tmp &= ~(0x7 << );
tmp |= (0x1 << );
tmp |= (0x1 << );
writel(tmp, PH_CFG2);
/* set PH20 and PH21 output 0 */
tmp = readl(PH_DAT);
tmp &= ~(0x1 << );
tmp &= ~(0x1 << );
writel(tmp, PH_DAT);
} /* C code entry point */
int main(void)
{
/* init led */
led_init();
/* init timer0 */
sunxi_timer0_init(); while () {
set_led_on();
udelay();
set_led_off();
udelay();
} return ;
}

timer.c文件。一个初始化函数,一个微妙延时函数,这里设置定时器的计时频率为6MHz。

 #include "timer.h"
#include "io.h" /* 6MHz for timer0 count freq*/
#define TIMER0_HZ (6000000) #if 0
static void sunxi_timer0_start(void)
{
unsigned int tmp; tmp = readl(TMR0_CTRL_REG);
tmp |= ( << TMR0_EN);
writel(tmp, TMR0_CTRL_REG);
} static void sunxi_timer0_stop(void)
{
unsigned int tmp; tmp = readl(TMR0_CTRL_REG);
tmp &= ~( << TMR0_EN);
writel(tmp, TMR0_CTRL_REG);
}
#endif /* accurate delay */
void udelay(unsigned int usec)
{
unsigned int count;
unsigned int tmp; /* write interval value */
count = (TIMER0_HZ / ) * ((unsigned int)usec);
writel(count, TMR0_INTV_VALUE_REG); /* reload and start timer0 must be operated at the same time */
tmp = readl(TMR0_CTRL_REG);
tmp |= ( << TMR0_RELOAD);
tmp |= ( << TMR0_EN);
writel(tmp, TMR0_CTRL_REG);
/* wait for interrupt */
while (!(readl(TMR_IRQ_STA_REG) & ( << TMR0_IRQ_PEND)));
/* clear timer0 interrupt */
tmp = readl(TMR_IRQ_STA_REG);
tmp |= ( << TMR0_IRQ_PEND);
writel(tmp, TMR_IRQ_STA_REG);
} void sunxi_timer0_init(void)
{
unsigned int tmp; /* single mode, /4 divide, clock source is OSC24M, reload . so clk_freq = 24M / 4 = 6M*/
tmp = (0x1 << TMR0_MODE) | (0x2 << TMR0_CLK_PRES) | (0x1 << TMR0_CLK_SRC) | (0x1 << TMR0_RELOAD);
writel(tmp, TMR0_CTRL_REG);
/* clear timer0 interrupt */
tmp = readl(TMR_IRQ_STA_REG);
tmp |= ( << TMR0_IRQ_PEND);
writel(tmp, TMR_IRQ_STA_REG);
/* enable timer0 interrupt */
tmp = readl(TMR_IRQ_EN_REG);
tmp |= ( << TMR0_IRQ_EN);
writel(tmp, TMR_IRQ_EN_REG);
}

三、验证

使用arm-linux-gnueabihf工具编译后生成timer.b文件,再使用mksunxiboot工具在timer.b文件前面加上一个头部,最终生成timer.bin文件,使用以下命令将timer.bin文件烧写到TF中:

#sudo dd if=./timer.bin of=/dev/sdb bs=1024 seek=8

将TF卡插入Cubieboard2,上电即可看到两个LED同时闪烁,并且闪烁周期为2秒(亮1秒,灭1秒),效果不好用图片展示,因此就不上图了。

Cubieboard2裸机开发之(四)定时器操作的更多相关文章

  1. Cubieboard2裸机开发之(五)看门狗操作

    前言 说到看门狗,应该不会陌生,看门狗说白了就是一个定时器,但是它有一个非常重要的功能就是复位系统.在A20里,看门狗的操作非常简单,只有两个寄存器,不需要操作时钟相关的东西,系统起来后可以直接使用, ...

  2. Cubieboard2裸机开发之(三)C语言操作LED

    前言 前面通过汇编语言点亮LED,代码虽然简单,但并不是很直观.这次使用熟悉的C语言来控制LED,但是需要注意的地方有两点,第一,要想使用C语言,首先需要在调用C语言代码之前设置好堆栈:第二,调用C语 ...

  3. Cubieboard2裸机开发之(二)板载LED交替闪烁

    前言 电路原理在文章http://www.cnblogs.com/lknlfy/p/3583806.html中已经说明,两个LED的原理图是一样的.要使两个LED交替闪烁,只需要在点亮蓝色LED,熄灭 ...

  4. Cubieboard2裸机开发之(一)点亮板载LED

    前言 CUbieboard2板载两个LED,一个绿色的,一个蓝色的,其中绿色LED通过三极管与PH20管脚连接,蓝色LED通过三极管与PH21管脚连接,这里只以蓝色LED为例,电路原理图如图1和图2所 ...

  5. S5PV210开发系列四_uCGUI的移植

    S5PV210开发系列四 uCGUI的移植 象棋小子          1048272975 GUI(图形用户界面)极大地方便了非专业用户的使用,用户无需记忆大量的命令,取而代之的是能够通过窗体.菜单 ...

  6. S3C2440—3.用点亮LED来熟悉裸机开发的详细流程

    文章目录 一.硬件知识 1.LED原理图 2.芯片手册 Ⅰ.找LED原理图 Ⅱ.找对应引脚 Ⅲ.在芯片手册中查找引脚信息 Ⅳ.查看寄存器说明 Ⅴ.配置寄存器 二.S3C2440框架与启动过程 三.要用 ...

  7. MS CRM 2011的自定义和开发(11)——插件(plugin)开发(四)

    http://www.cnblogs.com/StoneGarden/archive/2012/02/08/2343294.html MS CRM 2011的自定义和开发(11)——插件(plugin ...

  8. S3C2416裸机开发系列十六_sd卡驱动实现

    S3C2416裸机开发系列十六 sd卡驱动实现 象棋小子    1048272975 SD卡(Secure Digital Memory Card)具有体积小.容量大.传输数据快.可插拔.安全性好等长 ...

  9. Lucene.Net 2.3.1开发介绍 —— 四、搜索(一)

    原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(一) 既然是内容筛选,或者说是搜索引擎,有索引,必然要有搜索.搜索虽然与索引有关,那也只是与索引后的文件有关,和索引的程序是无关的,因此 ...

随机推荐

  1. 给“.Net工资低”争论一个了结吧!

    昨天我写了一篇<工资低的.Net程序员,活该你工资低>,底下的支持.争吵.骂娘的评论依旧像之前几篇园友的博客一样繁荣.公说公有理,婆说婆有理,这样争吵下去永远没有尽头.数据没有情绪,是公正 ...

  2. MySQL5.6 报错1067

    http://www.cnblogs.com/lixiaolun/p/5303687.html

  3. 使用七牛云存储实现Android的自动更新

    为了修复Bug或更新软件,我们通常需要实现自动更新,没有哪一个牛逼的人能够搞到每一个用户的机子去帮他们更新. 1.自动更新的流程 我们将了解一下自动更新的思路.既然软件要自动更新,那么它必须知道自己是 ...

  4. js里各浏览器解析XML,支持IE、火狐、Chrome等

    js在chrome中加载XML,js加载XML支持ff,IE6+,Opera等浏览器 见代码: <!doctype html> <html lang="en"&g ...

  5. GCD中的dispatch_sync、dispatch_sync 分别与串行、并行队列组合执行小实验

    平常开发中会经常用gcd做一下多线程任务,但一直没有对同步.异步任务在串行.并行队列的执行情况做个全面的认识,今天写了个demo跑了下,还是有些新发现的. 代码如下: - (void)touchesB ...

  6. Web调试工具——Fiddler介绍

    Fiddler 教程 Fiddler是最强大最好用的Web调试工具之一,它能记录所有客户端和服务器的http和https请求,允许你监视,设置断点,甚至修改输入输出数据. 使用Fiddler无论对开发 ...

  7. atititt.java定时任务框架选型Spring Quartz 注解总结

    atititt.java定时任务框架选型Spring Quartz 总结 1. .Spring Quartz  (ati recomm) 1 2. Spring Quartz具体配置 2 2.1. 增 ...

  8. Maven学习总结(八)——使用Maven构建多模块项目

    在平时的Javaweb项目开发中为了便于后期的维护,我们一般会进行分层开发,最常见的就是分为domain(域模型层).dao(数据库访问层).service(业务逻辑层).web(表现层),这样分层之 ...

  9. python None与Null

    一.Python对象 要理解这个,首先要理解Python对象: python对象具有三个特性:身份.类型.值. 三特性在对象创建时被赋值.只有值可以改变,其他只读. 类型本身也是对象. 二.Null与 ...

  10. Windows 8.1 with update 官方最新镜像汇总

    Windows 8.1 with update 官方最新镜像汇总,发布日期: 2014/12/16,Microsoft MSDN. 镜像更新日志: 12/29:32位大客户专业版中文版 12/24:6 ...