//3位数码电压表
//电压范围:0-50V
//原理:比较器做为ADC
//共阴数码管
//5V稳定性越高,测量的电压越准确
PCB用PADS打开.7z
(53.35 KB, 下载次数: 450)
程序如下:
- //3位数码电压表
- //电压范围:0-50V
- //原理:比较器做为ADC
- //共阴数码管
- //5V稳定性越高,测量的电压越准确
- #include "stc15w204s.h"
- #include "Led_can.h"
- typedef unsigned long u32; //32位无符号整型数
- typedef unsigned int u16; //16位无符号整型数
- typedef unsigned char u8; //8位无符号整型数
- #define MAIN_Fosc 22118400 //定义主时钟
- #define ADC_SCALE 50000 //ADC满量程, 根据需要设置
- /************* 本地常量声明 **************/
- //CMPCR1
- #define CMPEN 0x80 //1: 允许比较器, 0: 禁止,关闭比较器电源
- #define CMPIF 0x40 //比较器中断标志, 包括上升沿或下降沿中断, 软件清0
- #define PIE 0x20 //1: 比较结果由0变1, 产生上升沿中断
- #define NIE 0x10 //1: 比较结果由1变0, 产生下降沿中断
- #define PIS 0x08 //输入正极性选择, 0: 选择内部P5.5做正输入, 1: 由ADCIS[2:0]所选择的ADC输入端做正输入.
- #define NIS 0x04 //输入负极性选择, 0: 选择内部BandGap电压BGv做负输入, 1: 选择外部P5.4做输入.
- #define CMPOE 0x02 //1: 允许比较结果输出到P1.2, 0: 禁止.
- #define CMPRES 0x01 //比较结果, 1: CMP+电平高于CMP-, 0: CMP+电平低于CMP-, 只读
- //CMPCR2
- #define INVCMPO 0x80 //1: 比较器输出取反, 0: 不取反
- #define DISFLT 0x40 //1: 关闭0.1uF滤波, 0: 允许
- #define LCDTY 0x00 //0~63, 比较结果变化延时周期数
- #define Pin0 0x01 //IO引脚 Px.0
- #define Pin1 0x02 //IO引脚 Px.1
- #define Pin2 0x04 //IO引脚 Px.2
- #define Pin3 0x08 //IO引脚 Px.3
- #define Pin4 0x10 //IO引脚 Px.4
- #define Pin5 0x20 //IO引脚 Px.5
- #define Pin6 0x40 //IO引脚 Px.6
- #define Pin7 0x80 //IO引脚 Px.7
- #define PinAll 0xFF //IO所有引脚
- /************* 本地变量声明 **************/
- sbit P_ADC = P1^5; //P1.5 比较器转IO输出端
- u16 adc; //ADC中间值, 用户层不可见
- u16 adc_duty; //ADC计数周期, 用户层不可见
- u16 adc_value; //ADC值, 用户层使用
- bit adc_ok; //ADC结束标志, 为1则adc_value的值可用. 此标志给用户层查询,并且清0
- /************* 本地函数声明 **************/
- void ConfigTimer0();
- void ConfigTimer2(u8 ms);
- void main(void)
- {
-
- //IO口初始化
-
- P1M0 |= (Pin0+Pin1+Pin5); //P1.0 P1.1 P1.5脚定义为推挽模式
- P3M0 |= (Pin0+Pin1+Pin2+Pin3+Pin6+Pin7); //P3.0-P3.7脚定义为推挽模式
- P5M1 |= Pin4+Pin5; //P5.4 P5.5设置为高阻输入
-
- //比较器初始化
- CMPCR1 = 0;
- CMPCR2 = 20; //比较结果变化延时周期数, 0~63
- CMPCR1 |= CMPEN; //允许比较器 ENABLE,DISABLE
- // CMPCR1 |= PIE; //允许上升沿中断 ENABLE,DISABLE
- // CMPCR1 |= NIE; //允许下降沿中断 ENABLE,DISABLE
- // CMPCR1 |= PIS; //输入正极性选择, 0: 选择内部P5.5做正输入, 1: 由ADCIS[2:0]所选择的ADC输入端做正输入.
- CMPCR1 |= NIS; //输入负极性选择, 0: 选择内部BandGap电压BGv做负输入, 1: 选择外部P5.4做输入
- // CMPCR1 |= CMPOE; //允许比较结果输出到P1.2, ENABLE,DISABLE
- // CMPCR2 |= INVCMPO; //比较器输出取反, ENABLE,DISABLE
- CMPCR2 |= DISFLT; //内部0.1uF滤波, ENABLE,DISABLE
- ConfigTimer0();
- ConfigTimer2(5);
- EA = 1; //允许全局中断
- while (1)
- {
-
- if(adc_ok) //等待ADC结束
- {
- adc_ok = 0; //清除ADC已结束标志
- Led_buff[0] = Led_Char[adc_value / 10000 % 10];
- Led_buff[1] = Led_Char[adc_value / 1000 % 10];
- Led_buff[1] &= 0x7f; //加小数点
- Led_buff[2] = Led_Char[adc_value / 100 % 10];
- }
- }
- }
- /* 配置并启动T0,10us定时时间 */
- void ConfigTimer0()
- {
- AUXR |= 0x80; //定时器时钟1T模式
- TMOD &= 0xF0; //设置定时器模式
- TL0 = 0x23; //设置定时初值 10微秒@22.1184MHz
- TH0 = 0xFF; //设置定时初值
- TF0 = 0; //清除TF0标志
- ET0 = 1; //允许中断
- PT0 = 1; //高优先级中断
- TR0 = 1; //开始运行
- }
- /* 配置并启动T2,ms-T2定时时间 */
- void ConfigTimer2(u8 ms)
- {
- u32 tmp; //临时变量
-
- tmp = MAIN_Fosc / 12; //定时器计数频率
- tmp = (tmp * ms) / 1000; //计算所需的计数值
- tmp = 65536 - tmp; //计算定时器重载值
- tmp = tmp + 18; //补偿中断响应延时造成的误差
- T2H = (u8)(tmp>>8); //定时器重载值拆分为高低字节
- T2L = (u8)tmp;
-
- AUXR &= 0xEF; // 启动T2定时器 方式 :16位重装模式计数器
- AUXR |= 0x10; // 启动T2定时器
- IE2 &= 0xFB; // 使能T2中断
- IE2 |= 0x04; // 使能T2中断
-
- //ET2 = 1; //使能T2中断
- //T2R = 1; //启动T2定时器
- }
- /********************* Timer0中断函数************************/
- void timer0_int () interrupt 1
- {
- if((CMPCR1 & CMPRES) == 0) P_ADC = 0; //比较器输出高电平
- else //P_ADC输出低电平, 给负输入端做反馈.
- {
- P_ADC = 1; //P_ADC输出高电平, 给负输入端做反馈.
- adc ++; //ADC计数+1
- }
- if(--adc_duty == 0) //ADC周期-1, 到0则ADC结束
- {
- adc_duty = ADC_SCALE; //周期计数赋初值
- adc_value = adc; //保存ADC值
- adc = 0; //清除ADC值
- adc_ok = 1; //标志ADC已结束
- }
- }
- /* T0中断服务函数,执行数码管扫描显示 */
- void InterruptTimer2() interrupt 12
- {
- Led_can();
- WDT_CONTR=0x36; //喂狗 2S
- }
复制代码
|