目录
一、自己写过程中遇到的问题
1、U范围对应L3亮灭总是不对
用Rb2的范围!!!!
2、频率测量不正确(范围0-300之间)
dat_Hz、count_Hz用int!!!!
二、代码(自己写的)功能基本实现
#include "reg52.h"
#include "iic.h"
unsigned char code SMG_duanma[20] = {
// 0 1 2 3 4 5 6 7
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
// 8 9 A10 B11 C12 D13 E14 F15
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
// -16 .17
0xbf,0x7f,0xff,0xc1}; //共阳数码管
unsigned char code SMG_duanmaDot[19] = {
// 0. 1. 2. 3. 4. 5. 6. 7.
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,
// 8. 9. A10 B11 C12 D13 E14 F15
0x00,0x10,0x88,0x80,0xc6,0xc0,0x86,0x8e,
// -16 .17
0xbf,0x7f,0xff}; //数码管(小数点)
unsigned char yi, er, san, si, wu, liu, qi, ba;
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
unsigned char Rb2 = 0; U = 0; U_flat = 0;
unsigned int count_Hz = 0;//每秒变化次数计数(频率)
unsigned char count = 0;//1s
unsigned int dat_Hz = 0;//缓存上一秒频率
unsigned char count_ad = 0;//电压数据刷新时间<=0.5s
unsigned char jiemian = 1;//1:电压显示界面(上电默认) / 2:频率显示界面
unsigned char DACmode = 1;//1:固定输出2v(上电默认)/ 2:输出=Rb2电压
unsigned char LEDkongzhi = 1;//1:LED功能启用(上电默认) / 2:禁用
unsigned char SMGkongzhi = 1;//1:数码管显示功能启用(上电默认) / 2:禁用
void InitHC138(unsigned char n)
{
switch(n)
{
case 4:
P2 = (P2 & 0x1f) | 0x80;
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0;
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;
break;
}
}
void Delayms(unsigned int ms)
{
unsigned int i, j;
for (i = ms; i > 0; i--)
for (j = 845; j > 0; j--);
}
/*==================初始化系统=================================================
============================================================================*/
void InitSystem()
{
InitHC138(4);
P0 = 0xff;
InitHC138(5);
P0 = 0x00;
}
/*==================数码管=====================================================
============================================================================*/
void SMG_Bit(unsigned pos, unsigned char dat)
{
InitHC138(7);
P0 = 0xff;//消影
InitHC138(6);
P0 = 0x01 << pos;
InitHC138(7);
P0 = dat;
}
void SMG_All(unsigned char dat)
{
InitHC138(6);
P0 = 0xff;
InitHC138(7);
P0 = dat;
}
void ShowSMG()
{
SMG_Bit(0, SMG_duanma[yi]);
Delayms(1);
SMG_Bit(1, SMG_duanma[er]);
Delayms(1);
SMG_Bit(2, SMG_duanma[san]);
Delayms(1);
SMG_Bit(3, SMG_duanma[si]);
Delayms(1);
SMG_Bit(4, SMG_duanma[wu]);
Delayms(1);
if (jiemian == 2)//频率显示界面
{
SMG_Bit(5, SMG_duanma[liu]);
Delayms(1);
}
else if (jiemian == 1)//电压显示界面(有小数)
{
SMG_Bit(5, SMG_duanmaDot[liu]);
Delayms(1);
}
SMG_Bit(6, SMG_duanma[qi]);
Delayms(1);
SMG_Bit(7, SMG_duanma[ba]);
Delayms(1);
SMG_All(0xff);//数码管最后一位太亮
}
/*==================按键=======================================================
S4:“界面切换”(循环切换)
S5:“输出模式切换”(循环切换)
①DAC输出电压跟随Rb2输出电压变化
②固定输出2.0V
S6:“LED功能控制”(循环切换)
①功能启用
②功能禁止
S7:“数码管显示功能控制”(循环切换)
①显示启用
②显示禁用
============================================================================*/
void ScanKeys()
{
if (S7 == 0)
{
Delayms(5);
if (S7 == 0)//“数码管显示功能控制”
{
if (SMGkongzhi == 1) SMGkongzhi = 2;
else if (SMGkongzhi == 2)
{
SMGkongzhi = 1;
yi = 18; er = 18; san = 18; si = 18; wu = 18; liu = 18; qi = 18; ba = 18;
}
}
while(!S7)
{
ShowSMG();
}
}
else if (S6 == 0)//“LED功能控制”
{
Delayms(5);
if (S6 == 0)
{
if (LEDkongzhi == 1) LEDkongzhi = 2;
else if (LEDkongzhi == 2) LEDkongzhi = 1;
}
while(!S6)
{
ShowSMG();
}
}
else if (S5 == 0)//“输出模式切换”
{
Delayms(5);
if (S5 == 0)
{
if (DACmode == 1) DACmode = 2;
else if (DACmode == 2) DACmode = 1;
}
while(!S5)
{
ShowSMG();
}
}
else if (S4 == 0)//“界面切换”
{
Delayms(5);
if (S4 == 0)
{
if (jiemian == 1) jiemian = 2;
else if (jiemian == 2) jiemian = 1;
}
while(!S4)
{
ShowSMG();
}
}
}
/*==================AD=======================================================
电压数据刷新时间<=0.5s
============================================================================*/
unsigned char AD_read(unsigned AIN)//选择通道
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0x90);//写0允许
IIC_WaitAck();
IIC_SendByte(AIN);
IIC_WaitAck();
IIC_Stop();
//Delayms(200);
IIC_Start();
IIC_SendByte(0x91);//读1允许
IIC_WaitAck();
temp = IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
return temp;
}
/*==================DA输出=======================================================
============================================================================*/
void OutDA(unsigned char dat)
{
IIC_Start();
IIC_SendByte(0x90);//写0允许
IIC_WaitAck();
IIC_SendByte(0x40);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
/*==================NE555+定时器01=======================================================
频率数据刷新时间<=1s
用两个定时器:T0计数(1s计数多少次=>频率(单位时间变化次数))8位自动重装
T1定时(1s)16位
============================================================================*/
void InitTimer()
{
TMOD = 0x16;//0x06 | 0x10
//定时器0:(8位)计数
TH0 = 0xff;
TL0 = 0xff;
ET0 = 1;
TR0 = 1;
//定时器1:(16位)定时1s = 1000ms = 100 0000us = 20*50000us
TH1 = (65535 - 50000 + 1)/256;//+1:有1us误差
TL1 = (65535 - 50000 + 1)%256;
ET1 = 1;
TR1 = 1;
EA = 1;//打开总中断
}
void ServiceTimer0() interrupt 1 //计数
{
count_Hz++;//记住用int型!!!!!
}
void ServiceTimer1() interrupt 3 //定时
{
TH1 = (65535 - 50000 + 1)/256;//+1:有1us误差
TL1 = (65535 - 50000 + 1)%256;
count++;
count_ad++;
if (count == 20)//1s(频率数据刷新时间<=1s)
{
dat_Hz = count_Hz;//记住用int型!!!!!
count = 0;
count_Hz = 0;//清零,计算下一秒频率
}
if (count_ad == 5)//0.25s(电压数据刷新时间<=0.5s)
{
count_ad = 0;
Rb2 = AD_read(3);
U = Rb2*0.01961;
}
}
//******************主函数*******************************************************
void main()
{
InitSystem();
InitTimer();
OutDA(102);//2V:0-255 1v-51 2v-102
yi = 19; er = 18; san = 18; si = 18; wu = 18; liu = 3; qi = 4; ba = 1;
while(1)
{
ShowSMG();
ScanKeys();
//数码管界面显示
if ((jiemian == 1) && (SMGkongzhi == 1))//电压显示界面
{
U_flat = Rb2*0.01961*100;
yi = 19; er = 18; san = 18; si = 18; wu = 18; liu = U_flat/100; qi = (U_flat/10)%10; ba = U_flat%10;
}
else if ((jiemian == 2) && (SMGkongzhi == 1))//频率显示界面
{
yi = 15; er = 18;
if (dat_Hz > 99999)//六位数码管123456
{
san=dat_Hz/100000;si=(dat_Hz/10000)%10;wu =(dat_Hz/1000)%10;liu=(dat_Hz/100)%10;qi=(dat_Hz/10)%10;ba=dat_Hz%10;
}
else if (dat_Hz > 9999)//五位12345
{
san=18;si=dat_Hz/10000;wu=(dat_Hz/1000)%10;liu=(dat_Hz/100)%10;qi=(dat_Hz/10)%10;ba=dat_Hz%10;
}
else if (dat_Hz > 999)//四位1234
{
san=18;si=18;wu=dat_Hz/1000;liu=(dat_Hz/100)%10;qi=(dat_Hz/10)%10;ba=dat_Hz%10;
}
else if (dat_Hz > 99)//三位123
{
san=18;si=18;wu=18;liu=dat_Hz/100;qi=(dat_Hz/10)%10;ba=dat_Hz%10;
}
else if (dat_Hz > 9)//两位12
{
san=18;si=18;wu=18;liu=18;qi=dat_Hz/10;ba=dat_Hz%10;
}
else if (dat_Hz >= 0)//一位1
{
san=18;si=18;wu=18;liu=18;qi=18;ba=dat_Hz%10;
}
}
//DAC输出模式
if (DACmode == 1)//输出固定电压2.0V
{
OutDA(102);
}
else if (DACmode == 2)//输出=Rb2电压
{
OutDA(Rb2);
}
/*LED功能:电压测量:L1亮 / L2熄灭
频率测量:L1熄灭 / L2亮
L3:电压:U<1.5灭 / 1.5<=U<2.5亮 / 2.5<=U<3.5灭 / U>=3.5亮
L4:频率:F<1K灭 / 1K<=F<5K亮 / 5K<=F<10K灭 / F>=10K亮
L5:DAC固定输出时灭 / 变化输出亮*/
if (LEDkongzhi == 1)//LED功能启用()
{
if (jiemian == 1)//电压测量L1亮
{
if (DACmode == 1)//(固定输出)L5灭
{
if (Rb2 < 78 || ((Rb2>=127.5) && (Rb2<178.5)))//L3灭
{
InitHC138(4); P0 = 0xfe;//1111 1110
}
else if (Rb2 >= 178.5 || ((Rb2>=78) && (Rb2<127.5)))//L3亮
{
InitHC138(4); P0 = 0xfa;//1111 1010
}
}
else if (DACmode == 2)//(变化输出)L5亮
{
if (Rb2<78 || ((Rb2>=127.5) && (Rb2<178.5)))//L3灭
{
InitHC138(4); P0 = 0xee;//1110 1110
}
else if (Rb2>=178.5 || ((Rb2>=78) && (Rb2<127.5)))//L3亮
{
InitHC138(4); P0 = 0xea;//1110 1010
}
}
}
else if (jiemian == 2)//频率测量L2亮
{
if (DACmode == 1)//(固定输出)L5灭
{
if (dat_Hz<1000 || ((dat_Hz>=5000) && (dat_Hz<10000)))//L4灭
{
InitHC138(4); P0 = 0xfd;//1111 1101
}
else if (dat_Hz>=10000 || ((dat_Hz>=1000) && (dat_Hz<5000)))//L4亮
{
InitHC138(4); P0 = 0xf5;//1111 0101
}
}
else if (DACmode == 2)//(变化输出)L5亮
{
if (dat_Hz<1000 || ((dat_Hz>=5000) && (dat_Hz<10000)))//L4灭
{
InitHC138(4); P0 = 0xed;//1110 1101
}
else if (dat_Hz>=10000 || ((dat_Hz>=1000) && (dat_Hz<5000)))//L4亮
{
InitHC138(4); P0 = 0xe5;//1110 0101
}
}
}
}
else if (LEDkongzhi == 2)//LED功能禁用
{
InitHC138(4); P0 = 0xff;
}
//数码管功能
if (SMGkongzhi == 2)
{
yi = 18; er = 18; san = 18; si = 18; wu = 18; liu = 18; qi = 18; ba = 18;
}
}
}
三、代码改进:
数码管改进:加小数点(码值+10)
unsigned char code SMG_duanma[30] = {
// 0 1 2 3 4 5 6 7
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
// 8 9
0x80,0x90,//无小数点
// 0.10 1.11 2.12 3.13 4.14 5.15 6.16 7.17
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,
// 8.18 9.19
0x00,0x10,//(+10)小数点!
// A20 B21 C22 D23 E24 F25
0x88,0x80,0xc6,0xc0,0x86,0x8e,
// -26 .27 关28 U29
0xbf,0x7f,0xff,0xc1}; //共阳数码管