单片机C51数字频率计程序
/**************************************************
//头文件部分,文件名:plj.h
/**************************************************
#include<reg52.h>
#include<absacc.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
extern const uchar NoDisp=0;//无显示
extern const uchar NoCur=1;//有显示无光标
extern const uchar CurNoFlash=2;//有光标但不闪烁
extern const uchar CurFlash=3;//有光标且闪烁
extern void LcdPos(uchar,uchar);//确定光标位置
extern void LcdWd(uchar);//写字符
extern void LcdWc(uchar);//送控制字(检测忙信号)
extern void LcdWcn(uchar);//送控制字子程序(不检测忙信号)
extern void mDelay(uchar);//延时,毫秒数由j决定
extern void WaitIdle(void);//正常读写操作之前检测LCD控制器状态
extern void RstLcd(void);//复位LCD控制器
extern void WriteChar(uchar c,uchar xPos,uchar yPos);
//在指定的行与列显示指定的字符,xpos:行,ypos:列,c:待显示字符
extern void WriteString(uchar*s,uchar xPos,uchar yPos);
extern void SetCur(uchar Para);//设置光标
extern void ClrLcd(void);//清屏命令
extern void WaitIdle(void);//正常读写操作之前检测LCD控制器状态
extern void mDelay(uchar j);
/**************************************************
/**************************************************
//液晶1602子程序,文件名:1602.c
/**************************************************
;连线图:
; DB0---DPROT.0 DB4---DPROT.4 RS-------------P3.5
; DB1---DPROT.1 DB5---DPROT.5 RW-------------P3.6
; DB2---DPROT.2 DB6---DPROT.6 E--------------P3.7
; DB3---DPROT.3 DB7---DPROT.7 VLCD接10K可调电阻到GND*
;需要11根单片机口线
;80C51的晶振频率为12MHz
;液晶显示程序
;**************************************************/
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit RS= P3^5;
sbit RW= P3^6;
sbit EN= P3^7;
#define DPORT P1
void LcdPos(uchar,uchar);//确定光标位置
void LcdWd(uchar);//写字符
void LcdWc(uchar);//送控制字(检测忙信号)
void LcdWcn(uchar);//送控制字子程序(不检测忙信号)
void mDelay(uchar);//延时,毫秒数由j决定
void WaitIdle();//正常读写操作之前检测LCD控制器状态
//在指定的行与列显示指定的字符,xpos:行,ypos:列,c:待显示字符
void WriteChar(uchar c,uchar xPos,uchar yPos)
{
LcdPos(xPos,yPos);
LcdWd(c);
}
void WriteString(uchar*s,uchar xPos,uchar yPos)
{ uchar i;
if(*s==0)//遇到字符串结束
return;
for(i=0;;i++)
{
if(*(s+i)==0)
break;
WriteChar(*(s+i),xPos,yPos);
xPos++;
if(xPos>=15)//如果XPOS中的值未到15(可显示的最多位)
break;
}
}
void SetCur(uchar Para)//设置光标
{ mDelay(2);
switch(Para)
{ case 0:
{ LcdWc(0x08);//关显示
break;
}
case 1:
{ LcdWc(0x0c);//开显示但无光标
break;
}
case 2:
{ LcdWc(0x0e);//开显示有光标但不闪烁
break;
}
case 3:
{ LcdWc(0x0f);//开显示有光标且闪烁
break;
}
default:
break;
}
}
void ClrLcd()//清屏命令
{ LcdWc(0x01);
}
//正常读写操作之前检测LCD控制器状态
void WaitIdle()
{ uchar tmp;
RS=0;
RW=1;
EN=1;
_nop_();
for(;;)
{ tmp=DPORT;
tmp&=0x80;
if( tmp==0)
break;
}
EN=0;
}
void LcdWd(uchar c)//写字符子程序
{ WaitIdle();
RS=1;
RW=0;
DPORT=c;//将待写数据送到数据端口
EN=1;
_nop_();
_nop_();
EN=0;
}
void LcdWc(uchar c)//送控制字子程序(检测忙信号)
{ WaitIdle();
LcdWcn(c);
}
void LcdWcn(uchar c)//送控制字子程序(不检测忙信号)
{ RS=0;
RW=0;
DPORT=c;
EN=1;
_nop_();
EN=0;
}
void LcdPos(uchar xPos,uchar yPos)//设置第(xPos,yPos)个字符的DDRAM地址
{ unsigned char tmp;
xPos&=0x0f;//x位置范围是0~15
yPos&=0x01;//y位置范围是0~1
if(yPos==0)//显示第一行
tmp=xPos;
else
tmp=xPos+0x40;
tmp|=0x80;
LcdWc(tmp);
}
void RstLcd()//复位LCD控制器
{ mDelay(15);//如果使用12M或以下晶振,此数值不必改,如用24M晶振,须用30
LcdWc(0x38);//显示模式设置
LcdWc(0x08);//显示关闭
LcdWc(0x01);//显示清屏
LcdWc(0x06);//显示光标移动位置
LcdWc(0x0c);//显示开及光标设置
}
void mDelay(uchar j)//延时,毫秒数由j决定
{ uint i=0;
for(;j>0;j--)
{ for(i=0;i<124;i++)
{;}
}
}
//主函数:
/*==================================================================================
公司名称:河海大学电气工程学院*
模块名: AT89C52单片机系统,全国电子设计大赛*
创建人:南东亮日期:2007。7。28*
修改人:*
功能描述:利用AT89S51单片机的T0、T1的定时计数器功能,来完成对输入的信号进行
频率计数,计数的频率结果通过8位动态数码管显示出来。要求能够对0-250KHZ
的信号频率进行准确计数,计数误差不超过±hz
程序设计内容:
1)定时/计数器T0和T1的工作方式设置,由图可知,T0是工作在计数状态下,
对输入的频率信号进行计数,当T/C工作在定时器时,计数脉冲来自外部脉冲
输入管脚T0(P3。4)或T1(P3。5),当T0或T1产生负跳变时计数器加1。识别
管脚的负跳变需要两个机器周期,即24个振荡周期。以T0或T1脚输入的
可计数外部脉冲的最高频率为1/24Fosc。但对工作在计数状态下的T0,
最大计数值为fOSC/24,由于fOSC=12MHz因此:T0的最大计数频率为500KHz?
高于此频率将出错。
对于频率的概念就是在一秒只数脉冲的个数,即为频率值
所以T1工作在定时状态下,每定时1秒钟到,就停止T0的计数,
而从T0的计数单元中读取计数的数值,然后进行数据处理。
送到数码管显示出来。
2)T1工作在定时状态下,最大定时时间为65ms,达不到1秒的定时,
所以采用定时50ms,共定时20次,即可完成1秒的定时功能。
*
//;*其他说明:产品为设计阶段*
*/
//;==================================================================================
//;主程序开始
//;==================================================================================
#include"plj.h"
unsigned char code table1[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};//0123456789
//unsigned char code table2[]={0x41,0x42,0x43,0x44,0x45,0x46};//abcdef
uchar*s=" CYMOMETER";
uchar*s1="FREQ: Hz";
uchar T0count;//从T0的计数单元中读取计数的数值
uchar timecount;//
bit flag;//标志位
unsigned long x;
uchar xPos,yPos;
uchar i;
void main(void)
{
RstLcd();//初始化LCD
ClrLcd();//清屏
SetCur(1);//开光标显示、闪烁
WriteString(s,0,0);
WriteString(s1,0,1);
TMOD=0x15;//T0工作为16位计数器(方式1),T1工作方式为16位定时器
TH0=0;//计数为65536
TL0=0;//
TH1=(65536-4000)/256;//定时器采用定时4ms.初值为4000
TL1=(65536-4000)%256;
TR1=1;//TR1=1,控制开关闭合,计数脉冲进入T1计数器,启动定时
TR0=1;//TR0=1,控制开关闭合,计数脉冲进入T1计数器,启动计数
ET0=1;//定时器0开中断
ET1=1;//定时器1开中断
EA=1;//CPU开中断
while(1)
{
if(flag==1)//
{
flag=0;//清标志位
x=T0count*65536+TH0*256+TL0;//取得时间宽度参数
//LCD显示部分代码
//;==================================================================================
LcdPos(15,1);
WriteChar(table1[x%10],11,1);
WriteChar(table1[(x/10)%10],10,1);
WriteChar(table1[(x/100)%10],9,1);
WriteChar(table1[(x/1000)%10],8,1);
WriteChar(table1[(x/10000)%10],7,1);
WriteChar(table1[(x/100000)%10],6,1);
//;==================================================================================
timecount=0;
T0count=0;
TH0=0;
TL0=0;
TR0=1;//TR0=1,控制开关闭合,计数脉冲进入T1计数器,启动计数
}
}
}
//;==================================================================================
void t0() interrupt 1 using 0//T0中断服务
{
T0count++;//对P3。4口的脉冲进行计数
}
//;==================================================================================
void t1(void) interrupt 3 using 0//T1中断服务
{
TH1=(65536-4000)/256;//计数初值重装载
TL1=(65536-4000)%256;
timecount++;
if(timecount==250)
{
TR0=0;
timecount=0;
flag=1;//置标志
}
}<
单片机(Microcontroller)是一种小型的计算机系统,它集成了处理器、存储器、输入输出接口和定时器等基本功能模块,以实现控制任务的执行。
单片机通常集成在嵌入式系统中,可完成数据采集、控制、通信、和信号处理等功能,并具有低功耗、高集成度和成本相对较低的优点。
单片机主要用途
1、家电:单片机可以用于电视机、洗衣机、空调、电烤箱、微波炉、灶具等家用电器的控制和管理,并且实现多种智能控制,如定时、温度或湿度控制等。
2、智能家居:单片机可以用于连接物联网,实现智能家居控制,例如室内照明、温度、湿度控制,以及智能门禁、智能插座、智能家居安全等。
3、医疗:单片机可以用于医疗设备中,例如牙齿拍片机、便携式超声扫描仪、治疗器、血糖监测器等,实现人体生理参数的监测和控制。
4、工业自动化:单片机可以用于各种工业控制系统中,例如工厂生产线、机器人、商用车辆等,实现自动化、高效率、高精度的控制和管理。
5、仪器控制:单片机可以用于各种科学仪器的控制和管理,例如光谱仪、气相色谱仪、温控设备等。
6、交通运输:单片机可以应用于交通运输领域,例如智能交通信号灯、智能公交车卫星定位、交通摄像头等,实现交通流量的控制和安全管理。
7、金融支付:单片机还可以用于金融支付设备中,例如ATM机、POS机、智能自助支付终端等,以实现高效、安全的支付操作。
单片机具有功能强大、可靠性高、功耗低、体积小、成本低廉等优点,单片机在工程技术、电子商务、娱乐、金融、医疗、工业自动化等领域都有着广泛的应用。
#include<reg51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_EN=P2^2;
sbit SPK=P3^0;
sbit key1=P1^0;
sbit key2=P1^1;
sbit key3=P1^2;
sbit key4=P1^3;
uchar Display_Buffer[16]="";
uchar Count,hour=12,min=12,sec=12;
bit flag,H_or_M;
uchar display[]="This is colck";
void _delay_ms(uint x)
{
uchar i;
while(x--)
{
for(i=0;i<120;i++);
}
}
/**********************************************************************
*函数名称:LCD_Write_Command
*输入:uchar cmd
*输出:无
*功能:向LCD1602写指令
**********************************************************************/
void LCD_Write_Command(uchar cmd)
{
LCD_RS=0;//根据规定,RS和R/W同时为低电平时,可以写入指令
LCD_RW=0;
LCD_EN=0;//EN置低电平
P0=cmd;//将数据送入P2口,即写入指令或地址
LCD_EN=1;//EN置高电平
_delay_ms(1);//稍延时,给硬件反应时间
LCD_EN=0;//当EN由高电平跳变成低电平时,液晶模块开始执行命令
}
/**********************************************************************
*函数名称:LCD_Write_Data
*输入:uchar dat
*输出:无
*功能:向LCD1602写数据
**********************************************************************/
void LCD_Write_Data(uchar dat)
{
LCD_RS=1;//RS为高电平,RW为低电平时,可以写入数据
LCD_RW=0;
LCD_EN=0;//EN置低电平
P0=dat;//将数据送入P0口,即将数据写入液晶模块
LCD_EN=1;//EN置高电平
_delay_ms(1);//稍延时,给硬件反应时间
LCD_EN=0;//当EN由高电平跳变成低电平时,液晶模块开始执行命令
}
/**********************************************************************
*函数名称:Init_LCD
*输入:无
*输出:无
*功能:初始化LCD1602
**********************************************************************/
void Init_LCD(void)
{
LCD_Write_Command(0x38);//显示模式设置:16×2显示,5×7点阵,8位数据接口
_delay_ms(1);
LCD_Write_Command(0x06);//显示模式设置:光标右移,字符不移
_delay_ms(1);
LCD_Write_Command(0x0c);//显示模式设置:显示开,无光标,光标不闪烁
_delay_ms(1);
LCD_Write_Command(0x01);//清屏幕指令,将以前的显示内容清除
_delay_ms(1);
}
/**********************************************************************
*函数名称:LCD_POS
*输入:uchar pos
*输出:无
*功能:字符显示位置
**********************************************************************/
void LCD_POS(uchar pos)
{
LCD_Write_Command(0x80|pos);//显示位置的确定方法规定为"80H+地址码x"
}
/**********************************************************************
*函数名称:Show_String
*输入:uchar*str
*输出:无
*功能:LCD1602显示字符串处理函数
**********************************************************************/
void Show_String(uchar*str)
{
while(*str!='\0')//只要没有写到结束标志,就继续写
LCD_Write_Data(*str++);//将字符常量写入LCD,并指向下一个字符
}
void song(void)
{
uchar i,j,k;
for(i=0;i<200;i++)
{
SPK=~SPK;
for(k=0;k<50;k++);
for(j=0;j<50;j++);
}
}
/////lcd1602液晶显示//////
void Display_Time(uchar Hour,uchar Min,uchar Sec)
{
Display_Buffer[0]=Hour/10+'0';//小时十位
Display_Buffer[1]=Hour%10+'0';//小时个位
Display_Buffer[2]=':';//显示:号
Display_Buffer[3]=Min/10+'0';//显示分钟十位
Display_Buffer[4]=Min%10+'0';//显示分钟个位
Display_Buffer[5]=':';//显示:号
Display_Buffer[6]=Sec/10+'0';//显示秒十位
Display_Buffer[7]=Sec%10+'0';//显示秒个位
LCD_POS(0x40);//显示在液晶第1行第0列
Show_String(Display_Buffer);
}
/////按键处理//////
void Set_time(void)
{
flag=0;
if(key1==0||key2==0||key3==0)//若key1,key2,key3其中有键按下,则为真
{
TR0=0;//定时器0停止
flag=1;//按键标志位为真
}
while(flag)//判断那一个按键按下
{
if(key1==0)//判断key1是否按下
{
while(!key1);//等待释放
H_or_M=!H_or_M;//选择是修改时还是分钟
}
else if(key2==0)//判断key2是否被按下
{
while(!key2);//等待释放
if(H_or_M)//若H_OR_M为真,则修改小时
{
if(++hour==24)//若小时=24,则小时=0
hour=0;//小时加1
}
else//否则修改分钟
{
if(++min==60)//若分钟等于60,则分钟等于0
min=0;//分钟加1
}
}
else if(key3==0)//判断key3是否被按下
{
while(!key3);//等待释放
if(H_or_M)//若H_OR_M为真,则修改小时
{
if(--hour==0xff)//小时减1,若小时等于-1,则小时等于23
hour=23;
}
else//否则修改分钟
{
if(--min==0xff)//分钟减1,若分钟等于-1,则分钟等于59
min=59;
}
}
else if(key4==0)//判断key4是否被按下
{
while(!key4);//等待释放
flag=0;//按键标志清零
TR0=1;//定时器0启动
}
Display_Time(hour,min,sec);//传H,M,S值显示到液晶
}
}
void timer0_init(void)//定时器0初始化
{
TMOD=0x01;//定时器0,方式1
ET0=1;//
EA=1;//总中断允许
TR0=1;//启动定时器0
TH0=(65535-50000)/256;//装高8位初值
TL0=(65535-50000)%256;//装低8位初值
}
void main(void)//主函数
{
//P0=0xff;
P1=0xff;//端口初始化
P3=0xff;
Init_LCD();//液晶初始化
timer0_init();//定时器0初始化
LCD_POS(0);//显示在液晶第1行第0列
Show_String(display);
while(1)//无限循环
{
Display_Time(hour,min,sec);//液晶显示时间
//_delay_ms(500);//延时
Set_time();//时间调整
}
}
void timer0() interrupt 1//定时器0中断
{
TH0=(65535-50000)/256;//重装定时器0高8位
TL0=(65535-50000)%256;//重装定时器0低8位
Count++;//计数加1
if(Count==20)//如果COUNT等于20
{
Count=0;//计数清零
sec++;//秒加1
if(sec==60)//判断秒是否等于60
{
sec=0;//秒清零
min++;//分钟加1
if(min==60)//判断分钟是否等于60
{
min=0;//若等于60,则清零分钟
hour++;//小时加1
if(hour==24)//判断小时是否等于24
{
hour=0;//若小时等于24,则清零小时,分钟,秒
min=0;
sec=0;
}
song();
}
}
}
}
本文暂时没有评论,来添加一个吧(●'◡'●)