ESAYARM1138定时、中断、ADC(温度传感器)的综合应用

本文介绍了一个基于ESAYARM1138的综合小设计,利用内部16位定时器实现在数码管上显示时间,并通过外部中断切换时间与温度的显示。使用LM1138的温度传感器并通过ADC模块获取温度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在学ESAYARM1138,感觉比单片机要好用。做了个综合的小设计,在数码管上显示时间(由于找到的数码管是四位的,只能显示分和秒),用的是内部的16为定时器。在设计中开了个外部中断,用来切换时间的显示和温度的显示。

     温度传感器用的是lm1138内部的温度传感器,

温度算法:

10位的ADC模块集成有一个温度传感器,可以用来获取芯片的当前温度。

在温度传感器特性图里,给出了以下公式:

Vsenso = 2.7 - (T + 55) / 75,单位:V

设Vsenso对应的ADC采样值为N,2.7V对应N1,(T+55)/75对应N2

已知:

N1 * (3 / 1024) = 2.7

N2 * (3 / 1024) = (T + 55) / 75

由此得到:

N = N1 - N2 = 2.7 / (3 / 1024) - ((T + 55)/75) / (3 / 1024)

解得:

T = (151040 - 225 * N) / 1024

结论:

ADC配置为温度传感器模式后,只要得到ADC采样值N,就能推算出当前的温度T。

主程序:

#include  "systemInit.h"

#include  <adc.h>

#include  <stdio.h>

#include  <timer.h>

//  定义LED

#define  LED_PERIPH             SYSCTL_PERIPH_GPIOG

#define  LED_PORT               GPIO_PORTG_BASE

#define  LED_PIN                GPIO_PIN_2

//  定义KEY1和KEY2

#define  KEY1_PERIPH            SYSCTL_PERIPH_GPIOD

#define  KEY1_PORT              GPIO_PORTD_BASE

#define  KEY1_PIN               GPIO_PIN_1

//#define  KEY2_PERIPH            SYSCTL_PERIPH_GPIOG

//#define  KEY2_PORT              GPIO_PORTG_BASE

//#define  KEY2_PIN               GPIO_PIN_5

//    定义ADC

#define  ADCSequEnable          ADCSequenceEnable

#define  ADCSequDisable         ADCSequenceDisable

#define  ADCSequConfig          ADCSequenceConfigure

#define  ADCSequStepConfig      ADCSequenceStepConfigure

#define  ADCSequDataGet         ADCSequenceDataGet

tBoolean ADC_EndFlag = false;                               //  定义ADC转换结束的标志

int  min=0,sed=0,num=0,m=0;

int DATA_LED[10] =

  {

    //0~9的数码管段码  

0xC0,//"0"

0xF9,//"1"

0xA4,//"2"

0xB0,//"3"

0x99,//"4"

0x92,//"5"

0x82,//"6"

0xF8,//"7"

0x80,//"8"

0x98,//"9"

  };  

//  KEY1中断初始化

void key1IntInit(void)

{

    SysCtlPeriEnable(KEY1_PERIPH);                          //  使能KEY1所在的GPIO端口

    GPIOPinTypeIn(KEY1_PORT, KEY1_PIN);                     //  设置KEY1所在管脚为输出

    GPIOIntTypeSet(KEY1_PORT, KEY1_PIN, GPIO_LOW_LEVEL);    //  设置KEY1的中断类型

    IntPrioritySet(INT_GPIOD, 1 << 5);                      //  设置KEY1中断优先级为1

    GPIOPinIntEnable(KEY1_PORT, KEY1_PIN);                  //  使能KEY1所在管脚的中断

    IntEnable(INT_GPIOD);                                   //  使能GPIOD端口中断

}

/*

//  KEY2中断初始化

void key2IntInit(void)

{

    SysCtlPeriEnable(KEY2_PERIPH);                          //  使能KEY2所在的GPIO端口

    GPIOPinTypeIn(KEY2_PORT, KEY2_PIN);                     //  设置KEY2所在管脚为输出

    GPIOIntTypeSet(KEY2_PORT, KEY2_PIN, GPIO_LOW_LEVEL);    //  设置KEY2的中断类型

    IntPrioritySet(INT_GPIOG, 2<< 5);                      //  设置KEY2中断优先级为2

    GPIOPinIntEnable(KEY2_PORT, KEY2_PIN);                  //  使能KEY2所在管脚的中断

    IntEnable(INT_GPIOG);                                   //  使能GPIOG端口中断

}

*/

void led()    //数码管显示及数据处理程序

  {

int  T0,T1,T2,T3;

    GPIOPinWrite(GPIO_PORTA_BASE, 0xFF, 0xFF);

           T0=~DATA_LED[sed % 10];

           GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 0x00);

           GPIOPinWrite(GPIO_PORTA_BASE, 0xFF, T0); //个位

    SysCtlDelay(1* (TheSysClock / 6000));    //  延时约0.5ms

    GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 0xFF);

  

    GPIOPinWrite(GPIO_PORTA_BASE, 0xFF, 0xFF);

           T1=~DATA_LED[sed / 10 ];

            GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_1, 0x00);

           GPIOPinWrite(GPIO_PORTA_BASE, 0xFF,T1 );//十位    

    SysCtlDelay(1* (TheSysClock / 6000));    //  延时约0.5ms  

    GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_1, 0xFF);

  

    GPIOPinWrite(GPIO_PORTA_BASE, 0xFF, 0xFF);

           T2=~DATA_LED[min % 10];

           GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_2, 0x00);

           GPIOPinWrite(GPIO_PORTA_BASE, 0xFF,T2 );//百位  

           GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_7,0xff );//百位

    SysCtlDelay(1* (TheSysClock / 6000));    //  延时约0.5ms

    GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_2, 0xFF);

  

    GPIOPinWrite(GPIO_PORTA_BASE, 0xFF, 0xFF);

           T3=~DATA_LED[min /  10];

           GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_3, 0x00);

           GPIOPinWrite(GPIO_PORTA_BASE, 0xFF,T3 );//千位    

    SysCtlDelay(1* (TheSysClock / 6000));    //  延时约0.5ms

    GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_3, 0xFF);

  }

//  ADC初始化

void adcInit(void)

{

    SysCtlPeriEnable(SYSCTL_PERIPH_ADC);                    //  使能ADC模块

    SysCtlADCSpeedSet(SYSCTL_ADCSPEED_125KSPS);             //  设置ADC采样速率

    ADCSequDisable(ADC_BASE, 3);                            //  配置前先禁止采样序列

    //  采样序列配置:ADC基址,采样序列编号,触发事件,采样优先级

    ADCSequConfig(ADC_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);

    //  采样步进设置:ADC基址,采样序列编号,步值,通道设置

    ADCSequStepConfig(ADC_BASE, 3, 0, ADC_CTL_TS |

                                      ADC_CTL_END |

                                      ADC_CTL_IE);

    ADCIntEnable(ADC_BASE, 3);                              //  使能ADC中断

    IntEnable(INT_ADC3);                                    //  使能ADC采样序列中断

    IntMasterEnable();                                      //  使能处理器中断

    ADCSequEnable(ADC_BASE, 3);                             //  使能采样序列

}

//  ADC采样

unsigned long adcSample(void)

{

    unsigned long ulValue;

    ADCProcessorTrigger(ADC_BASE, 3);                       //  处理器触发采样序列

    while (!ADC_EndFlag);                                   //  等待采样结束

    ADC_EndFlag = false;                                    //  清除ADC采样结束标志

    ADCSequDataGet(ADC_BASE, 3, &ulValue);                  //  读取ADC转换结果

    return(ulValue);

}

//  计算芯片温度值

unsigned char  tmpDisplay(unsigned long ulValue)

{

    unsigned long T;

    T= 151040UL - 225 * ulValue;

    T=T/1024;

    return(T);

}

//显示温度

void led2(int n)    //数码管显示及数据处理程序

  {

int  T0,T1;

    GPIOPinWrite(GPIO_PORTA_BASE, 0xFF, 0xFF);

           T0=~DATA_LED[n % 10];

           GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 0x00);

           GPIOPinWrite(GPIO_PORTA_BASE, 0xFF, T0); //个位

    SysCtlDelay(1* (TheSysClock / 6000));    //  延时约0.5ms

    GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 0xFF);

  

    GPIOPinWrite(GPIO_PORTA_BASE, 0xFF, 0xFF);

           T1=~DATA_LED[n / 10 % 10];

            GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_1, 0x00);

           GPIOPinWrite(GPIO_PORTA_BASE, 0xFF,T1 );//十位    

    SysCtlDelay(1* (TheSysClock / 6000));    //  延时约0.5ms  

    GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_1, 0xFF);

          

    GPIOPinWrite(GPIO_PORTA_BASE, 0xFF, 0xFF);

           //T2=~DATA_LED[min % 10];

           GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_2, 0x00);

           GPIOPinWrite(GPIO_PORTA_BASE, 0xFF,0X00 );//百位  

           //GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_7,0xff );//百位

    SysCtlDelay(1* (TheSysClock / 6000));    //  延时约0.5ms

    GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_2, 0xFF);

  

    GPIOPinWrite(GPIO_PORTA_BASE, 0xFF, 0xFF);  

           //T3=~DATA_LED[min /  10];

           GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_3, 0x00);

           GPIOPinWrite(GPIO_PORTA_BASE, 0xFF,0X00 );//千位    

    SysCtlDelay(1* (TheSysClock / 6000));    //  延时约0.5ms

    GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_3, 0xFF);

}

//  主函数(程序入口)

int main(void)

{

    jtagWait();                                             //  防止JTAG失效,重要!

    clockInit();                                            //  时钟初始化:晶振,6MHz

    adcInit();  

    

    unsigned long ulValue;

    int t;

    SysCtlPeriEnable(SYSCTL_PERIPH_GPIOA);                           //  使能LGPIO端口

    SysCtlPeriEnable(SYSCTL_PERIPH_GPIOB);    

    GPIOPinTypeOut(GPIO_PORTA_BASE, 0xFF);                     //  设置管脚为输出

    GPIOPinTypeOut(GPIO_PORTB_BASE, 0xFF);

    

  // IntPriorityGroupingSet(0);

    key1IntInit();                                          //  KEY1中断初始化

  //key2IntInit();                                          //  KEY2中断初始化

    

    SysCtlPeriEnable(SYSCTL_PERIPH_TIMER0);                 //  使能Timer模块

    TimerConfigure(TIMER0_BASE, TIMER_CFG_16_BIT_PAIR |     //  配置Timer为16位周期定时器

                                TIMER_CFG_A_PERIODIC);

    TimerPrescaleSet(TIMER0_BASE, TIMER_A, 99);             //  预先进行100分频

    TimerLoadSet(TIMER0_BASE, TIMER_A, 60000);              //  设置Timer初值,定时1s

    TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);        //  使能Timer超时中断

    IntEnable(INT_TIMER0A);                                 //  使能Timer中断

    IntMasterEnable();                                      //  使能处理器中断

    TimerEnable(TIMER0_BASE, TIMER_A);                      //  使能Timer计数

    

    for (;;)

    {  

        m=num%2;

      if(m==0)

      {

       IntEnable(INT_TIMER0A);  

      TimerEnable(TIMER0_BASE, TIMER_A);

       led();

      }

      if(m==1)

      {

        ulValue = adcSample();                              //  ADC温度采样

        t= tmpDisplay(ulValue);

         led2(t);

      }  

    }

}

//  定时器的中断服务函数

void Timer0A_ISR(void)

{

    unsigned long ulStatus;

    ulStatus = TimerIntStatus(TIMER0_BASE, true);           //  读取中断状态

    TimerIntClear(TIMER0_BASE, ulStatus);                   //  清除中断状态,重要!

    if (ulStatus & TIMER_TIMA_TIMEOUT)                      //  如果是Timer超时中断

    {

         if(sed==59)

              {

                 if(min==59)

                {

            min=0;

          }

                   else

                     min++;

              sed=0;

              }

          else

              sed++;

     }

}

//  GPIOD的中断服务函数

void GPIO_Port_D_ISR(void)

{

   //  unsigned char ucVal;

    unsigned long ulStatus;

    ulStatus = GPIOPinIntStatus(KEY1_PORT, true);           //  读取中断状态

    GPIOPinIntClear(KEY1_PORT, ulStatus);                   //  清除中断状态,重要

    if (ulStatus & KEY1_PIN)                                //  如果KEY1的中断状态有效

    {

       num++;                                              //  中断服务函数

       /*

         ucVal = GPIOPinRead(LED_PORT, LED_PIN);             //  翻转LED

        GPIOPinWrite(LED_PORT, LED_PIN, ~ucVal);  

        */  

        SysCtlDelay(10 * (TheSysClock / 3000));             //  延时约10ms,消除按键抖动

        while (GPIOPinRead(KEY1_PORT, KEY1_PIN) == 0x00);     //  等待KEY抬起

        SysCtlDelay(10 * (TheSysClock / 3000));             //  延时约10ms,消除松键抖动

      

                                        

    }

  

}

/*

//  GPIOG的中断服务函数

void GPIO_Port_G_ISR(void)

{

    unsigned long ulStatus;

    ulStatus = GPIOPinIntStatus(KEY2_PORT, true);           //  读取中断状态

    GPIOPinIntClear(KEY2_PORT, ulStatus);                   //  清除中断状态,重要

    

    if (ulStatus & KEY2_PIN)                                //  如果KEY2的中断状态有效

    {

         if(sed==59)                                        //  中断服务函数

        {

            if(min==59)

        {

    min=0;

  }

      else

            min++;

              sed=0;

          }

    else

           sed++;  

     SysCtlDelay(10 * (TheSysClock / 3000));             //  延时约10ms,消除按键抖动

        while (GPIOPinRead(KEY2_PORT, KEY2_PIN) == 0x00);     //  等待KEY抬起

        SysCtlDelay(10 * (TheSysClock / 3000));             //  延时约10ms,消除松键抖动

    }

    

}

*/

//  ADC采样序列3的中断

void ADC_Sequence_3_ISR(void)

{

    unsigned long ulStatus;

    ulStatus = ADCIntStatus(ADC_BASE, 3, true);             //  读取中断状态

    ADCIntClear(ADC_BASE, 3);                               //  清除中断状态,重要

    if (ulStatus != 0)                                      //  如果中断状态有效

    {

        ADC_EndFlag = true;                                 //  置位ADC采样结束标志

    }

}

注:程序是我的原创,数码管部分用了两个显示函数主要是为了显示效果。上面的程序只是主程序,使用时只需要添加在工程模版中就可以了,不过要在工程模版中加入相应必要的文件。另外,在启动代码处要打开相应的中断(在工程模版中不会打开全部的中断,自己根据需要设置,这是我学习中发现的),否则程序无法实现其功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值