一、实验目的
1、了解STC15W408AS的ADC模块的功能
2、探索STC15W408AS的ADC模块的使用方法
二、实验内容
使用STC15W408AS的ADC模块和LM35温度传感器测量环境温度,然后将测得的数据转换成温度值,通过串口在上位机(串口助手)上显示出来。
三、硬件电路设计
四、软件程序设计
#include "STC15.h"
#include <stdio.h>
#include "intrins.h"
#define ADC_POWER 0x80 // ADC电源控制位
#define ADC_FLAG 0x10 // ADC完成标志
#define ADC_START 0x08 // ADC起始控制位
#define ADC_SPEEDLL 0x00 // 540个时钟
#define ADC_SPEEDL 0x20 // 360个时钟
#define ADC_SPEEDH 0x40 // 180个时钟
#define ADC_SPEEDHH 0x60 // 90个时钟
#define VCC 5000 // set ADC_REF_VCC
typedef unsigned char BYTE;
typedef unsigned int WORD;
BYTE ch = 1; // ADC通道号1,接LM35传感器信号输出引脚
BYTE flag = 0; // 设置转换完成标志位
BYTE H8bit = 0, L2bit = 0;
WORD AD10bit = 0, temp = 0, dat = 0, dat1 = 0;
unsigned long result = 0;
void InitADC();
void UartInit(void);
char putchar(char c);
void Delay(WORD n);
void DisplayData(unsigned int iData);
void main()
{
InitADC(); //初始化ADC
while (1)
{
if (flag)
{
flag = 0;
AD10bit = (AD10bit | H8bit) & 0x00ff;
AD10bit = (AD10bit << 2) | (L2bit & 0X03); //合并成10位二进制数
temp = AD10bit;
AD10bit = 0;
ADC_RES = 0;
ADC_RESL = 0;
printf("value=%d", temp);
printf(" ");
//注意:先把temp强制转换成long型,再进行电压转换才可获得正确的电压值
result = ((long)temp * VCC / 102.3);
DisplayData(result);
printf("\r\n");
}
}
}
/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
P1ASF = 0x02; //设置P1口为AD口
P1M1 = 0x02; // set 1# chanel to AD
P1M0 = 0x00; // set 1# chanel to AD
CLK_DIV = 0x00; //结果右对齐
ADC_RES = 0; //清除结果寄存器
ADC_RESL = 0;
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
Delay(10); // ADC上电并延时
AUXR |= 0x10; // set EADCI
IE = 0xa0; // Enable ADC interrupt and Open master interrupt switch
}
/*----------------------------
软件延时
----------------------------*/
void Delay(WORD n)
{
WORD x;
while (n--)
{
x = 5000;
while (x--)
;
}
}
void DisplayData(unsigned int iData)
{
char NumStr[4] = {0, 0, 0, 0}, i = 0;
NumStr[0] = iData / 1000; // 千位
NumStr[1] = (iData % 1000) / 100; // 百位
NumStr[2] = iData % 100 / 10; // 十位
NumStr[3] = iData % 10; // 个位
printf("ADC1=");
printf("%c", NumStr[0] + 0x30);
printf("%c", NumStr[1] + 0x30);
printf(".");
printf("%c", NumStr[2] + 0x30);
printf("%c", NumStr[3] + 0x30);
}
/*----------------------------
ADC中断服务程序
----------------------------*/
void adc_isr() interrupt 5
{
H8bit = ADC_RES;
L2bit = ADC_RESL;
ADC_CONTR &= !ADC_FLAG; //清除ADC中断标志
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
flag = 1;
}
void UartInit(void)
{
SCON = 0x50; // 8位可变波特率
T2L = 0xe8; //设置波特率重装值
T2H = 0xff; // T2为1T模式, 并启动定时器2
AUXR = 0x11; //选择定时器2为串口1的波特率发生器
ES = 1; //使能串口1中断
EA = 1; //打开总中断
}
char putchar(char c)
{
UartInit();
ES = 0;
SBUF = c;
while (TI == 0)
;
TI = 0;
ES = 1;
return 0;
}
五、实验效果
六、实验心得
在本次试验中,遇到了各种各样的问题,经过本人通过各种途径,被我一一攻克了,很有成就感。还是要多练习,多折腾,才会理解的深一些。所以在日常生活中,每当遇到困难,不要轻易放弃,集中自己的精力,攻坚克难,突破这道坎,才会有所提升,不然,永远原地踏步,没有进步。