ADC常用库函数(STC8系列)
ADC工作原理:
深化量化误差分析:引入公式Equant=Vref2n+1 E_{\text{quant}} = \frac{V_{\text{ref}}}{2^{n+1}} Equant=2n+1Vref,其中EquantE_{\text{quant}}Equant为量化误差,nnn为分辨率(12位时误差约0.61 mV)。解释如何通过过采样降低噪声。
STC8 ADC硬件特性:
补充多通道切换时序:建议添加时序图描述(例如,通道切换延迟tswitch≈1μst_{\text{switch}} \approx 1 \mu stswitch≈1μs),并讨论外部参考电压源的选择(如使用TL431稳压器提升精度)。
1. ADC初始化函数
/******************* ADc配置函数 *******************/
void ADC_config(void)
{ADC_InitTypeDef ADC_InitStructure; //结构定义ADC_InitStructure.ADC_SMPduty = 31; //ADC 模拟信号采样时间控制, 0~31(注意: SMPDUTY 一定不能设置小于 10)ADC_InitStructure.ADC_CsSetup = 0; //ADC 通道选择时间控制 0(默认),1ADC_InitStructure.ADC_CsHold = 1; //ADC 通道选择保持时间控制 0,1(默认),2,3ADC_InitStructure.ADC_Speed = ADC_SPEED_2X1T; //设置 ADC 工作时钟频率 ADC_SPEED_2X1T~ADC_SPEED_2X16TADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED; //ADC结果调整, ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIEDADC_Inilize(&ADC_InitStructure); //初始化ADC_PowerControl(ENABLE); //ADC电源开关, ENABLE或DISABLENVIC_ADC_Init(DISABLE,Priority_0); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}
2. 获取值
u16 result = Get_ADCResult(chn); // chn: ADC_CH0, ADC_CH1, ADC_CH2 .... ADC_CH15
3. 计算电压
float v = result * 基准电压 / 采样精度;
4. 案例
#include "GPIO.h"
#include "Delay.h"
#include "UART.h" // 串口配置 UART_Configuration
#include "NVIC.h" // 中断初始化NVIC_UART1_Init
#include "Switch.h" // 引脚切换 UART1_SW_P30_P31
#include "ADC.h"void GPIO_config() { GPIO_InitTypeDef info;// ===== UART1 P30 P31 准双向info.Mode = GPIO_PullUp; // 准双向info.Pin = GPIO_Pin_0 | GPIO_Pin_1; // 引脚GPIO_Inilize(GPIO_P3, &info);// P05 高阻输入info.Mode = GPIO_HighZ; // 高阻输入info.Pin = GPIO_Pin_5; // 引脚GPIO_Inilize(GPIO_P0, &info);
}// 串口配置函数的定义
void UART_config(void) {// >>> 记得添加 NVIC.c, UART.c, UART_Isr.c <<<COMx_InitDefine COMx_InitStructure; //结构定义COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTxCOMx_InitStructure.UART_BRT_Use = BRT_Timer1; //选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 一般 110 ~ 115200COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLECOMx_InitStructure.BaudRateDouble = DISABLE; //波特率加倍, ENABLE或DISABLEUART_Configuration(UART1, &COMx_InitStructure); //初始化串口1 UART1,UART2,UART3,UART4NVIC_UART1_Init(ENABLE,Priority_1); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3UART1_SW(UART1_SW_P30_P31); // 引脚选择, UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
}/******************* AD配置函数 *******************/
void ADC_config(void)
{ADC_InitTypeDef ADC_InitStructure; //结构定义ADC_InitStructure.ADC_SMPduty = 31; //ADC 模拟信号采样时间控制, 0~31(注意: SMPDUTY 一定不能设置小于 10)ADC_InitStructure.ADC_CsSetup = 0; //ADC 通道选择时间控制 0(默认),1ADC_InitStructure.ADC_CsHold = 1; //ADC 通道选择保持时间控制 0,1(默认),2,3ADC_InitStructure.ADC_Speed = ADC_SPEED_2X1T; //设置 ADC 工作时钟频率 ADC_SPEED_2X1T~ADC_SPEED_2X16TADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED; //ADC结果调整, ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIEDADC_Inilize(&ADC_InitStructure); //初始化ADC_PowerControl(ENABLE); //ADC电源开关, ENABLE或DISABLENVIC_ADC_Init(DISABLE,Priority_0); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}void main() {u16 adc;float vol; // 电压EA = 1; // 使能中断总开关GPIO_config(); // GPIO配置UART_config(); // 串口配置ADC_config(); // ADC配置while (1){// 读取ADC采样值,是采样值,不是电压值,但和电压有关系// 参数不能乱写,原理图 芯片手册 P05 对应的通道是 13 通道adc = Get_ADCResult(ADC_CH13);// 转换为电压vol = adc * 2.5 / 4095;// 0~2.5v 是准确的, 2.5v~3.3v 代码读到的数据都是2.5v// 1.65 ~ 2.5v printf("adc = %d, vol = %.2f\n", (int)adc, vol);// 处理的太快delay_ms(250);delay_ms(250);}
}
关键寄存器说明:
寄存器 | 功能描述 |
---|---|
ADC_CONTR | 控制寄存器 (通道选择/启动/速度) |
ADC_RES | ADC结果高8位 |
ADC_RESL | ADC结果低2位 |
P1M1/P1M0 | P1口模式配置寄存器 |
使用注意:
- 首次使用需延时30μs等待ADC稳定
- ADC引脚必须配置为高阻输入模式
- 转换时间约tconv=12×分频系数sysclkt_{conv} = \frac{12 \times 分频系数}{sysclk}tconv=sysclk12×分频系数
- STC8A系列有12位ADC,需调整结果组合方式
建议配合STC-ISP工具生成的寄存器配置文件使用,不同子系列需查看对应数据手册调整细节。