i.MX6ULL终结者GPT定时器延时例程程序设计

本实验的源码工程在开发板光盘资料的:i.MX6UL终结者光盘资料\04_裸机例程源码\11_gpt_delay 目录下。我们在Ubuntu系统下使用命令“mkdir 11_gpt_delay”建立“11_gpt_delay”文件夹,如图 1所示:
在这里插入图片描述

图 1

然后使用“cd 11_gpt_delay”命令进入到11_gpt_delay文件夹,如图 2所示:
在这里插入图片描述

图 2

然后使用命令“cp -r …/10_key_filter/* ./”将上一章试验中的所有内容拷贝到刚刚新建的“11_gpt_delay”里面,如图 3所示:
在这里插入图片描述

图 3

然后我们只需要修改“drivers/delay”目录下的delay.h和delay.c,两个文件,首先我们打开“drivers/delay/delay.h”文件,在里面输入下面的内容:

  1 #ifndef __BSP_DELAY_H
  2 #define __BSP_DELAY_H
  3 
  4 #include "imx6ul.h"
  5 
  6 
  7 /* 函数声明 */
  8 void delay_init(void);
  9 void delayus(unsigned    int usdelay);
 10 void delayms(unsigned    int msdelay);
 11 void delay(volatile unsigned int n);
 12 void gpt1_irqhandler(void);
 13 
 14 #endif

我们可以看到在delay.h里面主要添加了几个函数的声明,然后我们打开“deivers/delay/delay.c”文件,在里面输入下面的内容:

  1 #include "delay.h"
  2 
  3 /*
  4  * @description : 延时有关硬件初始化,主要是GPT定时器
  5                 GPT定时器时钟源选择ipg_clk=66Mhz
  6  * @param               : 无
  7  * @return              : 无
  8  */
  9 void delay_init(void)
 10 {
    
    
 11         GPT1->CR = 0;      /* 清零,bit0也为0,即停止GPT                   */
 12 
 13         GPT1->CR = 1 << 15; /* bit15置1进入软复位                           */
 14 while((GPT1->CR>>15)&0x01);/* 等待复位完成  */
 15 
 16         /*
 17          * GPT的CR寄存器,GPT通用设置
 18          * bit22:20     000 输出比较1的输出功能关闭,也就是对应的引脚没反应
 19      * bit9:    0   Restart模式,当CNT等于OCR1的时候就产生中断
 20      * bit8:6   001 GPT时钟源选择ipg_clk=66Mhz
 21      * bit
 22          */
 23         GPT1->CR = (1<<6);
 24 
 25         /*
 26      * GPT的PR寄存器,GPT的分频设置
 27      * bit11:0  设置分频值,设置为0表示1分频,
 28      *          以此类推,最大可以设置为0XFFF,也就是最大4096分频
 29          */
 30         GPT1->PR = 65;  /* 设置为65,GPT1时钟为66M/(65+1)=1MHz */
 31 
 32          /*
 33       * GPT的OCR1寄存器,GPT的输出比较1比较计数值,
 34       * GPT的时钟为1Mz,那么计数器每计一个值就是就是1us。
 35       * 为了实现较大的计数,我们将比较值设置为最大的0XFFFFFFFF,
 36       * 这样一次计满就是:0XFFFFFFFFus = 4294967296us = 4295s = 71.5min
 37       * 也就是说一次计满最多71.5分钟,存在溢出
 38           */
 39         GPT1->OCR[0] = 0XFFFFFFFF;
 40 
 41         GPT1->CR |= 1<<0;    //使能GPT1
 42 
 43         /* 一下屏蔽的代码是GPT定时器中断代码,
 44          * 如果想学习GPT定时器的话可以参考一下代码。
 45          */
 46 }
 47 
 48 /*
 49  * @description         : 微秒(us)级延时
 50  * @param - value       : 需要延时的us数,最大延时0XFFFFFFFFus
 51  * @return                      : 无
 52  */
 53 void delayus(unsigned    int usdelay)
 54 {
    
    
 55         unsigned long oldcnt,newcnt;
 56         unsigned long tcntvalue = 0;    /* 走过的总时间  */
 57 
 58         oldcnt = GPT1->CNT;
 59         while(1)
 60         {
    
    
 61                 newcnt = GPT1->CNT;
 62                 if(newcnt != oldcnt)
 63                 {
    
    
 64                         if(newcnt > oldcnt) /* GPT是向上计数器,并且没有溢出 */
 65                                 tcntvalue += newcnt - oldcnt;
 66                         else  /* 发生溢出    */
 67                                 tcntvalue += 0XFFFFFFFF-oldcnt + newcnt;
 68                         oldcnt = newcnt;
 69                         if(tcntvalue >= usdelay)/* 延时时间到了 */
 70                         break;              /*  跳出 */
 71                 }
 72         }
 73 }
 74 
 75 /*
 76  * @description         : 毫秒(ms)级延时
 77  * @param - msdelay     : 需要延时的ms数
 78  * @return                      : 无
 79  */
 80 void delayms(unsigned    int msdelay)
 81 {
    
    
 82         int i = 0;
 83         for(i=0; i<msdelay; i++)
 84         {
    
    
 85                 delayus(1000);
 86         }
 87 }
 88 
 89 /*
 90  * @description : 短时间延时函数
 91  * @param - n   : 要延时循环次数(空操作循环次数,模式延时)
 92  * @return              : 无
 93  */
 94 void delay_short(volatile unsigned int n)
 95 {
    
    
 96         while(n--){
    
    }
 97 }
 98 
 99 /*
100  * @description : 延时函数,在396Mhz的主频下
101  *              延时时间大约为1ms
102  * @param - n   : 要延时的ms数
103  * @return              : 无
104  */
105 void delay(volatile unsigned int n)
106 {
    
    
107         while(n--)
108         {
    
    
109                 delay_short(0x7ff);
110         }
111 }

我们在delay.c文件里面增加了三个函数:delay_init、delayus、delayms。
delay_init函数是延时初始化函数,主要完成了初始化GPT1定时器,设置时钟源,分频值和比较寄存器,最后使能GPT1定时器。
delayus函数是微秒级的延时,传入的参数代表要延时的微秒。在这个函数中我们对计数器溢出的情况作了处理。
delayms函数是毫秒级延时,传入的参数代表要延时的毫秒。

然后我们打开main.c文件,输入下面的内容:

  1 #include "clk.h"
  2 #include "delay.h"
  3 #include "led.h"
  4 #include "beep.h"
  5 #include "key.h"
  6 #include "int.h"
  7 #include "keyfilter.h"
  8 
  9 /*
 10  * @description : main函数
 11  * @param               : 无
 12  * @return              : 无
 13  */
 14 int main(void)
 15 {
    
    
 16         unsigned char state = OFF;
 17 
 18         int_init();     /* 初始化中断(一定要最先调用!) */
 19         imx6u_clkinit();  /* 初始化系统时钟                       */
 20         delay_init(); /* 初始化延时                   */
 21         clk_enable(); /* 使能所有的时钟                       */
 22         led_init();   /* 初始化led                    */
 23         beep_init();  /* 初始化beep                   */
 24 
 25         while(1)
 26         {
    
    
 27                 state = !state;
 28                 led_switch(LED0, state);
 29                 delayms(500);
 30         }
 31 
 32         return 0;
 33 }

我们在main.c文件中调用delay_init延时初始化函数,最后在while(1)循环中调用delayms毫秒延时函数,每隔500毫秒切换led的状态。在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_46635880/article/details/109057095