//-----------------------------------------------------------------------------
// 文件名:AD.C
//-----------------------------------------------------------------------------
//
// 功能说明:AD转换,并在LED数码管上显示转换结果
// 初始日期:2007年1月26日
//
// 修改版本:
// 修改内容:
// 修改日期:
CPU型号 : C8051F330
// 硬件工具:TY-51-J1
// 调试器:U-EC5
// 软件工具: SL IDE 2.82
//-----------------------------------------------------------------------------
#include <c8051f330.h> // SFR 声明
//-----------------------------------------------------------------------------
// 定义16位特殊功能寄存器
sfr16 ADC0 = 0xbd; // ADC0 采样数据寄存器地址
//-----------------------------------------------------------------------------
// 函数原形定义
#define uchar unsigned char
void main (void); // 主函数
void SYSCLK_Init (void); // 系统时钟初始化
void PORT_Init (void); // IO口初始化
void ADC0_Init (void); // AD转换初始化
void LED4_Display (void); // LED显示
void LED_OUT(uchar X); // LED单字节串行移位函数
unsigned int AD_Sampling (unsigned char Channel); // AD采样子程序
void _16to4bit10(unsigned int dd); // 16进制到4位10进制转换
unsigned char code LED_0F[]; // LED字模表
//-----------------------------------------------------------------------------
// 全局常量
#define SYSCLK 24500000 / 8 // 系统频率
sbit LED_DOUT = P1^6; //串行数据输入
sbit LED_CLK = P1^5; //时钟脉冲信号——上升沿有效
sbit LED_LATCH = P1^7; //打入信号————上升沿有效
#define AI1 6 // AI1采样通道为P0.6
#define AI2 7 // AI2采样通道为P0.7
//-----------------------------------------------------------------------------
// 全局变量
uchar LED[4]; //用于LED的4位显示缓存
//*****************************************************************************
// 主程序
//
void main (void)
{
PCA0MD &= ~0x40; // 禁止watchdog timer
SYSCLK_Init (); // 初始化系统时钟到 24.5MHz
PORT_Init (); // 初始化io口与交叉开关
ADC0_Init (); // 初始化AD转换
while(1)
{
unsigned long i1;
i1=AD_Sampling (AI1); //采样
i1=i1*3300; //参考电压选择VDD=3.3V
//3.3*1000=3300
i1=i1/1024; //除以2的10次方(10位AD)
_16to4bit10(i1); //结果转换为4位10进制数
//并送显示
LED4_Display ();
}
}
// 主程序结束
//*****************************************************************************
//*****************************************************************************
// 初始化程序
//-----------------------------------------------------------------------------
// SYSCLK_Init 系统时钟初始化程序
//
// 使用内部 24.5MHz / 8 振荡器作为时钟源
// 同时允许时钟丢失检测器
//
void SYSCLK_Init (void)
{
OSCICN = 0x80; // 使用内部振荡器;8分频
RSTSRC = 0x04; // 检测到时钟丢失时允许系统复位
}
//-----------------------------------------------------------------------------
// PORT_Init IO端口初始化程序
//
// 定义交叉开关和IO口
// P1.0 - LED (推挽)
//
void PORT_Init (void)
{
P0MDIN = 0x3f; // 定义P0.6、P0.7为模拟输入通道
// P0.6——AI1
// P0.7——AI2
P0SKIP = 0xc0; // P0.6、P0.7被交叉开关跳过
XBR0 = 0x00; // 未选择任何数字外设
XBR1 = 0x40; // 使能交叉开关和弱上拉
P1MDOUT |= 0xE0; // 设P1.5、P1.6、P1.7为输出端口
}
//-----------------------------------------------------------------------------
// ADC0初始化
//
void ADC0_Init (void)
{
AMX0N = 0x11; // 单端输入方式
ADC0CN = 0x80; // ADC0使能;正常跟踪模式
// 当写AD0BUSY时ADC0转换开始;ADC0数据右对齐
REF0CN = 0xA; // (电压基准控制寄存器)使用VDD
// 禁止片内温度传感器
ADC0CF = (SYSCLK/2500000) << 3; // ADC转换时钟=2.5MHz
EIE1 &= ~0x0C; // 禁止ADC0窗口比较器中断
// 禁止ADC0 EOC中断
}
// 初始化程序结束
//*****************************************************************************
//-----------------------------------------------------------------------------
// AD_Sampling ——AD采样子程序
//
// Channel 采样通道
//
unsigned int AD_Sampling (unsigned char Channel)
{
AMX0P = Channel; // 选择模拟转换通道
AD0INT = 0; // xx转换结束标记
AD0BUSY = 1; // 开始转换
while (AD0INT == 0); // 等待转换结束
return(ADC0); // 读ADC0数据
}
//-----------------------------------------------------------------------------
// 16进制到4位10进制转换
//
// 将dd数据转换为4位10进制数,并存入LED显示缓存
void _16to4bit10(unsigned int dd)
{
unsigned int div;
unsigned char i;
div=1000;
for (i=0;i<4;i++) {
LED[i]=dd/div;
dd%=div;
div/=10;
}
}
//*****************************************************************************
// 显示程序
//-----------------------------------------------------------------------------
// 4位LED显示程序
//
void LED4_Display (void)
{
unsigned char code *led_table; // 查表指针
uchar i;
//显示第1位
led_table = LED_0F + LED[0];
i = *led_table;
i &= 0x7f; //显示小数点
LED_OUT(i); //段码输出
LED_OUT(0xfe); //位码输出
LED_LATCH = 0;
LED_LATCH = 1;
//显示第2位
led_table = LED_0F + LED[1];
i = *led_table;
LED_OUT(i); //段码输出
LED_OUT(0xfd); //位码输出
LED_LATCH = 0;
LED_LATCH = 1;
//显示第3位
led_table = LED_0F + LED[2];
i = *led_table;
LED_OUT(i); //段码输出
LED_OUT(0xfb); //位码输出
LED_LATCH = 0;
LED_LATCH = 1;
//显示第4位
led_table = LED_0F + LED[3];
i = *led_table;
LED_OUT(i); //段码输出
LED_OUT(0xf7); //位码输出
LED_LATCH = 0;
LED_LATCH = 1;
}
//-----------------------------------------------------------------------------
// LED单字节串行移位函数
//
void LED_OUT(uchar X)
{
uchar i;
for(i=8;i>=1;i--)
{
if (X&0x80) LED_DOUT=1; else LED_DOUT=0;
X<<=1;
LED_CLK = 0;
LED_CLK = 1;
}
}
// 显示程序结束
//*****************************************************************************
//----------------------------------------------
// LED转换表0——F
//----------------------------------------------
unsigned char code LED_0F[] =
{// 0 1 2 3 4 5 6 7 8 9 A b C d E F -
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8C,0xBF,0xC6,0xA1,0x86,0xFF,0xbf
};