Chinaunix首页 | 论坛 | 博客
  • 博客访问: 153886
  • 博文数量: 72
  • 博客积分: 3680
  • 博客等级: 中校
  • 技术积分: 1051
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-22 13:51
文章分类
文章存档

2010年(72)

我的朋友

分类: 嵌入式

2010-10-18 09:19:58

上篇I/O控制文章中,程序需要延时时,我们是利用循环语句来实现。这种方法的延时简单,但不是很精确。当需要精确延时时,就不能采用这种方法了。一般是利用定时器来实现。在这里,我们就介绍一下s3c2440定时器。

S3C2440时钟
    在讲解之前,先介绍一下s3c2440时钟系统。一般来说,MCU的主时钟源主要是外部晶振或外部时钟,而用的最多的是外部晶振。在正确情况下,系统内所使用的时钟都是外部时钟源经过一定的处理得到的。由于外部时钟源的频率一般不能满足系统所需要的高频条件,所以往往需要PLL(锁相环)进行倍频处理。在s3c2440中,有2个不同的PLL,一个是MPLL,另一个是UPLL。
    UPLL是给USB提供48MHz。在这里,我们主要介绍MPLL。外部时钟源经过MPLL处理后能够得到三个不同的系统时钟:FCLK、HCLK和PCLK。
    FCLK是主频时钟,用于ARM920T内核;
    HCLK用于AHB总线设备,如ARM920T,内存控制,中断控制,LCD控制,DMA以及USB主模块;
    PCLK用于APB总线设备,如外围设备的看门狗,IIS,I2C,PWM,MMC接口,ADC,UART,GPIO,RTC以及SPI。
    这三个系统时钟(FCLK、HCLK和PCLK)是有一定的比例关系,这种关系是通过寄存器CLKDIVN中的HDIVN位和PDIVN位来控制的,因此我们只要知道了FCLK,再通过这两位的控制,就能确定HCLK和PCLK。
    而FCLK是如何得到的呢?它是通过输入时钟(即外部时钟源)的频率,经过一个计算公式(具体公式请查阅数据手册)得到的,这个计算公式还需要三个参数(MDIV、PDIV、SDIV),而这三个参数是经过寄存器MPLLCON配置得到的。
    最后,我们用最清晰的线路来绘制一下时钟的产生过程:
    外部时钟源通过寄存器MPLLCON得到FCLK再通过寄存器CLKDIVN得到HCLK和PCLK。
    这个配置过程在启动文件中就已完成。例如,外部晶振为12MHz,进过MPLL倍频以后得到400MHz的FCLK,而FCLK、HCLK、PCLK之间的比例关系为1:4:8,因此HCLK为100MHz,PCLK为50MHz。

► S3C2440的定时器特性
    S3C2440有5个16位的定时器,定时器0~3有脉宽调制功能(PWM)。定时器4没有输出引脚的内部定时器。定时器0有一个用于大电流设备的死区生成器。S3C2440定时器0和1共享一个8位的预分频器,定时器2、3、4共享另一个8位预分频器。每个定时器有一个时钟分频器,其中以生成5种不同的分频信号。
    每个定时器有一个自己的由定时器时钟驱动16位递减计数器,当递减计数器为零时,定时器中断请求生成通知CPU定时器操作完成。
    S3C2440定时器特性如下:
    5个16位定时器
    两个8位预分频器和2个4位分频器
    输出波形的可编程任务控制
    自动重载模式或单脉冲模式
    死区生成器

► S3C2440的定时器寄存器
    S3C2440定时器:
    ● 定时器配置寄存器(TCFGn);
    ● 定时器控制寄存器(TCON);
    ● 定时器n计数缓存寄存器(TCNTBn),定时器n比较缓存寄存器(TCMPBn);
    ● 定时器计数观察计数器。
    定时器寄存器具体说明请查阅S3C2440芯片手册。

    定时器配置寄存器(TCFGn)
    定时器配置寄存器用于配置两个8位预分频器值,该寄存器复位值为0,定时器输出时钟频率计算如下:
    定时器输出时钟频率 = PCLK / (预分频器值+1) / 分频值

    ● TCFG0配置寄存器:[0-7]配置定时器0,1的预分频值;[8-15]配置定时器2,3,4的预分频值。
    ● TCFG1配置寄存器:[0-3]配置定时器0分频值;[4-7]配置定时器1分频值;[8-11]配置定时器2分频值;[12-15]配置定时器3分频值;[16-149]配置定时器4分频值;

    定时器控制寄存器(TCON)
    TCON寄存器用于控制定时器0~4,寄存器复位值为0。

TCON寄存器 描述
0~3 控制定时器0:使能[0]、手动更新[1]、匹配输出[2]、自动重载[3]
4 死区使能
8~11 控制定时器1:使能[8]、手动更新[9]、匹配输出[10]、自动重载[11]
12~15 控制定时器2:使能[12]、手动更新[13]、匹配输出[14]、自动重载[15]
1516~19 控制定时器3:使能[16]、手动更新[17]、匹配输出[18]、自动重载19]
20~22 控制定时器4:使能[20]、手动更新[21]、自动重载[23]



    定时器n计数缓存寄存器(TCNTBn),定时器n比较缓存寄存器(TCMPBn)
    定时器计数与比较缓存寄存器用于缓存用户所给的定时值,当配置TCON寄存器定时器n使能“手动更新”时,该值将在下一个定时启动时装载到TCMPn与TCNTn中,重新进行定时。例如,定时器0内部结构如图所示:

    TCMP0与TCNT0不能直接对其操作。

    定时器计数观察计数器(TCNTOn)
    定时器计数观察计数器保存定时器计数器值(只读)。

► S3C2440定时器操作
    定时器启动后,TCNTn开始减一计数,当TCNTn 等于TCMPn时,TOUTn 反转,TCNTn继续减数。当TCNTn= 0 时,TOUTn 再次反转,并触发中断(中断已经使能)。若TCON 设为自动加载,TNCTn/TCMPNn 的值被重装。

    图中步骤如下:
    1、使能自动重载功能。设置TCNTBn为160,TCMPBn为110。设置手动更新位且配置反相器位(开/关)。手动更行位将TCNTBn和TCMPBn的值分别给TCNTn和TCMPn寄存器,然后设置TCNTBn=80和TCMPBn=40,决定下一个重载值;
    2、设置开始位,手动更新位为0,手动更新关闭且自动重载开启,定时器开始倒数计数;
    3、当TCNTn的值和TCMPn的值相同,TOUTn的逻辑电平从低变高;
    4、当TCNTn为0,中断请求生成且TCNTBn的值装载到一个临时寄存器中。在下一个定时器周期,TCNTn会用该临时寄存器的值重载;
    5、在中断服务程序中,TCNTBn和TCMPBn为下一个周期分别设置为80和60;
    6、当TCNTn的值和TCMPn的值相同,TOUTn的逻辑电平从低变高;
    7、当TCNTn为0,TCNTn用TCNTBn的值自动重载,并触发中断请求;
    8、在中断服务程序中,自动重载和自动请求被设无效以停止定时器;
    10、就算TCNTn为0,因为自动重载被设为无效,TCNTn不再重载且定时器停止;
    11、没有其他的自动请求生成。

► S3C2440定时器初始化
    以定时器0为例,启动定时器操作步骤大致如下:
    1、设置TCMPB0和TCNTB0寄存器;
    2、设置TCON寄存器,计数值进行装载;
    3、启动定时器;
    4、计数器重新被装载。
  1. void Timer0_init()
  2. {
  3.         TCFG0 = 119;                        //配置定时器0,1的预分频值
  4.         TCFG1 = 0x03;                        //配置定时器0分频值
  5.         TCNTB0 = 3125;                        //计数缓存寄存器
  6.         TCMPB0 = 0;                        //比较缓存寄存器
  7.         TCON |= (1<<1);                        //手动更新位且配置反相器位(开/关)(手动更行位将TCNTBn和TCMPBn的值分别给TCNTn和TCMPn寄存器)
  8.         TCON = 0x09;                        //定时器使能并自动重载
  9. }
复制代码
► 定时器报警实验
    实验设备
    硬件:        PC机                                        一台
    YX-AIO嵌入式综合创新设计平台                        一台
    ARM9核心板                                        一块
    软件:        Windows操作系统,ADS1.2集成开发环境,H-JTAG下载环境

    实验内容
    使用定时器延时方式控制YX-AIO嵌入式综合创新设计平台上的蜂鸣器报警。

    实验步骤
    ① 在ADS开发环境中使用ARM9_S3C2440工程模版创建一个工程,并将程序代码添加到该工程;
    ② 在ADS开发环境中编译链接并生成目标文件;
    ③ 将JTAG下载器连接YX-AIO嵌入式综合创新设计平台,并将该平台通电;
    ④ 开启H-JTAG软件检测处理器与NOR-Flash;
    ⑤ 使用H-JTAG软件将目标文件(.bin)下载到YX-AIO嵌入式综合创新设计平台上;
    ⑥ 复位平台。

    源代码:
  1. /********************************************************************
  2. ** 名称:DelayS()
  3. ** 功能:软件延时
  4. ** 入口参数:dly                延时参数(s)
  5. ********************************************************************/
  6. void  DelayMS(U32  dly)
  7. {
  8.         U32        time_val;

  9.         rTCFG0 = 3;                        //配置定时器0,1的预分频值
  10.         rTCFG1 = 0<<4;                  //配置定时器1分频值

  11.         time_val = PCLK/ (3+1) / 2 / 1000 - 1;     // 1ms = PCLK / prescaler / divider / 1000
  12.         
  13.         rTCNTB1 = time_val;            //计数缓存寄存器
  14.         rTCMPB1 = time_val>>1;      // 50%
  15.         
  16.         rTCON &= ~(0xf<<8);          //手动更新位且配置反相器位(开/关)
  17.         rTCON |= 0xb<<8;              //定时器使能并自动重载
  18.         rTCON &= ~(2<<8);             //clear manual update bit
  19.         
  20.         while(dly--)
  21.         {
  22.                 while(rTCNTO1>=time_val>>1);
  23.                 while(rTCNTO1>1);
  24.         }
  25. }
  26. /********************************************************************
  27. ** 文件名:main()
  28. ** 文件名:                        main.c
  29. ** 修改时间:                        2009-6-1
  30. ** 描述:
  31. ********************************************************************/
  32. void Main(void)
  33. {
  34.         //----------------添加自己的代码-------------------
  35.         rGPACON &= ~(1<<16);
  36.         
  37.         while (1)
  38.         {
  39.                 rGPADAT |= (1<<16);
  40.                 DelayMS(1000);
  41.                 rGPADAT &= ~(1<<16);
  42.                 DelayMS(500);
  43.         }
  44. }
阅读(1279) | 评论(0) | 转发(0) |
0

上一篇:I/O口控制

下一篇:中断

给主人留下些什么吧!~~