S3C2440 开发板实战(5):定时器中断

发布者:HeavenlyJoy444最新更新时间:2022-07-18 来源: csdn关键字:S3C2440  开发板  定时器中断 手机看文章 扫描二维码
随时随地手机看文章

一、定时器大体结构

查看芯片手册,可以找到以下定时器结构框图

从做到右看,对该图进行分析:(不考虑)


Prescaler:定时器0和1共享一个8位分频器,而定时器2、3、4共享另一个8位分频器。分频器将输入的PCLK分频为:PCLK/(prescaler+1)。


Clock divider & MUX:每个定时器有一个时钟分频器,它产生5个不同的分频信号(1/2,1/4,1/8,1/16,和TCLK)。每个定时器块从时钟分频器接收自己的时钟信号,时钟分频器从相应的8位分频器接收时钟。8位分频器是可编程的,根据加载值对PCLK进行划分,存储在TCFG0和TCFG1寄存器中。此时定时器的时钟频率为:Timer input clock Frequency = PCLK / (prescaler+1) / divider value。


Control logic:计数缓冲区寄存器(TCNTBn)有一初始值,当计时器启用时,该初始值将加载到减计数器中。比较缓冲区寄存器(TCMPBn)有一初始值,它被加载到比较寄存器中,以便与减计数器的值进行比较。TCNTBn和TCMPBn的双缓冲特性使定时器在改变频率和占空比时产生稳定的输出。每个定时器有它自己的16位减计数器,由Timer input clock Frequency 进行计数。当减计数器达到0时,产生定时器中断请求,通知CPU定时器中断。当发生中断时,TCNTBn的值自动加载到下一个计数器中,继续下一个操作。其中可以通过在计时器运行模式期间通过清除计时器启用TCONn的位让计时器停止,TCNTBn的值将不会重新加载到计数器中。


TOUTn & Dead Zone Generator:S3C2440有五个16位定时器。定时器0、1、2、3有脉冲宽度调制(PWM)功能。定时器4只有一个没有输出引脚的内部定时器。定时器0有一个死区发生器。

*PS: 


比较缓冲区寄存器(TCMPBn)用于PWM发生使用

计时器重新加载操作是自动发生的,减计数器达到0。

prescaler value = 0~255 ;divider value = 2, 4, 8, 16 

关于死区的内容在之后的博文中讲到(挖坑)

二、定时器中断程序设计

I.初始化定时器中断

这个可以类比外部中断操作(因为同样为irq模式),所以重复寄存器的具体作用在上一篇博客S3C2440 开发板实战(4):外部中断中有提到。


在这里,我们设定终极目标是间隔0.5秒执行一次定时器中断函数。


Setp 1: 打开CPSR中 中断总开关 


mrs    r0,    cpsr

 

bic    r0,    r0,    #0xf    //将模式设置为user模式

bic    r0,    r0,    (1<<7)  //外部中断IRQ打开

 

msr    cpsr,  r0             //user模式

ldr    sp,    =0x33f00000    //设置user的栈(没啥用只是和以后的中断地址做比较)

Step 2: INTERRUPT MASK (INTMSK) REGISTER 


void init_EINT(void)

{

    INTMSK &= ~(1<<10);

    // 按键对应的中断: TIMER  ->对应的位为:10

}


Step 3: 配置定时器中断参数


这里以PCLK=50Mhz为例,对于2440来说时钟的配置很简单,具体的时钟设置请看S3C2440 开发板实战(2):start.S初认识 + SDRAM配置 + 重定位的第二部分。


按照公式:Timer input clock Frequency = PCLK / (prescaler+1) / divider value。我们设置prescaler = 99;divider value = 16。可以计算得到定时器时钟的频率为31250hz。所以若要定时1s,计数器装在初值要为31250。按照这个参数配置,设置定时器寄存器如下:


1. TIMER CONFIGURATION REGISTER0 (TCFG0) 


作用:配置两个8位 prescaler,配置死区长度


Do:将 prescaler0 置为99


2. TIMER CONFIGURATION REGISTER1 (TCFG1) 


作用:5-MUX & DMA模式选择


Do: 将Timer对应的Clock divider配置为16分频


3. TIMER 0 COUNT BUFFER REGISTER(TCNTB0)


作用:设置减计数器的初值


Do: 由终极目标可以看出设定的初值为31250 / 2 =15625


4. TIMER CONTROL (TCON) REGISTER 


作用: 更新减计数器的初值、设置为自动装载、启动、输出逆变器


Do: 先手动更新减计数器的初值,然后设置为自动装载并且启动


* 其中 manual update 这位需要在使用之后清0(下一次写入前清0)


综上可得。定时器初始化配置函数如下所示:


void init_timer(void)

{                       //TCLK = PCLK/(99+1)/16 = 31250

    TCFG0 = 0x63;    //prescaler = 99

    TCFG1 &= ~(0xf<<0);

    TCFG1 |= (3<<0);  //1/16 divider

    TCNTB0 = 15625;   // count 15625 (0.5s)

 

    TCON |= (1<<1);   // updata TCNTB0 to coutor

    TCON &= ~(1<<1);  // CLEAR

    TCON |= ((1<<0) | (1<<3)); // AUTO RELOAD & START

}

II. 中断入口函数

和上一篇中相同,直接上代码!


do_irq:

    /* 执行到这里之前:

     * 1. lr_und保存有被中断模式中的下一条即将执行的指令的地址

     * 2. SPSR_irq保存有被中断模式的CPSR

     * 3. CPSR中的M4-M0被设置为10010, 进入到irq模式

     * 4. 跳到0x18的地方执行程序 

     */

 

    // 1.保护现场

    ldr sp, =0x33d00000

    /* 在irq异常处理函数中有可能会修改r0-r12, 所以先保存 */

    /*  lr-4  是异常处理完后的返回地址, 也要保存 */

    sub lr, lr, #4

    stmdb sp!, {r0-r12, lr}  

 

    // 2.处理中断函数

    bl Find_interrupt_source

 

    /* 3.恢复现场 */

    ldmia sp!, {r0-r12, pc}^  /* ^会把spsr的值恢复到cpsr里 */

III. 设置定时器中断函数

在上一篇中我们设计了一个外部中断的函数模板,所以在这里引用进行延展,所以定时器中断函数


void Find_interrupt_source(void)

{

    puts("begin_interruptnr");

    int bit = INTOFFSET;

    if(bit == 10)

        timer_interrupt_fun();

    /* 清中断 : 从源头开始清 */

    SRCPND = (1<    INTPND = (1<}

 

void timer_interrupt_fun(void)

{

    led_control_NOT(4); 

}

 

void led_control_NOT(int val)

{

    unsigned int val_DATF = GPFDAT;

    if(val_DATF & (1 << val))

        GPFDAT &= ~(1 << val);

    else

        GPFDAT |= (1 << val);

}


运行完就能看见有一个灯在闪烁了,这是我第一次手撸代码解完bug直接实现目标哈哈哈。虽然有了外部中断的程序上修改但是自己动手难道不是兴奋的事情?


关键字:S3C2440  开发板  定时器中断 引用地址:S3C2440 开发板实战(5):定时器中断

上一篇:S3C2440 开发板实战(6):网络配置 + 设置NFS
下一篇:S3C2440 开发板实战(3):编译概念 + LED点亮闪烁

推荐阅读最新更新时间:2024-11-11 19:11

STM8S003定时器1中断服务程序(PWM)中开启定时器2定时计数
STM8S003定时器1中断服务程序(PWM)中开启定时器2定时定时功能,那么在定时器1中断服务程序退出时,立即就产生了定时器2更新中断,但是轴定时器2中断服务程序中(PWM),开启定时器2定时功能,却工作正常,何故? 这是定时器1中断服务程序的开启定时器2的代码: //TIM2_Cmd(DISABLE); TIM2- CR1 &= (uint8_t)(~TIM2_CR1_CEN); //TIM1_Cmd(DISABLE); TIM1- CR1 &= (uint8_t)(~TIM1_CR1_CEN); gsMOTOR.ucPulseCnt = 0;
[单片机]
JZ2440下载程序到开发板的3种方法
1. 使用mount命令进行挂载 ①开发板必须要和虚拟机、电脑在同一个网段内(相互可以ping通) ②将要下载到开发板的程序放到指定目录,这个目录需要在/etc/exports中指定,否则无法被挂载 ②然后在开发板上执行以下命令,要下载的程序就在开发板的/mnt目录里了 mount -t nfs -o nolock,vers=2 192.168.1.100:/design/tools /mnt 2.利用SecureCRT上传、下载文件 ①下载rzsz-3.48.tar.gz: http://download.csdn.net/detail/pcli_218/3347536 ②解压文件包,命令如下 tar zxf rzsz-3
[单片机]
JZ2440下载程序到<font color='red'>开发板</font>的3种方法
单片机定时器与串口中断的问题
{ TMOD |= 0x20; //0011 0000 SCON = 0x50; //0101,0000 TH1 = 0xFA; TL1 = 0xFA; TMOD = 0x01; //应该改成TMOD |= 0x01; TH0 = 0x70; TL0 = 0xc6; ET0=1; ES = 1; // EA = 1; // TR0 = 1; TR1 = 1; // } 如上是串口中断初始化和定时器T0初始化,,,咋一看没有啥问题,, 但注意了,在设置定时器的TMOD时,应使用TMOD |= 0x01,,,否则串口中断是不工作的,,,,这些小问题总是很恼火~~~~~
[单片机]
s3c2440烧写整个系统(及利用Jlink下载u-boot)
s3c2440烧写整个系统 分为两部分 烧写内核文件 烧写文件系统 每一部分分为三个步骤 a. 下载文件到开发板(tftp方式) b. 擦除分区 c. 设置环境变量 d. 烧写 1.烧写内核文件 a. 下载文件到开发板(tftp方式) 进入s3c2440 uboot界面 输入命令下载内核文件 OpenJTAG tftp 30000000 uImage ( 内核文件名根据自己情况而定) b. 擦除分区 OpenJTAG nand erase kernel c. 设置环境变量 OpenJTAG set bootargs noinitrd root=/dev/mtdblock3 init=/l
[单片机]
S3C2440中一些不清楚的概念
UART 通用异步收发器,UART是Universal Asynchronous Receiver/Transmitter的缩写 。UART是用于控制计算机与串行设备的芯片 SPI接口  SPI(Serial Peripheral Interface--串行外设接口)总线系统是一种同步串行外设接口,它可以使MCU与各种外围设备以串行方式进行通信以交换信息 IIC串行总线接口 即I2C,一种总线结构。 IIC 是作为英特尔IC 的互补,这种总线类型是由菲利浦半导体公司在八十年代初设计出来的,主要是用来连接整体电路(ICS) ,IIC是一种多向控制总线,也就是说多个芯片可以连接到同一总线结构下,同时每个芯片都可以作为实施数据传
[单片机]
STM8S的定时器周期中断时钟测试系统
  1 问题   在下面的测试程序中,如果将Init_CLK()函数中的 CLK_CKDIVR |= 0x08;去掉’|‘,则TIM1的功能实现跟预设定相同(10ms中断一次),但是TIM2的PWM频率就变高了;如果加上,则TIM2的功能实现跟预设定相同(产生1Hz的PWM),但是TIM1的周期就变长了;   尝试了很多测试,均无效(买的开发板和另一块gs自画板测试也都一样)。   2 尝试   因为STM8S默认使用内部16M高速RC振荡器,且8分频,则系统启动主时钟为2M。即CLK_CKDIVR = 0X18;,如果再去赋值CLK_CKDIVR |= 0X08; 则主时钟还是不变即0X18,但是如果赋值为CLK_CKD
[单片机]
STM8S的<font color='red'>定时器</font>周期<font color='red'>中断</font>时钟测试系统
OK6410A 开发板 (八) 69 linux-5.11 OK6410A linux 内核同步机制 禁中断/中断屏蔽的实现
解决的问题是什么 中断 抢占 1.实现原理 1/ 禁止 irq与fiq 2/ 禁止 中断源 // 与 vic/gic 等 中断控制器 相关 适用于 某个中断源 中断处理过程中,不能接受 来自该中断源的中断 2.1 禁止 irq与fiq local_irq_enable arch/arm/include/asm/irqflags.h 36 #define arch_local_irq_enable arch_local_irq_enable 37 static inline void arch_local_irq_enable(void) 38
[单片机]
S3C2440内存控制器与SDRAM
1、S3C2440中内存控制器的简单介绍 内存控制器的作用是什么,它有哪些特点? 内存控制器是怎么被CPU使用的? CPU的地址总线是怎么与存储类芯片进行连接的? 1、它的作用与特点如图1,以下是简单的翻译: S3C2440A内存控制器提供外部内存访问所需的内存控制信号。 S3C2440A具有以下特点: -小/大端(可由软件选择)。 -地址空间:每个BANK都有128Mb(总共1GB/8个BANK)。 -除BANK0的可编程总线位宽位(16/32位)外,其他的所有BANK的可编程总线位宽位有三种(8/16/32位)。 -总共8个BANK: BANK0 ~ BANK5 用于ROM、SRAM等。 BANK6 ~ BANK7 可
[单片机]
<font color='red'>S3C2440</font>内存控制器与SDRAM
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved