第20集 ADC_NTC测温,已手敲代码,测试通过
任务1:ADC采集NTC换算内温度
- #include "adc.h"
-
- void AdcSetRate(void) //50KSPS@24.000MHz
- {
- ADCCFG &= ~0x0f;
- ADCCFG |= 0x04; //SPEED(4)
- ADCTIM = 0xbf; //CSSETUP(1), CSHOLD(1), SMPDUTY(31)
- }
-
- void ADC_Init(void)
- {
- P5M0 |= 0x02; P5M1 &= ~0x02;
- P51 = 1;
-
- //1.初始化IO为高祖输入
- P1M0 &= ~0x01; P1M1 |= 0x01;
- P1M0 &= ~0x08; P1M1 |= 0x08;
-
- //2.初始化ADC速度
- AdcSetRate();
-
- //3.对齐模式
- ADCCFG |= 0x20;
-
- //4.打开ADC电源
- ADC_POWER = 1;
- }
-
- u16 ADC_Read(u8 no)
- {
- u16 adcval = 0;
- ADC_CONTR &= 0Xf0; //清空低四位
- ADC_CONTR |= no;
-
- ADC_START = 1; //启动ADC转化
- _nop_();
- _nop_();
- while( !ADC_FLAG ); //等待采集完成
- ADC_FLAG = 0; //手动清空
-
- adcval = (((u16)ADC_RES) << 8) + (ADC_RESL); //获取到最终的ADC数值
-
- return adcval;
- }
-
- // (256-64) - (256+64)
- // (512-64) - (512+64)
-
- #define ADC_OFFEST 64
-
- u8 ADC_KEY_READ( u16 adc ) //返回值1-16分别对应16个按键
- {
- u16 i;
- // 1.判断当前有没有按键按下
- if( adc < (256 - ADC_OFFEST) )
- {
- return 0;
- }
- else //按键按下了
- {
- for( i=1;i<=16;i++ )
- {
- if(( adc >= ( i*256-ADC_OFFEST ) ) &&( adc <= ( i*256+ADC_OFFEST )))
- {
- return i;
- }
- }
- }
- return 0;
- }
-
- u16 code Temp_Tab[]=
- {
- 140 ,
- 149 ,
- 159 ,
- 168 ,
- 178 ,
- 188 ,
- 199 ,
- 210 ,
- 222 ,
- 233 ,
- 246 ,
- 259 ,
- 272 ,
- 286 ,
- 301 ,
- 317 ,
- 333 ,
- 349 ,
- 367 ,
- 385 ,
- 403 ,
- 423 ,
- 443 ,
- 464 ,
- 486 ,
- 509 ,
- 533 ,
- 558 ,
- 583 ,
- 610 ,
- 638 ,
- 667 ,
- 696 ,
- 727 ,
- 758 ,
- 791 ,
- 824 ,
- 858 ,
- 893 ,
- 929 ,
- 965 ,
- 1003,
- 1041,
- 1080,
- 1119,
- 1160,
- 1201,
- 1243,
- 1285,
- 1328,
- 1371,
- 1414,
- 1459,
- 1503,
- 1548,
- 1593,
- 1638,
- 1684,
- 1730,
- 1775,
- 1821,
- 1867,
- 1912,
- 1958,
- 2003,
- 2048,
- 2093,
- 2137,
- 2182,
- 2225,
- 2269,
- 2312,
- 2354,
- 2397,
- 2438,
- 2479,
- 2519,
- 2559,
- 2598,
- 2637,
- 2675,
- 2712,
- 2748,
- 2784,
- 2819,
- 2853,
- 2887,
- 2920,
- 2952,
- 2984,
- 3014,
- 3044,
- 3073,
- 3102,
- 3130,
- 3157,
- 3183,
- 3209,
- 3234,
- 3259,
- 3283,
- 3306,
- 3328,
- 3351,
- 3372,
- 3393,
- 3413,
- 3432,
- 3452,
- 3470,
- 3488,
- 3506,
- 3523,
- 3539,
- 3555,
- 3571,
- 3586,
- 3601,
- 3615,
- 3628,
- 3642,
- 3655,
- 3667,
- 3679,
- 3691,
- 3702,
- 3714,
- 3724,
- 3735,
- 3745,
- 3754,
- 3764,
- 3773,
- 3782,
- 3791,
- 3799,
- 3807,
- 3815,
- 3822,
- 3830,
- 3837,
- 3844,
- 3850,
- 3857,
- 3863,
- 3869,
- 3875,
- 3881,
- 3887,
- 3892,
- 3897,
- 3902,
- 3907,
- 3912,
- 3917,
- 3921,
- 3926,
- 3930,
- 3934,
- 3938,
- 3942,
- };
-
- u16 Temp_Cal(u16 adc) //返回结果是放大10倍的数值16.9*10=169
- {
- u8 j = 0;
- u16 k = 0;
- u16 min; //当前的位置
- u16 max; //当前最大的位置
- u16 i; //温度
-
- adc = 4096- adc; //得到当前的adc数值
-
- if( adc <Temp_Tab[0]) //温度最小值检测
- return 0xfffe;
- if( adc >Temp_Tab[160]) //温度最大值检测
- return 0xffff;
-
- min = 0;
- max = 160;
-
- for( j=0;j<5;j++ ) //实现五次二分法查询
- {
- k = (min+max)/2;
- if( adc <=Temp_Tab[k])
- max = k;
- else
- min = k;
- }
-
- if( adc == Temp_Tab[min])
- i=min*10;
- else if( adc == Temp_Tab[max])
- i=max*10;
- else
- {
- while(min<=max)
- {
- min++;
- if(Temp_Tab[min] == adc)
- {
- i=min*10;
- break;
- }
- else if( adc< Temp_Tab[min] ) //超过这一档的温度的adc
- {
- min --;
- i=Temp_Tab[min]; //上一档的adc数值记下来
- j=Temp_Tab[min+1]-Temp_Tab[min]; //这2档之间的差值
- j=(adc-i)*10/j;
- i=min*10+j;
- break;
- }
- }
- }
- return i;
- }
复制代码
任务2:使用ADC测量内部1.19V信号源,反推电源电压
- #include "config.h"
- #include "task.h"
- #include "io.h"
- #include "tim.h"
- #include "18b20.h"
- #include "adc.h"
-
- char *USER_DEVICEDESC = NULL;
- char *USER_PRODUCTDESC = NULL;
- char *USER_STCISPCMD = "@STCISP#";
-
- void Delay3000ms(void) //@24.000MHz
- {
- unsigned long edata i;
-
- _nop_();
- _nop_();
- i = 17999998UL;
- while (i) i--;
- }
-
- void main(void)
- {
- Sys_init(); //系统初始化
- usb_init(); //USB CDC 接口配置
-
- IE2 |= 0x80; //使能USB中断
- Timer0_Init(); //定时器初始化
- Init_595();
-
- Timer1_Init();
- ADC_Init();
-
- EA = 1; //IE |= 0X80;
-
- P40 = 0;
-
- while (DeviceState != DEVSTATE_CONFIGURED); //等待USB完成配置
-
-
- while(1)
- {
-
- if (bUsbOutReady) //如果接收到了数据
- {
- //USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
-
- usb_OUT_done(); //
- }
- Task_Pro_Handler_Callback(); //执行功能函数
-
- SEG_Show_U32((4096*119/(u32)ADC_Read(15)) );
-
- }
- }
-
-
-
- void Timer0_Isr(void) interrupt 1 //1MS执行一次
- {
-
- Task_Marks_Handler_Callback(); //系统计时
-
- }
复制代码
|