标题:
湖南大学STC-B单片机学习板光照温度测量程序(AD转换)
[打印本页]
作者:
小蓝好好的
时间:
2018-11-16 21:07
标题:
湖南大学STC-B单片机学习板光照温度测量程序(AD转换)
可以将光照值和温度值显示在数码管上(AD转换)
单片机源程序如下:
#include <reg52.h>
#include <intrins.h>
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr CLK_DIV = 0x97;
//sfr AUXR = 0x8E;
sfr ADC_CONTR = 0xBC; //ADC控制寄存器
sfr ADC_RES = 0xBD; //ADC高8位结果
sfr ADC_LOW2 = 0xBE; //ADC低2位结果
sfr P1ASF = 0x9D; //P1口模拟功能控制寄存器
#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个时钟
sbit LED_SEL = P2^3;
sbit BEEP = P3^4;
unsigned char code LedChar[] = { //数码管显示字符转换表 0-F
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71
};
unsigned char LedBuff[9] = { //数码管显示缓冲区 + 独立LED缓冲区
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
int code TempData[]={
239,197,175,160,150,142,135,129,124,120,116,113,109,107,104,101, //温度值对应表
99, 97, 95, 93, 91, 90, 88, 86, 85, 84, 82, 81, 80, 78, 77, 76,
75, 74, 73, 72, 71, 70, 69, 68, 67, 67, 66, 65, 64, 63, 63, 62,
61, 61, 60, 59, 58, 58, 57, 57, 56, 55, 55, 54, 54, 53, 52, 52,
51, 51, 50, 50, 49, 49, 48, 48, 47, 47, 46, 46, 45, 45, 44, 44,
43, 43, 42, 42, 41, 41, 41, 40, 40, 39, 39, 38, 38, 38, 37, 37,
36, 36, 36, 35, 35, 34, 34, 34, 33, 33, 32, 32, 32, 31, 31, 31,
30, 30, 29, 29, 29, 28, 28, 28, 27, 27, 27, 26, 26, 26, 25, 25,
24, 24, 24, 23, 23, 23, 22, 22, 22, 21, 21, 21, 20, 20, 20, 19,
19, 19, 18, 18, 18, 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 14,
13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 9, 9, 9, 8, 8, 8, 7,
7, 7, 6, 6,5, 5, 54,4, 3, 3,3, 2, 2, 1, 1, 1, 0, 0, -1, -1, -1,
-2, -2, -3, -3, -4, -4, -5, -5, -6, -6, -7, -7, -8, -8, -9, -9,
-10, -10, -11, -11, -12, -13, -13, -14, -14, -15, -16, -16, -17,
-18, -19, -19, -20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
30, -32, -33, -35, -36, -38, -40, -43, -46, -50, -55, -63, 361
};
unsigned char ch = 3; //ADC通道号
int temp = 0;
unsigned int light = 0;
unsigned char T0RH = 0; //T0重载值的高字节
unsigned char T0RL = 0; //T0重载值的低字节
bit beep_flag = 0; //蜂鸣器运行控制位
void InitADC();
void Delay2ms();
void ConfigTimer0(unsigned int ms);
void main()
{
P0M0 = 0xFF;
P0M1 = 0x00;
P2M0 = 0x08;
P2M1 = 0x00;
LED_SEL = 0;
InitADC(); //初始化ADC
IE = 0xA0; //使能ADC中断
//开始AD转换
ConfigTimer0(1); //配置T0定时1ms
while(1)
{
if (temp < 0)
{
LedBuff[0] = 0x40;
LedBuff[1] = LedChar[-temp/10%10];
LedBuff[2] = LedChar[-temp%10];
}
else
{
LedBuff[0] = LedChar[temp/100%10];
LedBuff[1] = LedChar[temp/10%10];
LedBuff[2] = LedChar[temp%10];
}
LedBuff[5] = LedChar[light/100%10];
LedBuff[6] = LedChar[light/10%10];
LedBuff[7] = LedChar[light%10];
if (temp >= 28)
{
beep_flag = 1;
LedBuff[8] = 0xFF;
}
else
{
LedBuff[8] = 0x01;
}
}
}
/* ADC中断服务程序 */
void adc_isr() interrupt 5 using 1
{
static unsigned int cnt = 0; //记录ADC中断次数
static unsigned long temp_sum = 0; //温度AD值累加和
static unsigned long light_sum = 0; //光照AD值累加和
cnt++; //中断次数+1
ADC_CONTR &= !ADC_FLAG; //清除ADC中断标志
if (ch == 3)
{
temp_sum += (ADC_RES*256+ADC_LOW2)/4;
}
if (ch == 4)
{
light_sum += ADC_RES*256+ADC_LOW2;
}
if (cnt > 2000)
{
cnt = 0;
temp = TempData[(temp_sum+1000/2)/1000-1];
light = (light_sum+1000/2)/1000;
temp_sum = 0;
light_sum = 0;
}
ADC_RES = 0;
ADC_LOW2 = 0; //清除结果寄存器
if (++ch == 5) ch=3; //切换到下一个通道
ADC_CONTR = ADC_POWER|ADC_SPEEDLL|ADC_START|ch;
CLK_DIV = 0x20;
}
/* 初始化ADC */
void InitADC()
{
P1ASF = 0xFF; //设置P1口为AD口
ADC_RES = 0;
ADC_LOW2 = 0; //清除结果寄存器
ADC_CONTR = ADC_POWER|ADC_SPEEDLL|ADC_START|ch;
CLK_DIV = 0x20; //ADC_RES[1:0]存放高2位ADC结果,ADC_RESL[7:0]存放低8位ADC结果
Delay2ms(); //ADC上电并延时
}
void Delay2ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 22;
j = 128;
do
{
while (--j);
} while (--i);
}
/* 配置并启动T0,ms为T0定时时间 */
void ConfigTimer0(unsigned int ms)
{
unsigned long tmp; //临时变量
tmp = 11059200 / 12; //定时器计数频率
tmp = (tmp * ms) / 1000; //计算所需的计数值
tmp = 65536 - tmp; //计算定时器重载值
tmp = tmp + 13; //补偿中断响应延时造成的误差
T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
T0RL = (unsigned char)tmp;
TMOD &= 0xF0; //清零T0的控制位
TMOD |= 0x01; //配置T0为模式1
TH0 = T0RH; //加载T0重载值
TL0 = T0RL;
ET0 = 1; //使能T0中断
TR0 = 1; //启动T0
}
/* LED动态扫描函数,需在定时中断中调用 */
void LedScan()
{
static unsigned char i = 0; //动态扫描索引
P0 = 0x00; //关闭所有段选位,显示消隐
P2 = (P2 & 0xF0) | i; //位选索引值赋值到P2口低3位
P0 = LedBuff[i]; //缓冲区中索引位置的数据送到P0口
if (i < sizeof(LedBuff)-1) //索引递增循环,遍历整个缓冲区
i++;
else
i = 0;
}
/* T0中断服务函数,完成数码管扫描 */
void InterruptTimer0() interrupt 1
{
static unsigned int cnt = 0;
TH0 = T0RH; //重新加载重载值
TL0 = T0RL;
LedScan(); //LED扫描显示
if (beep_flag)
{
BEEP = ~BEEP; //反转蜂鸣器控制电平
cnt++;
if (cnt > 5000) { //中断5000次后,即定时5ms
cnt = 0;
beep_flag = 0;
}
}
}
复制代码
所有资料51hei提供下载:
lesson5.zip
(39.54 KB, 下载次数: 11)
2018-11-16 21:07 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1