📄 main.c
字号:
//***********************************
//单片机为16f877a 晶震为8m
//************************************
#include <pic.h>
#include <math.h>
__CONFIG(0x1f76);
extern void initset(); //定义引用的函数
void delay_1000() ;
//extern void moniled (char led_data);
unsigned char fADConverter(unsigned char ChannelNum); //函数声明
unsigned char comp(unsigned char temp4);
unsigned char dycomp(unsigned char temp9);
unsigned int Rpm(unsigned char temp);
void DYdisplay(unsigned int x1);
void Rpmdisplay(unsigned int x);
void DELAY11();
bit rb0inc,compok,compok1;
persistent char lednum,lednuml,lednumh;
persistent unsigned char pinlv,pinlvback,count=0;
unsigned int Data,tempint,rpmyushu=0,dyback,tempback,dytemp,dyyushu=0,rpmtemp;
unsigned char pinlvtemp=0,temp=0;
const char ledtab[10]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XD8,0X80,0X90 }; //不带小数点LED段码表0-9,高电平灭 共阳LED
const char ledtab1[10]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X58,0X00,0X10 };//带小数点LED段码表0-9,高电平灭 共阳LED
#define nop() asm("nop")
#define FBOUT RA2 //方波输出端口
#define GEWEI RC6 //转速显示位控制端口
#define SHIWEI RC3
#define BAIWEI RC5
#define QIANWEI RC4
#define DYGEWEI RC0 //电压显示位控制端口
#define DYSHIWEI RC1
#define DYBAIWEI RC2
//********************************************************/
//中断子程序
//Timer2中断服务子程序,方波发生器 1ms中断一次
//********************************************************/
void interrupt IRQ(void)
{
if(TMR2IF)
{
TMR2IF=0;
++pinlvtemp;
if(pinlvtemp==pinlv)
{
FBOUT=!FBOUT ;
pinlvtemp=0;
}
}
}
//*********************************************************/
//*********************************************************/
inirb0int() //中断初使化
{
lednuml=0;
lednumh=0;
}
//***************************************************/
//AD转换
//***************************************************/
unsigned char fADConverter(unsigned char ChannelNum)
{
unsigned char ad_result = 0;
ADCON0 =ChannelNum; //ADON
nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
//sample time
ADGO=1;
while(ADGO);
ad_result = ADRESH;
return(ad_result); //得到的数据为转速频率,或为电压数据
}
//***************************************************/
//比较两次转速数据,看是否刷新
//***************************************************/
unsigned char comp(unsigned char temp4)
{
if(count==0) // 第1次需要保存上次采集的数据
{
pinlvback=temp4;
count=1;
return(temp4); //返回当前的转速的周期数据
}
else
{
if(pinlvback==temp4) //如果上次采集的数据与这次相等,则标志成立
{compok=1;return(temp4); }
else
{compok=0;pinlvback=temp4;return(temp4); }
}
}
//***************************************************/
//比较两次电压数据,看是否刷新
//***************************************************/
unsigned char dycomp(unsigned char temp9)
{
if(count==0) // 第1次需要保存上次采集的数据
{
dyback=temp9;
count=1;
return(temp9); //返回当前的转速的周期数据
}
else
{
if(dyback==temp9) //如果上次采集的数据与这次相等,则标志成立
{compok1=1;return(temp9); }
else
{compok1=0;dyback=temp9;return(temp9); }
}
}
//***************************************************/
//求转速数据
//temp为当前转速的频率,此数据依据AD值得到
//***************************************************/
unsigned int Rpm( unsigned char temp5)
{ unsigned int temp11;
temp5=(unsigned char)temp5/2; //除2 周期最大值为127MS,1代表周期时间为1ms的意思
if(temp5<12) {temp5=12;} //转速设置最高为6*2=12MS rpm=1000/12*60=5000 最小为 =1000/127*60
pinlv=temp5;
pinlv=pinlv/2; //除4,周期的一半
temp11=(unsigned int)1000/temp5; //强制转换成整形
temp11=temp11*60 ; //求转速
nop();
return(temp11); //返回当前的转数值
}
//**********************************************
//转速数据显示
//**********************************************
void Rpmdisplay(unsigned int x)
{int qian,bai,shi,ge;
unsigned int temp;
PORTC=0;
temp=x;
qian=temp/0x3e8;
PORTD=ledtab[qian]; //查表得千位显示的代码
NOP();
NOP();
PORTD=ledtab[qian]; //查表得千位显示的代码
QIANWEI=1; //千位输出低电平,点亮千位显示
// DELAY11(); //延时一定时间,保证显示亮度
QIANWEI=0;
bai=(temp%0x3e8)/0x64;
PORTD=ledtab[bai]; //查表得百位显示的代码
BAIWEI=1; //点亮百位显示
// DELAY11();
BAIWEI=0;
shi=((temp%0x3e8)%0x64)/0xa;
PORTD=ledtab[shi]; //查表得十位显示的代码
SHIWEI=1; //点亮十位显示
// DELAY11();
SHIWEI=0;
ge=((temp%0x3e8)%0x64)%0xa;
PORTD=ledtab[ge]; //求个位显示的代码
GEWEI=1; //点亮个位显示
// DELAY11();
GEWEI=0;
}
//****************************************************/
//电压数据显示
//****************************************************/
void DYdisplay(unsigned int x1)
{int DYbai,DYshi,DYge;
unsigned int temp;
PORTC=0;
temp=x1;
DYbai=temp/0x64;
PORTD=ledtab1[DYbai]; //查表得百位显示的代码
DYBAIWEI=1; //点亮百位显示
DELAY11();
PORTC=0;
DYshi=(temp%0x64)/0xa;
PORTD=ledtab[DYshi]; //查表得十位显示的代码
DYSHIWEI=1; //点亮十位显示
DELAY11();
PORTC=0;
DYge=(temp%0x64)%0xa;
PORTD=ledtab[DYge]; //求个位显示的代码
DYGEWEI=1; //点亮个位显示
DELAY11();
PORTC=0;
}
//**********************************************
//**********************************************
void DELAY11()
{
int i;
for(i=0;i<=30;i++)
continue;
}
//***************************************************/
//求电压数据,
//temp为当前转速的频率,此数据依据AD值得到
//***************************************************/
unsigned int DYDATA(unsigned char temp)
{unsigned int temp1=0;
temp1=temp*1.96 ;
return(temp1); //返回当前的电压值,当数据为255时,返回的值为499 ,此处的数据为*100的数据
}
//*********************1ms精确延时***************************
void delay_1000() //1.008ms
{
unsigned char i,j;
for(i=0x03;i>0;i--)
for(j=110;j>0;j--);
}
//*************************************************************
//延时程序(Xms)
void DELAY(unsigned int x)
{
unsigned char j;
for(;x--;)
{
for(j=110;--j;) continue;
}
}
//****************************************************************/
//****************************************************************/
void main()
{
initset();
compok=0;
compok1=0;
GIE=1 ;
while(1)
{
CLRWDT(); //看门狗
DELAY(80);
rpmtemp=fADConverter(0x49) ; //求频率 AN1通道 fose=32 AN1为0x89
rpmtemp=comp(rpmtemp);
if(compok!=1)
{
rpmyushu=Rpm(rpmtemp); //求转速数据
Rpmdisplay(rpmyushu); //转速数据显示
}
CLRWDT(); //看门狗
DELAY(80);
dytemp=fADConverter(0x41) ; //电压值 AN0通道 fose=32
dytemp=dycomp(dytemp);
if(compok1!=1)
{dyyushu=DYDATA(dytemp); //返回当前的电压数据
DYdisplay(dyyushu);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -