
C8051F320AD转换和温度传感器.docx
8页C8051F320内部有一个10位逐次逼近型ADC,可以工作在单端方式或者差分方式一、简要原理单片机内集成了 2个多路选择器,分别作为ADC的正输入信号和负输入正输入端由寄存器AMXOP控制输入信号,可以是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 104、 跟踪方式 对跟踪不是很理解!5、寄存器AMX0P,正输入通道选择寄存器00H〜10H,对应P1.0〜P3.0 0x1E对应温度传感器 0x1F对应VDD寄存器XMXON,负输入通道选择寄存器00H〜10H,对应P1.0〜P3.0 0x1E对应VREF 0x1F对应GND,此时为单端方式6、寄存器ADCOCF,配置寄存器,控制转换时钟,和数据保存方向D7〜D3时钟控制位,大意就是分频数,系统时钟与AD时钟的比值减1D2,为0时数据右对齐,为1时左对齐7、寄存器ADC0CN,控制寄存器D7, AD 使能, 0 时禁止转换D6,跟踪方式,不懂D5,中断标志位,要手动清0D4,读取时为忙标志位,写入时可为启动标志位,但不知道要不要清0D3,窗口比较中断标志,不是很清楚D2〜D0转换方式选择,且受到D6影响具体未深究8、寄存器REF0CN,电压基准控制器与 AD 的关系不完全明朗D3 决定了电压基准 D2 使能温度传感器下面是完整例程,但不包含12864的C文件完整例程下载地址:http://www.51hei.eom/f/c8051sad.rar#include "c8051f3xx.h"#include "12864.h"#define uchar unsigned char#define uint unsigned intsfr16 TMR2RL = 0xca; // Timer2 reload value 定时器 2 重载值sfr16 TMR2 = 0xcc; // Timer2 counter 定时器 2 计数器 〃这两行相当好用,直接把T2的四个8位寄存器重新定义成2个16位寄存器!! !uchar adnum3,adnum2,adnum1; //打算用来显示的数百位、十位和个位,在这里没有进行运算,只是直接的AD结果sbit ledO二P0“5;有没有死机。
//连了个发光二极管观察uchar code table[]="O123456789";uchar code hang1[17]="1234567"; 显示的内容,不重要uchar code hang2[17]="123456789 ";uchar code hang3[17]="2O11-7-1O 星期日"uchar code hang4[17]=" OO:OO:OO "//显示数据用//以下四行为 12864 初始void Timer2_ISR (void) interrupt 5 没程序,清标志位而已{TF2H = O;}// T2 只是用来溢出的,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, 一、 修改程序,将10位数字量转换成0〜1023显示在屏幕上*用变位器,可以实现1〜1023的变化, 1 和0之间无法稳定,直接接地也无法显示0*用一节全新电池,显示485, VDD为3V,偏差不大。
二、 再修改程序,将正输入设为温度传感器*显示 263,稍微加热后变成 265,仍然觉得不够明显 263对应电压约770mv,根据公式换算温度是负数在笔记本散热口放了一会升到 268,还是低!近笔记本风扇数秒后变成 66,说明温度有变化因为是高位,不明显,也没计算3、 用全新的南孚电池一节,显示稳定的 121。
