附上程序
//
////****************************************************************************//
//// STC12C5A60S2 A/D转换模块 //
////
//// 说明: STC12C5A60S2单片机有8路10位高速AD转换器,P1^0-P1^7
////
//// 涉及寄存器:P1ASF(模拟功能控制寄存器)、ADC_CONTR(ADC控制寄存器)
//// ADC_RES、ADC_RESL(转换结果寄存器)
////
//// 注意: 1、初次打开内部A/D模拟电源需适当延时等内部模拟电源稳定后,再启动A/D转换
//// 启动A/D后,在转换结束前不改变任何I/O口的状态,有利于高精度A/D转换
//// 若能将定时器/串行/中断系统关闭更好。
//// 2、A/D转换模块使用的时钟为内部R/C振荡器所产生的系统时钟
//// 3、由于使用两套时钟,设置好ADC_CONTR后要加4个空延时操作才可以正确
//// 读到ADC_CONTR寄存器的值
//////
//// 程序说明:
//// 本程序实现P1^0口作为A/D采集输入口,对外部电压的测量并将测量结果通过
//// 12864和串口显示出来
//////****************************************************************************//
#include <STC12C5A60S2.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define Lcd_IO P0
#define comm 0
#define dat 1
sbit RS=P2^5;
sbit RW=P2^6;
sbit EN=P2^7;
sbit PSB=P2^4;
sbit RST=P2^2;
#define ADC_POWER 0x80 //AD电源控制
#define ADC_START 0x08 //AD转换控制
#define ADC_FLAG 0x10 //AD转换完成
#define Speed_0 0x00 //540 clk
#define Speed_1 0x20 //360 clk
#define Speed_2 0x40 //180 clk
#define Speed_3 0x60 //90 clk
#define ADC0 0x00 //P1.0
#define ADC1 0x01 //P1.1
#define ADC2 0x02 //P1.2
#define ADC3 0x03 //P1.3
#define ADC4 0x04 //P1.4
#define ADC5 0x05 //P1.5
#define ADC6 0x06 //P1.6
#define ADC7 0x07 //P1.7
void AD_init(void);
double Result_Calculate(void);
void SendData( uchar byte );
//**********************************//
// A/D初始化 //
//**********************************//
void AD_init(void)
{
AUXR1 = 0x04; //转换结果高2位放在ADC_RES的低2位中,低8位放在ADC_RESL中
P1ASF = 0x01; //P1.0口作为模拟功能A/D使用
ADC_RES = 0x00; //结果清零
ADC_RESL = 0x00;
ADC_CONTR = ADC_POWER|Speed_2|ADC0|ADC_START; //打开电源,180CLK周期转换,选择P1.0作输入
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
EADC = 1; //允许A/D转换中断
EA = 1; //开总中断
}
//****************************************//
// 串口初始化 //
//****************************************//
//void UART_init(void)
//{
// SM0 = 0; //选择串口为方式1工作
// SM1 = 1; //8位数据波特率可变
// REN = 1;
// BRT = 0xDC;
// AUXR = 0x15; //选择独立波特率发生器为串行
// //口的波特率发生器,模式为1T
//}
//******************************************//
// 转换结果计算 //
//******************************************//
double Result_Calculate(void)
{
uint temp;
double result;
temp = ADC_RES * 256 + ADC_RESL;
result = temp * 4.94 / 1024;
return result;
}
//******************************************//
// 串口发送数据 //
//******************************************//
//void SendData( uchar byte )
//{
// SBUF = byte;
// while(!TI);
// TI = 0;
//}
void Delay_us(uint i)//i=10,time=100us
{
for(;i>0;i--);
}
void Delay_ms(uint i)//i=10,time=10ms
{
while(i--)
Delay_us(100);
}
//向12864液晶写数据或命令
void Lcd_wcd(uchar dat_comm,uchar Lcd_data)
{
if(dat_comm)
RS=1; //数据
else RS=0; //命令
Lcd_IO=Lcd_data;
RW=0;
EN=1;
Delay_us(50);
EN=0;
}
void Lcd_init() //液晶初始化
{
RST=0;
Delay_us(50); //外部复位
RST=1;
PSB=1;
Lcd_wcd(comm,0x30); //基本指令格式
Delay_us(50);
Lcd_wcd(comm,0x01); //液晶清屏
Delay_ms(30);
Lcd_wcd(comm,0x06); //设置显示格式,光标位置
Lcd_wcd(comm,0x0c);
}
void Lcd_pst(uchar xx,uchar yy) //设置显示坐标
{
uint line;
switch(yy)
{
case 0:line=0x00;break;
case 1:line=0x10;break;
case 2:line=0x08;break;
case 3:line=0x18;break;
default :break;
}
Lcd_wcd(comm,0x80+line+xx);
}
void Lcd_str(uchar *str) //显示字符串和汉字
{
while(*str!='\0')
{
Lcd_wcd(dat,*str);
str++;
}
}
//液晶自定义显示
void Lcd_define(uchar *str)
{
uint m,n;
Lcd_wcd(comm,0x34); //设置位扩展指令格式
for(m=0;m<32;m++)
{
for(n=0;n<8;n++)
{
Lcd_wcd(comm,0x80+m); //写纵坐标,00H--1FH
Lcd_wcd(comm,0x80+n); //写横坐标,00H--07H
Lcd_wcd(dat,str[m*16+n*2]);
Lcd_wcd(dat,str[m*16+n*2+1]);//连续写两个数据
}
}
for(m=32;m<64;m++)
{
for(n=0;n<8;n++)
{
Lcd_wcd(comm,0x80+m-32); //写纵坐标,00H--1FH
Lcd_wcd(comm,0x88+n); //写横坐标,08H--0FH
Lcd_wcd(dat,str[m*16+n*2]);
Lcd_wcd(dat,str[m*16+n*2+1]); //连续写两个数据
}
}
Lcd_wcd(comm,0x30); //基本指令格式
Lcd_wcd(comm,0x01); //清屏
Delay_ms(30);
Lcd_wcd(comm,0x34); //扩展指令格式
Lcd_wcd(comm,0x36); //显示自定义图形
}
//*********************************//
//* 名称:Printf_Decimal()
//* 功能:打印浮点类型数据
//* 输入:double Num --要打印的数据
//* 输出:无
//*********************************//
void Printf_Decimal(double Num)
{
uchar s[] = {0,0,46,0,0};
uint t;
t = (uint)(Num * 1000);
s[0] = t/10000+48;
s[1] = t%10000/1000+48;
s[3] = t%1000/100+48;
s[4] = t%100/10+48;
s[5] = t%10+48;
Lcd_pst(0,1);
Lcd_str(s);
// SendData(s[0]);
// SendData(s[1]);
// SendData(s[2]);
// SendData(s[3]);
// SendData(s[4]);
// SendData(s[5]);
// SendData('\t');
}
//主函数
void main()
{
Lcd_init();
Lcd_pst(0,0);
Lcd_str("电压:");
AD_init();
// UART_init();
Delay_ms(1000);
while(1);
}
//******************************************//
// A/D中断服务 //
//******************************************//
void AD_Service(void) interrupt 5
{
ADC_CONTR &= !ADC_FLAG; //清标志
Printf_Decimal(Result_Calculate());
ADC_RES = 0x00;
ADC_RESL = 0x00;
ADC_CONTR = ADC_POWER|Speed_2|ADC_START; //开始下一次转换
_nop_();
_nop_();
_nop_();
_nop_();
}
|