⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adc1.c

📁 一个不错的A/D非常适合初学者
💻 C
字号:
// 包含文件
//-----------------------------------------------------------------------------
#include <c8051f020.h> // SFR声明
#include <stdio.h>
//-----------------------------------------------------------------------------
// C8051F02X的16位SFR定义
//-----------------------------------------------------------------------------
sfr16 DP = 0x82; // 数据指针
sfr16 TMR3RL = 0x92; // 定时器3重装值
sfr16 TMR3 = 0x94; // 定时器3计数器
sfr16 ADC0 = 0xbe; // ADC0数据
sfr16 ADC0GT = 0xc4; // ADC0大于窗口
sfr16 ADC0LT = 0xc6; // ADC0小于窗口
sfr16 RCAP2 = 0xca; // 定时器2捕捉/重装
sfr16 T2 = 0xcc; // 定时器2
sfr16 RCAP4 = 0xe4; // 定时器4捕捉/重装
sfr16 T4 = 0xf4; // 定时器4
sfr16 DAC0 = 0xd2; // DAC0数据
sfr16 DAC1 = 0xd5; // DAC1数据
//-----------------------------------------------------------------------------
// 全局常量
//-----------------------------------------------------------------------------
#define SYSCLK 22118400 // 系统时钟频率Hz
#define BAUDRATE 115200 // UART波特率bps
#define SAMPLERATE0 50000 // ADC0采样频率Hz
#define NUM_SAMPLES 2048 // ADC0采样次数
#define TRUE 1
#define FALSE 0
sbit LED = P1^6; // LED=’1’ 意为开
sbit SW1 = P3^7; // SW1=’0’ 意为按压开关
//-----------------------------------------------------------------------------
// 函数原型
//-----------------------------------------------------------------------------
void SYSCLK_Init (void);
void PORT_Init (void);
void UART0_Init (void);
void ADC0_Init (void);
void Timer3_Init (int counts);
void ADC0_ISR (void);
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
xdata unsigned samples[NUM_SAMPLES]; // 存储ADC0结果数组
bit ADC0_DONE; // 当NUM_SAMPLES次被采集为真
//-----------------------------------------------------------------------------
// 主程序
//-----------------------------------------------------------------------------
void main (void) {
int i; // 循环计数器
WDTCN = 0xde; // 禁止看门狗定时器
WDTCN = 0xad;
SYSCLK_Init (); // 初始化振荡器
PORT_Init (); // 初始化数据交叉开关和通用IO口
UART0_Init (); // 初始化UART0
Timer3_Init (SYSCLK/SAMPLERATE0); // 初始化定时器3溢出作为ADC0采样率
ADC0_Init (); // 初始化ADC
EA = 1; // 允许全部中断
while (1) {
ADC0_DONE = FALSE;
LED = 1; // 在采样过程中点亮LED
EIE2 |= 0x02; // 允许ADC0中断
while (ADC0_DONE == FALSE); // 等待采样结果
// 上传采样值到UART0
LED = 0; // 上传其间关LED 灭
for (i = 0; i < NUM_SAMPLES; i++) {
printf ("%u\n", samples[i]);
}
printf ("\n");
}
}
//-----------------------------------------------------------------------------
// 初始化化子程序
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// 时钟初始化
//-----------------------------------------------------------------------------
//
// 此程序初始化系统时钟使用22.1184MHz晶体为时钟源
//
void SYSCLK_Init (void)
{
int i; // 延时计数器
OSCXCN = 0x67; // 开启外部振荡器22.1184MHz晶体
for (i=0; i < 256; i++) ; // 等待振荡器启振
while (!(OSCXCN & 0x80)) ; // 等待晶体振荡器稳定
OSCICN = 0x88; // 选择外部振荡器为系统时钟源并允许丢失时钟检测器
}
//-----------------------------------------------------------------------------
// IO口初始化
//-----------------------------------------------------------------------------
//
// 配置数据交叉开关和通用IO口
//
void PORT_Init (void)
{
XBR0 = 0x04; // 使能UART0
XBR1 = 0x00;
XBR2 = 0x40; // 使能数据交叉开关和弱上拉
P0MDOUT |= 0x01; // 允许TX0为推挽输出
P1MDOUT |= 0x40; // 允许P1.6(LED)为推挽输出
}
//-----------------------------------------------------------------------------
// UART0初始化
//-----------------------------------------------------------------------------
//
// 配置UART0 使用定时器1为波特率发生器
//
void UART0_Init (void)
{
SCON0 = 0x50; // SCON0: 模式1, 8位UART, 使能RX
TMOD = 0x20; // TMOD: 定时器1, 模式2, 8位重装
TH1 = -(SYSCLK/BAUDRATE/16); // 根据波特率的值设定定时器1重装值
TR1 = 1; // 启动定时器1
CKCON |= 0x10; // 定时器1使用系统时钟作为时基
PCON |= 0x80; // SMOD00 = 1
TI0 = 1; // 表示TX0就绪
}
//-----------------------------------------------------------------------------
// ADC0初始化
//-----------------------------------------------------------------------------
//
// 配置ADC0 使用定时器3溢出作为转换开始信号,转换结束产生一个中断,
// 使用左对齐输出模式
// 使能ADC转换结束中断中断使能ADC0 但禁止ADC0转换结束中断
//
void ADC0_Init (void)
{
ADC0CN = 0x04; // ADC0 禁止; 正常跟踪模式定时器3溢出ADC0转换开始
// ADC0数据右对齐
REF0CN = 0x07; // 使能温度传感器, 片内 VREF,和 VREF 输出缓冲器
AMX0SL = 0x00; // 选择AIN0作为ADC多路转换输出
ADC0CF = (SYSCLK/2500000) << 3; // ADC转换时钟2.5MHz
ADC0CF &= ~0x07; // PGA增益 = 1
EIE2 &= ~0x02; // 禁止ADC0中断
AD0EN = 1; // 使能ADC0
}
//-----------------------------------------------------------------------------
// 定时器3初始化
//-----------------------------------------------------------------------------
//
// 配置定时器3 自动重装间隔由 <counts> 决定(不产生中断) 使用系统时钟为时基
//
void Timer3_Init (int counts)
{
TMR3CN = 0x02; // 停止定时器3; 清除TF3;
// 使用系统时钟作为时基
TMR3RL = -counts; // 初始化重装值
TMR3 = 0xffff; // 立即开始重装
EIE2 &= ~0x01; // 禁止定时器3中断
TMR3CN |= 0x04; // 启动定时器3
}
//-----------------------------------------------------------------------------
//中断服务程序
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// ADC0中断服务程序
//-----------------------------------------------------------------------------
//
// ADC0转换结束中断服务程序
// 得到ADC0采样值并存储到全局数组<samples[]>
// 并更新局部采样计数器 <num_samples> 当 <num_samples> == <NUM_SAMPLES>时,
// 禁止ADC0 转换结束中断并置ADC0_DONE = 1
//
void ADC0_ISR (void) interrupt 15 using 3
{
static unsigned num_samples = 0; // ADC0采样计数器
AD0INT = 0; // 清除ADC0转换结束标志
samples[num_samples] = ADC0; // 读和存储ADC0值
num_samples++; // 更新采样计数器
if (num_samples == NUM_SAMPLES) {
num_samples = 0; // 复位采样计数器
EIE2 &= ~0x02; // 禁止ADC0中断
ADC0_DONE = 1; // 设置DONE标志
}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -