⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 temp_adc_student.c

📁 温度的测试
💻 C
字号:

#include <c8051f000.h> 
#include <stdio.h>

#define ON 1
#define OFF 0
#define XTLVLD_BIT 0x80 // OSCXCN.7 晶体振荡器有效标志
#define TC_20MS 18432 // 定时器在 11.0592MHz/12时对应于
// 20ms的嘀答数

sbit rd     = P1^7;
sbit re     = P1^5;
sbit wr		= P1^6;
sbit addr0	= P1^0;
sbit addr1	= P1^1;
sbit addr2	= P1^2;
sbit addr3	= P1^3;
sbit addr4	= P1^4;

sbit data0	= P2^0;
sbit data1	= P2^1;
sbit data2	= P2^2;
sbit data3	= P2^3;
sbit lcd_en = P3^0;

//--------------------------------------------------------------------
// 函数原型
//--------------------------------------------------------------------
void sysclk_init (void);
void xbar_init (void);

void ADC_init (void);
void ADC_enable (void);
void Timer3_init (void);
void ADC_isr (void);
void write (int addr, int datain);
unsigned int read();
void delay(int time_10ms);
//--------------------------------------------------------------------
// 全局变量
//--------------------------------------------------------------------
long temperature; // 以百分之一度表示的温度值
unsigned idata temp[16]; // 温度采样值的循环缓冲区
int temp_ptr; // 指向 temp[]的指针
int temp_int; // 温度值的整数部分
int temp_frac; // 温度值的小数部分(以百分之一度为单位)
int n,m,l;    //延时程序中用
//--------------------------------------------------------------------
// 主程序
//--------------------------------------------------------------------
void main (void) 
{
  unsigned int temp1,temp2,xor1,wei1,wei2,temp_wei,i;
   WDTCN = 0xde;                       // Disable watchdog timer
   WDTCN = 0xad;
  sysclk_init (); // 初始化振荡器
  xbar_init (); // 初始化交叉开关和GPIO
  Timer3_init (); // 初始化定时器3为 20ms 溢出
  ADC_init (); // 初始化 ADC 的输入为温度传感器
  ADC_enable (); // 允许 ADC转换结束中断
  temperature = 0L;
  temp_ptr = 0;
  lcd_en=0;
  write(1,0);
  EA =1    ; // 允许中断
  temp2=read();
  while (1)
   {
    temp1=read();
	if (temp1!=temp2) 
	{
    xor1=temp1^temp2;
	delay(10);
    temp2=read(); 
    if (temp1==temp2) 
	{   
	    wei1=xor1%2;
		temp_wei=temp2;
	    if(wei1!=0)
		{
		   wei2=temp_wei%2;
		   if(wei2==0) 
		   {i++;
		   if(i%2==0) EA=0;
		   if(i%2!=0) EA=1;               }    //处理KEY1

		}
		xor1>>=1;
	    wei1=xor1%2;
	    if(wei1!=0)
		{
           temp_wei>>=1;
		   wei2=temp_wei%2;
		   if(wei2==0) 
		   {                }       //处理KEY2

		}
		xor1>>=1;
	    wei1=xor1%2;
	    if(wei1!=0)
		{
           temp_wei>>=2;
		   wei2=temp_wei%2;
		   if(wei2==0) 
		   {               }         //处理KEY3

		}
		xor1>>=1;
	    wei1=xor1%2;
	    if(wei1!=0)
		{
           temp_wei>>=3;
		   wei2=temp_wei%2;
		   if(wei2==0) 
		   {               }           //处理KEY4

		}
	} 
   } 
  }
}

// 将器件配置为使用外部 CMOS 时钟。
void sysclk_init (void)
{
  WDTCN = 0xde; // 禁止看门狗定时器
  WDTCN = 0xad;
  OSCXCN = 0x65; // 启动外部振荡器// 对于11.0592MHz的晶体,允许SYSCLK/1
  while ( (OSCXCN & XTLVLD_BIT) == 0 ){}// 等待外部振荡器起动
  OSCICN = 0x88; // 选择外部振荡器作为系统时钟// 禁止内部振荡器
}

// 配置交叉开关和 GPIO 端口
void xbar_init (void)
{
  XBR0 =0x10       ;
  XBR1 =0x00       ; 
  XBR2 =0x40      ; // 允许交叉开关和弱上拉
//  PRT0CF |= 0x10; // 允许P0口的所有输出为弱上拉;// 让交叉开关将这些引脚配置为输入
  PRT1CF  |= 0xff;                     // P1.6 is push-pull
  PRT2CF  |= 0xff;                     // P1.6 is push-pull
  P1     |= 0xa0;   

}

// 配置 A/D 转换器使用定时器3溢出为转换启动源,并在转换完成时产生中断
void ADC_init (void)
{
  ADCEN = 0; // 禁止 ADC
  REF0CN =0x07      ; // 允许温度传感器,片内偏置发生器和偏置输出缓冲器
  AMX0SL =0x08      ; // 选择温度传感器为ADC多路开关的输出
  ADC0CF =0x61     ; // ADC 转换时钟 = sysclk/8// 对11.0592MHz,GAIN = 2x
  ADC0CN =0xc5     ; // 禁止ADC,低功耗跟踪方式,// ADC 由定时器3溢出启动,数据左对齐
}

// 允许 ADC;定时器3溢出启动转换;允许ADC中断
void ADC_enable (void)
{
  ADCEN =1        ; //允许 ADC
  EIE2 |=0X02           ; //允许ADC中断(正常优先级)
}

// 配置定时器3为自动重装载方式,定时间隔为 20ms(不产生中断)
void Timer3_init (void)
{
  TMR3CN = 0; // 停止定时器3,清除TF3,使用SYSCLK/12作为时基
  TMR3RLH = 0xff & ((-TC_20MS) >> 8);// 初始化重载值
  TMR3RLL = 0xff & (-TC_20MS);
  TMR3H = 0xff; // 立即重装载
  TMR3L = 0xff;
  EIE2 =0x00	        ; // 禁止定时器3中断
  TMR3CN |=0X04        ; // 启动定时器3
}

// ADC 转换结束 ISR
// 在此我们读 ADC 采样值,将其放入到16个采样值的缓冲区内,求所有采样值的平均值
// 并将其转换为以百分之一摄氏度为单位的温度值
void ADC_isr (void) interrupt 15
{
  int i; // 循环计数器
  long temp_temp; // 临时温度值
  ADCINT =0     ; // 清除ADC转换结束中断标志
  temp_temp =ADC0H*256+ADC0L; // 装入16位ADC结果
  temp[temp_ptr] = temp_temp; // 加到缓冲区中
  temp_ptr++;
  temp_ptr = temp_ptr % 16; // 回绕缓冲区指针
  temp_temp = 0L;
  for (i=0; i<16; i++) 
  {
    temp_temp = temp_temp + temp[i]; // 累加采样值,以便求均值
  }
  temp_temp =temp_temp/16             ; // 总和/16,求得平均值
// 至此,temp_temp 中为16个采样值得平均值。
//现在我们需要将其转换为以百分之一摄氏度表示的温度值。
//
// 在左对齐方式,ADC 产生的代码(CODE)与输入电压成正比:
// CODE = Vin * Gain / Vref * 2^16
//
// 温度传感器产生的电压(Vtemp)与以摄氏度表示的绝对温度(Temp)成正比:
// Vtemp = 2.86mV/C * Temp + 0.776V
//
// 结合这两个方程,我们可以将输出码(左对齐)与输入温度的关系表示为:
// CODE = (2.86mV/C * Temp + 0.776V) * Gain / Vref * 2^16
//
// 解上面的方程求Temp:
// CODE = 2.86mV/C * Temp * Gain/Vref * 2^16 + 0.776V * Gain/Vref * 2^16
// Temp =(CODE-(0.776V * Gain/Vref * 2^16))/(2.86mV/C * Gain/Vref * 2^16)
//
// 可以表示为:
// Temp = (CODE - K1) * K2
//
// 其中 K1 = 0.776 * Gain/Vref * 2^16
// K2 = 1/(2.86mV/C * Gain/Vref * 2^16)
//
// 对于 Vref = 2.4V 和 Gain = 2,
// K1 = 32,932 = 0xa58c
// K2 = 480 / 2^16 – 我们在所有计算中保持该值为480,在最后除以2^16。420=0x01a4
  temp_temp =temp_temp-0xa58c                     ; // 将偏差校正到 0度, 0V
  temp_temp =temp_temp*0x01e0                      ; // 2.5mV/摄氏度
  temp_temp = temp_temp * 100; // 显示结果,以百分之一摄氏度表示
  temperature = temp_temp >> 16; // 除以 2^16
temperature=temperature-122;
//补写输出部分程序,将以百分之一度表示的温度值转换成两个十进制数,整数部分和小数部分
write(1,temperature%10);
delay(100);
write(2,temperature/10%10);
delay(100);
write(7,3);
write(3,temperature/100%10);
write(4,temperature/1000%10);




}

void write (int addr, int datain)
{
    char pp;
    PRT2CF  |= 0xff; 
    pp=addr;
	pp|= 0xA0;
	P1 =pp;
 
	P2=datain;
	wr=1;	
	wr=0;

}

unsigned int read()
{
   unsigned int data_rd;
   PRT2CF  &= 0xf0; 
   P2=0xff;
   rd=0;
   data_rd=P2;
   data_rd &=0x0f;

   rd=1;
   PRT2CF  |= 0xff; 

   return data_rd;

}

void delay(int time_10ms)
{

	for (n=0;n<=time_10ms;n++)
	{
		for(m=0;m<=10;m++)
		{
			for(l=0;l<=80;l++) ; 
		}
	}
}

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -