合肥POS机办理 | 快速申请与安装服务 - 合肥POS网
手机:13029808955
电话:13029808955
邮箱:478084072.com
地址:合肥市蜀山区科技园区创新大道88号
发布时间:2024-04-07 点此:42次
单片机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;//置标志
}
}<
该程序演示了如何用鼠标来获得任何像素的RGB颜色。该程序使用了计时器,间隔设置为0.01秒来捕捉事件,使用了GetPixel, GetCursorPos和GetDC WinAPI调用,来获得屏幕上任何地方的像素的颜色。
option Explicit
'在表单中加入计时器,使用鼠标移动到屏幕上任何一处,RGB颜色就会显示在表单中的Caption中
'
private Type POINTAPI
x as Long
y as Long
End Type
'
private Declare Function GetPixel Lib"gdi32"(byval hdc as Long, _
byval x as Long, byval y as Long) as Long
private Declare Function GetCursorPos Lib"user32"(lpPoint as POINTAPI) as Long
private Declare Function GetWindowDC Lib"user32"(byval hwnd as Long) as Long
'
private Sub Form_Load()
Timer1.Interval= 100
End Sub
'
private Sub Timer1_Timer()
Dim tPOS as POINTAPI
Dim sTmp as string
Dim lColor as Long
Dim lDC as Long
'
lDC= GetWindowDC(0)
Call GetCursorPos(tPOS)
lColor= GetPixel(lDC, tPOS.x, tPOS.y)
Label2.BackColor= lColor
'
sTmp= Right$("000000"& Hex(lColor), 6)
Caption="R:"& Right$(sTmp, 2)&" G:"& mid$(sTmp, 3, 2)&" B:"& Left$(sTmp, 2)
End Sub
至于获取当前窗口,可以使用
Public Declare Function GetForegroundWindow Lib"user32"() As Long
获取当前活动窗体的句柄,再使用GetWindowText的API能获取到相应的标题啦!
Public Declare Function GetForegroundWindow Lib"user32"() As Long
Public Declare Function SendMessage Lib"user32" Alias"SendMessageA"(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const WM_GETTEXT=&HD
Public Function GetWin() As String
Dim tmp As Long
Dim iLen As Long
Dim Txt As String
tmp= GetForegroundWindow
Txt= String(255, Chr(0))
iLen= SendMessage(tmp, WM_GETTEXT, Len(Txt), ByVal Txt)
Txt= Left(Txt, iLen)
GetWin=Txt
End Function
以上代码是获取当前窗体的标题代码!(这里没使用GetWindowText的API)
宏定义
宏定义是C提供的三种预处理功能的其中一种,这三种预处理包括:宏定义、文件包含、条件编译
编辑本段1.不带参数的宏定义:
宏定义又称为宏代换、宏替换,简称“宏”。
格式:
#define标识符字符串
其中的标识符就是所谓的符号常量,也称为“宏名”。
预处理(预编译)工作也叫做宏展开:将宏名替换为字符串。
掌握"宏"概念的关键是“换”。一切以换为前提、做任何事情之前先要换,准确理解之前就要“换”。
即在对相关命令或语句的含义和功能作具体分析之前就要换:
例:
#define PI 3.1415926
把程序中出现的PI全部换成3.1415926
说明:
(1)宏名一般用大写
(2)使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。例如:数组大小常用宏定义
(3)预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查。
(4)宏定义末尾不加分号;
(5)宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头。
(6)可以用#undef命令终止宏定义的作用域
(7)宏定义可以嵌套
(8)字符串""中永远不包含宏
(9)宏定义不分配内存,变量定义分配内存。
编辑本段2.带参数的宏定义:
除了一般的字符串替换,还要做参数代换
格式:
#define宏名(参数表)字符串
例如:#define S(a,b) a*b
area=S(3,2);第一步被换为area=a*b;,第二步被换为area=3*2;
类似于函数调用,有一个哑实结合的过程:
(1)实参如果是表达式容易出问题
#define S(r) r*r
area=S(a+b);第一步换为area=r*r;,第二步被换为area=a+b*a+b;
正确的宏定义是#define S(r)((r)*(r))
(2)宏名和参数的括号间不能有空格
(3)宏替换只作替换,不做计算,不做表达式求解
(4)函数调用在编译后程序运行时进行,并且分配内存。宏替换在编译前进行,不分配内存
(5)宏的哑实结合不存在类型,也没有类型转换。
(6)函数只有一个返回值,利用宏则可以设法得到多个值
(7)宏展开使源程序变长,函数调用不会
(8)宏展开不占运行时间,只占编译时间,函数调用占运行时间(分配内存、保留现场、值传递、返回值
C语言宏定义技巧(常用宏定义)
写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性等等。
下面列举一些成熟软件中常用得宏定义:
1,防止一个头文件被重复包含
#ifndef COMDEF_H
#define COMDEF_H
//头文件内容
#endif
2,重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。
typedef unsigned char boolean;/* Boolean value type.*/
typedef unsigned long int uint32;/* Unsigned 32 bit value*/
typedef unsigned short uint16;/* Unsigned 16 bit value*/
typedef unsigned char uint8;/* Unsigned 8 bit value*/
typedef signed long int int32;/* Signed 32 bit value*/
typedef signed short int16;/* Signed 16 bit value*/
typedef signed char int8;/* Signed 8 bit value*/
3,得到指定地址上的一个字节或字
#define MEM_B( x)(*((byte*)(x)))
#define MEM_W( x)(*((word*)(x)))
4,求最大值和最小值
#define MAX( x, y)(((x)>(y))?(x):(y))
#define MIN( x, y)(((x)<(y))?(x):(y))
5,得到一个field在结构体(struct)中的偏移量
#define FPOS( type, field)\
/*lint-e545*/((dword)&(( type*) 0)-> field)/*lint+e545*/
6,得到一个结构体中field所占用的字节数
#define FSIZ( type, field) sizeof(((type*) 0)->field)
7,按照LSB格式把两个字节转化为一个Word
#define FLIPW( ray)((((word)(ray)[0])* 256)+(ray)[1])
8,按照LSB格式把一个Word转化为两个字节
#define FLOPW( ray, val)\
(ray)[0]=((val)/ 256);\
(ray)[1]=((val)& 0xFF)
9,得到一个变量的地址(word宽度)
#define B_PTR( var)((byte*)(void*)&(var))
#define W_PTR( var)((word*)(void*)&(var))
10,得到一个字的高位和低位字节
#define WORD_LO(xxx)((byte)((word)(xxx)& 255))
#define WORD_HI(xxx)((byte)((word)(xxx)>> 8))
11,返回一个比X大的最接近的8的倍数
#define RND8( x)((((x)+ 7)/ 8)* 8)
12,将一个字母转换为大写
#define UPCASE( c)(((c)>='a'&&(c)<='z')?((c)- 0x20):(c))
13,判断字符是不是10进值的数字
#define DECCHK( c)((c)>='0'&&(c)<='9')
14,判断字符是不是16进值的数字
#define HEXCHK( c)(((c)>='0'&&(c)<='9')||\
((c)>='A'&&(c)<='F')||\
((c)>='a'&&(c)<='f'))
15,防止溢出的一个方法
#define INC_SAT( val)(val=((val)+1>(val))?(val)+1:(val))
16,返回数组元素的个数
#define ARR_SIZE( a)( sizeof((a))/ sizeof((a[0])))
17,返回一个无符号数n尾的值MOD_BY_Power_OF_TWO(X,n)=X%(2^n)
#define MOD_BY_POWER_OF_TWO( val, mod_by)\
((dword)(val)&(dword)((mod_by)-1))
18,对于IO空间映射在存储空间的结构,输入输出处理
#define inp(port)(*((volatile byte*)(port)))
#define inpw(port)(*((volatile word*)(port)))
#define inpdw(port)(*((volatile dword*)(port)))
#define outp(port, val)(*((volatile byte*)(port))=((byte)(val)))
#define outpw(port, val)(*((volatile word*)(port))=((word)(val)))
#define outpdw(port, val)(*((volatile dword*)(port))=((dword)(val)))
[2005-9-9添加]
19,使用一些宏跟踪调试
A N S I标准说明了五个预定义的宏名。它们是:
_ L I N E _
_ F I L E _
_ D A T E _
_ T I M E _
_ S T D C _
如果编译不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序
也许还提供其它预定义的宏名。
_ L I N E _及_ F I L E _宏指令在有关# l i n e的部分中已讨论,这里讨论其余的宏名。
_ D AT E _宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期。
源代码翻译到目标代码的时间作为串包含在_ T I M E _中。串形式为时:分:秒。
如果实现是标准的,则宏_ S T D C _含有十进制常量1。如果它含有任何其它数,则实现是
非标准的。
可以定义宏,例如:
当定义了_DEBUG,输出数据信息和所在文件所在行
#ifdef _DEBUG
#define DEBUGMSG(msg,date) printf(msg);printf(“%d%d%d”,date,_LINE_,_FILE_)
#else
#define DEBUGMSG(msg,date)
#endif
20,宏定义防止使用是错误
用小括号包含。
例如:#define ADD(a,b)(a+b)
用do{}while(0)语句包含多语句防止错误
例如:#difne DO(a,b) a+b;\
a++;
应用时:if(….)
DO(a,b);//产生错误
else
解决方法:#difne DO(a,b) do{a+b;\
a++;}while(0)
宏中"#"和"##"的用法
一、一般用法
我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起.
用法:
#include<cstdio>
#include<climits>
using namespace std;
#define STR(s)#s
#define CONS(a,b) int(a##e##b)
int main()
{
printf(STR(vck));//输出字符串"vck"
printf("%d
", CONS(2,3));// 2e3输出:2000
return 0;
}
相关推荐