你试试下面的代码
#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 4000000 // 假设使用4MHz晶振
// 函数声明
void init();
uint16_t get_ad();
void disp(uint8_t num1, uint8_t num2, uint8_t num3, uint8_t num4);
void delay(uint16_t x);
void main() {
uint16_t ad_value;
float voltage;
init();
while(1) {
ad_value = get_ad(); // 获取ADC原始值
voltage = (ad_value / 1023.0) * 5.0; // 计算实际电压值
// 显示电压(千分位,如5.000V)
uint8_t a1 = (uint16_t)(voltage * 1000) / 1000;
uint8_t a2 = ((uint16_t)(voltage * 1000) % 1000) / 100;
uint8_t a3 = ((uint16_t)(voltage * 1000) % 100) / 10;
uint8_t a4 = (uint16_t)(voltage * 1000) % 10;
disp(a1, a2, a3, a4);
// 检测电压是否接近5V(考虑误差,如4.95V~5.05V)
if (voltage >= 4.95 && voltage <= 5.05) {
PORTEbits.RE0 = 1; // RE0输出高电平
} else {
PORTEbits.RE0 = 0; // 其他情况输出低电平
}
__delay_ms(100); // 延时防抖动
}
}
void init() {
TRISA = 0x01; // RA0为输入(ADC),其他为输出
TRISE = 0x00; // RE0为输出
PORTA = 0x00;
PORTE = 0x00;
// 配置ADC:Fosc/8时钟,右对齐,AN0通道,VDD/VSS参考电压
ADCON0 = 0x41; // 01000001: 开启ADC,选择AN0
ADCON1 = 0x80; // 10000000: 右对齐,VDD/VSS参考
__delay_ms(10); // 等待ADC稳定
}
uint16_t get_ad() {
GO_nDONE = 1; // 启动ADC转换
while (GO_nDONE); // 等待转换完成
return ((ADRESH << 8) | ADRESL); // 返回10位ADC结果
}
// 显示函数(需根据实际硬件调整)
void disp(uint8_t num1, uint8_t num2, uint8_t num3, uint8_t num4) {
// 假设使用共阳数码管,table为段码表
extern const uint8_t table[];
PORTD = table[num1];
PORTA = 0x20; // 第1位数码管使能
__delay_ms(2);
// ...(其他位显示类似)
}
void delay(uint16_t x) {
for (uint16_t a = x; a > 0; a--)
for (uint16_t b = 110; b > 0; b--);
}
|