|
|
//-----------------------------------------------------------------------------
// F32x_ADC_ScanAllChannels.c
//-----------------------------------------------------------------------------
// 示例说明:
// 本程序自动扫描 ADC0 的 32 个通道(0~31),
// 每通道读取一次 ADC 值,然后通过 UART0 打印。
// 使用单端输入(负端接地),并保证串口输出完整。
//-----------------------------------------------------------------------------
#include "c8051F320.h" // SFR 定义
#include <stdio.h>
//-----------------------------------------------------------------------------
// 16-bit SFR 定义
//-----------------------------------------------------------------------------
sfr16 TMR2RL = 0xca; // Timer2 重装值
sfr16 TMR2 = 0xcc; // Timer2 计数器
sfr16 ADC0 = 0xbd; // ADC0 数据寄存器
//-----------------------------------------------------------------------------
// 全局常量
//-----------------------------------------------------------------------------
#define SYSCLK 12000000 // 系统时钟 12MHz
#define BAUDRATE 115200 // UART 波特率
sbit LED = P2^2; // LED 输出
#define NUM_CHANNELS (sizeof(valid_channels)/sizeof(valid_channels[0]))
unsigned char valid_channels[] = {
0x04, // P0.4
0x0C, // P1.4
0x10, // P2.0
0x11, // P2.1
0x12, // P2.2
0x13, // P2.3
0x14 // P2.4(重点)
};
//-----------------------------------------------------------------------------
// 函数原型
//-----------------------------------------------------------------------------
void SYSCLK_Init(void);
void PORT_Init(void);
void ADC0_Init(void);
void UART0_Init(void);
void delay_ms(unsigned int ms); // 简单延时函数
// 读取 ADC0 值,保证 10 位有效值
unsigned int Read_ADC(void)
{
unsigned int val;
AD0BUSY = 1; // 启动 ADC 转换
while(!AD0INT); // 等待转换完成
AD0INT = 0; // 清 ADC 完成标志
val = ((ADC0H << 2) | (ADC0L >> 6)) & 0x03FF; // 右对齐 10 位
val = ((unsigned int)ADC0H << 8) | ADC0L;
val >>= 6;
return val;
}
//-----------------------------------------------------------------------------
// MAIN 函数
//-----------------------------------------------------------------------------
void main(void)
{
PCA0MD &= ~0x40; // 关闭看门狗
SYSCLK_Init(); // 系统时钟初始化
PORT_Init(); // 端口初始化
UART0_Init(); // UART 初始化
ADC0_Init(); // ADC 初始化
//EA = 1; // 全局中断使能
printf("ADC 扫描程序启动...\n");
// 无限循环扫描 ADC 通道
while(1)
{
unsigned char i;
unsigned char ch;
unsigned int val;
for(i = 0; i < NUM_CHANNELS; i++)
{
ch = valid_channels[i]; // ? 从数组取通道
AMX0P = ch;
Read_ADC(); // 丢弃第一次(MUX稳定)
val = Read_ADC(); // 取有效值
if(val < 20)
{
printf("CH=0x%02X, ADC=%04u (接近GND)\n", (unsigned int)ch, val);
}
else if(val > 1000)
{
printf("CH=0x%02X, ADC=%04u (接近VREF)\n", (unsigned int)ch, val);
}
else
{
printf("CH=0x%02X, ADC=%04u (有信号)\n", (unsigned int)ch, val);
}
delay_ms(2);
}
printf("------------------\n");
}
}
//-----------------------------------------------------------------------------
// 系统时钟初始化
//-----------------------------------------------------------------------------
void SYSCLK_Init(void)
{
OSCICN = 0x83; // 内部 12MHz 振荡器
RSTSRC = 0x04; // 启用缺钟复位
}
//-----------------------------------------------------------------------------
// 端口初始化
//-----------------------------------------------------------------------------
void PORT_Init(void)
{
XBR0 = 0x01; // UART0 使能
XBR1 = 0x40; // 交叉开关使能,弱上拉
P0MDOUT |= 0x10; // TX push-pull
P2MDOUT |= 0x04; // LED push-pull
//P0MDIN &= ~(1<<4); // P0.4
P1MDIN &= ~(1<<4); // P1.4
//P2MDIN &= ~0x10; // P2.4 作为模拟输入
P2MDIN &= ~0x1F; // P2.0~P2.4 全部设为模拟输入
}
//-----------------------------------------------------------------------------
// ADC0 初始化
//-----------------------------------------------------------------------------
void ADC0_Init(void)
{
ADC0CN = 0x80; // ADC 禁用,普通跟踪模式,TMR2 触发
REF0CN = 0x03; // 启用内部 VREF
AMX0P = 0x0C; // 初始通道 P2.4
AMX0N = 0x1F; // 负端接地
ADC0CF = ((SYSCLK/3000000)-1)<<3; // SAR 时钟 3MHz
ADC0CF |= 0x00; // 右对齐结果
//EIE1 |= 0x08; // 允许 ADC 完成中断
AD0EN = 1; // 启用 ADC
}
//-----------------------------------------------------------------------------
// UART0 初始化
//-----------------------------------------------------------------------------
void UART0_Init(void)
{
SCON0 = 0x10; // 8-bit 可变速率, RX 使能
if(SYSCLK/BAUDRATE/2/256 < 1) {
TH1 = -(SYSCLK/BAUDRATE/2);
CKCON |= 0x08;
} else if(SYSCLK/BAUDRATE/2/256 < 4) {
TH1 = -(SYSCLK/BAUDRATE/2/4);
CKCON &= ~0x0B;
CKCON |= 0x01;
} else if(SYSCLK/BAUDRATE/2/256 < 12) {
TH1 = -(SYSCLK/BAUDRATE/2/12);
CKCON &= ~0x0B;
} else if(SYSCLK/BAUDRATE/2/256 < 48) {
TH1 = -(SYSCLK/BAUDRATE/2/48);
CKCON &= ~0x0B;
CKCON |= 0x02;
} else {
while(1); // 不支持波特率
}
TL1 = TH1;
TMOD &= ~0xF0;
TMOD |= 0x20; // Timer1 8-bit 自动重装
TR1 = 1; // 启动 Timer1
TI0 = 1; // TX0 ready
}
//-----------------------------------------------------------------------------
// 简单延时函数
//-----------------------------------------------------------------------------
void delay_ms(unsigned int ms)
{
unsigned int i,j;
for(i=0;i<ms;i++)
for(j=0;j<120;j++);
}
//-----------------------------------------------------------------------------
// End of File
//----------------------------------------------------------------------------- |
|