专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

C8051F320AD转换和温度传感器

作者:佚名   来源:本站原创   点击数:  更新时间:2011年09月02日   【字体:

   C8051F320内部有一个10位逐次逼近型ADC,可以工作在单端方式或者差分方式。

一、简要原理
    单片机内集成了2个多路选择器,分别作为ADC的正输入信号和负输入。
        正输入端由寄存器AMX0P控制输入信号,可以是P1~P3、温度传感器、VDD之一;
              负输入端由寄存器AMX0N控制输入信号,可以是P1~P3、VREF、GND之一。
    单负输入端选择GND时,采用单端方式;其他情况则采用差分方式,即用正端相对于负端的电压进行转换。
*采用并行口作为输入信号时,必须将对应输入引脚设为模拟输入,并且对应的SKIP要设置为1,即跳过
     
二、寄存器
 1、转换结果保存在两个8位寄存器ADC0H和ADC0L,由于转换结果是10位,可以自由选择在寄存器中采用左对齐或者右对齐(下详)
    单端方式下,转换结果直接保存为10位的无符号数
    差分方式下,结果保存为10位有符号整数(原说明:2的补码。未深究
 2、温度传感器的输出电压由下面公式决定:
          V = 2.86(T)+ 776 (单位mv)   从图表看,最高只能在1000mv左右,也就是100°时仅1V上下
 3、AD启动方式
    有六种启动方式,包括四个定时器溢出启动、特定位置1启动和P0.6上升沿启动。(下详)
    采用中断时,中断号interrupt 10
 4、跟踪方式  对跟踪不是很理解!
 
 5、寄存器AMX0P,正输入通道选择寄存器
    00H~10H,对应P1.0~P3.0     0x1E对应温度传感器  0x1F对应VDD 
    寄存器XMXON,负输入通道选择寄存器
    00H~10H,对应P1.0~P3.0     0x1E对应VREF        0x1F对应GND,此时为单端方式
 
 6、寄存器ADC0CF,配置寄存器,控制转换时钟,和数据保存方向
    D7~D3 时钟控制位,大意就是分频数,系统时钟与AD时钟的比值减1
    D2,为0时数据右对齐,为1时左对齐
 
 7、寄存器ADC0CN,控制寄存器。
    D7,AD使能,0时禁止转换
    D6,跟踪方式,不懂
    D5,中断标志位,要手动清0
    D4,读取时为忙标志位,写入时可为启动标志位,但不知道要不要清0
    D3,窗口比较中断标志,不是很清楚
    D2~D0 转换方式选择,且受到D6影响。具体未深究。
   
 8、寄存器REF0CN,电压基准控制器
      与AD的关系不完全明朗       
      D3   决定了电压基准              D2   使能温度传感器

 

 
下面是完整例程,但不包含12864的C文件。
完整例程下载地址:http://www.51hei.com/f/c8051sad.rar
#include "c8051f3xx.h"
#include "12864.h"
#define uchar unsigned char
#define uint unsigned int
 
sfr16 TMR2RL   = 0xca;                 // Timer2 reload value定时器2重载值
sfr16 TMR2     = 0xcc;                 // Timer2 counter定时器2计数器
//这两行相当好用,直接把T2的四个8位寄存器重新定义成2个16位寄存器!!!!!!
uchar adnum3,adnum2,adnum1;         //打算用来显示的数百位、十位和个位,在这里没有进行运算,只是直接的AD结果

sbit led0=P0^5;                //连了个发光二极管观察有没有死机。。


uchar code table[]="0123456789";       //显示数据用 
uchar code hang1[17]="1234567";         //以下四行为12864初始显示的内容,不重要
uchar code hang2[17]="123456789 ";
uchar code hang3[17]="2011-7-10 星期日";
uchar code hang4[17]="    00:00:00    ";

 

void Timer2_ISR (void) interrupt 5       // T2只是用来溢出的,没程序,清标志位而已
{
   TF2H = 0;
}

 


void Adc_ConvComplete_ISR (void) interrupt 10  //AD中断程序,除了清标志位,只是把数据送到12864第三行
{
   AD0INT = 0;                         
   lcd_pos(3,0);
   adnum3 = ADC0H/100;
   adnum2 = (ADC0H%100)/10;
   adnum1 = (ADC0H%100)%10;
   disp_only(tableaa[adnum3]);
   disp_only(tableaa[adnum2]);
   disp_only(tableaa[adnum1]);

 }

void Port_Init (void)   //端口初始化,哪个位要输入,就要设为模拟,并跳过
{
   P1MDIN   = 0x7F;
   P0MDIN   = 0xff; 
   P2MDIN   = 0xff;
   P3MDIN   = 0x00;
   P0MDOUT |= 0xfF;                    
   P1MDOUT |= 0x0F;                    
   P2MDOUT |= 0x0C;
   P1SKIP   = 0x80; 
   P0SKIP   = 0x00; 
   P2SKIP   = 0x00; 

   XBR0     = 0x00;
   XBR1     = 0x40;                
}

void Timer_Init (void)
{
   TMR2CN  = 0x00;                     
   CKCON  &= ~0xF0;                    
   TMR2RL  = 0;                       
   TMR2    = 0xffff;                   
   ET2     = 1;                        
   TR2     = 1;                       
}


void ADC0_Init (void)
{
   REF0CN = 0x0E;    // VDD作为基准电压,启用内部温度传感器
   AMX0P = 0x10;     // 10是P3.0,试过07(1.7)和1E(温度),都没问题
   ADC0CF = 0xFC;   // 11111,32分频?    (*表示分频数-1=31)  D2为1,左对齐
   AMX0N = 0x1F;    // 单端方式
   ADC0CN = 0xC2;   // T2溢出作为启动信号
   EIE1 |= 0x08;    // 开中断
}


  void System_Init (void)
{
   PCA0MD &= ~0x40;                    
   OSCICN |= 0x03;           
   Port_Init ();                     
   Timer_Init ();                 
   ADC0_Init ();
}

void DelayMS(uint x)
{
  uchar i;
 while(x--)
 {
   for(i=120;i>0;i--);
 }
}

 

void main(void)
{
    System_Init ();    
 lcd_init();
 clr_screen();
 DelayMS(100);
 lcd_pos(0,0);
    disp_chinese(hang1);
 lcd_pos(1,0);
    disp_chinese(hang2);
 lcd_pos(2,0);
    disp_chinese(hang3);
 lcd_pos(3,0);
    disp_chinese(hang4);
 EA = 1;
   while (1)
 {
   led0=~led0;
  DelayMS(5500);
   }
}

测试结果:

1、用开发板上的电位器,可以让高位结果在0~255之间变化

2、用温度传感器,室温下显示高位为65,*近笔记本风扇数秒后变成66,说明温度有变化,因为是高位,不明显,也没计算。

3、用全新的南孚电池一节,显示稳定的121。

 

____________________________________________________________________________

一、修改程序,将10位数字量转换成0~1023显示在屏幕上  

*用变位器,可以实现1~1023的变化,1和0之间无法稳定,直接接地也无法显示0

*用一节全新电池,显示485,VDD为3V,偏差不大。

二、再修改程序,将正输入设为温度传感器

*显示263,稍微加热后变成265,仍然觉得不够明显

*263对应电压约770mv,根据公式换算温度是负数。。。。

 在笔记本散热口放了一会升到268,还是低!

关闭窗口

相关文章