单片机pos值(单片机posi)

单片机的问题与探讨

单片机C51数字频率计程序

单片机pos值(单片机posi)

/**************************************************

//头文件部分,文件名: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;//置标志

}

}<

单片机时钟程序 24小时制怎么设置

C语言的:

#include<reg51.h>

#include<stdio.h>

unsigned char ledbuf[8];

code unsigned char ledmap[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99,

0x92, 0x82, 0xf8, 0x80, 0x90};//8段显示

void delay(unsigned char cnt)

{

unsigned char i;

while(cnt--!=0)

for(i=100;i!=0;i--);

}

#define tick 7554

#define T100us(256-134)

unsigned char hour,minute,second,ankey;

unsigned int c100us;

void sees()

{

ledbuf[0]=ledmap[hour/10];

ledbuf[1]=ledmap[hour%10];

ledbuf[2]=0xbf;

ledbuf[3]=ledmap[minute/10];

ledbuf[4]=ledmap[minute%10];

ledbuf[5]=0xbf;

ledbuf[6]=ledmap[second/10];

ledbuf[7]=ledmap[second%10];

}

void displayled()

{

char i;

unsigned char pos;

pos=0x01;

for(i=7;i>=0;i--)

{

P2=0x255;

P0=ledbuf[i];

P2=~pos;

delay(2);

P2=0x255;

pos<<=1;

}

}

void key()

{

if(P32==0||P33==0||P35==0)

delay(2);

if(P32==0||P33==0||P35==0)

{

if(P32==0)

{

hour++;

if(hour==24)

hour=0;

while(P32==0)

{

sees();

displayled();

}

}

if(P33==0)

{

minute++;

if(minute==60)

minute=0;

while(P33==0)

{

sees();

displayled();

}

}

if(P35==0)

{

second++;

if(second==60)

second=0;

while(P35==0)

{

sees();

displayled();

}

}

}

}

void t0int()interrupt 1

{

c100us--;

if(c100us==0)

{

c100us=tick;

second++;

if(second==60)

{

second=0;

minute++;

if(minute==60)

{

minute=0;

hour++;

if(hour==24)hour=0;

}

}

}

}

void main()

{

TMOD=0x02;

TH0=T100us;

TL0=T100us;

IE=0x82;

hour=0;

minute=0;

second=0;

c100us=tick;

TR0=1;

while(1)

{

sees();

displayled();

key();

}

}

汇编的:

ORG 0000H

AJMP MAIN

ORG 000BH

AJMP TIME

ORG 0300H

MAIN:

MOV P3,#0FFH;

MOV 25H,#00H;

MOV R0,#40H;

MOV 20H,#00H;

MOV 21H,#00H;

MOV 22H,#00H;

MOV 23H,#00H;

MOV P2,#0FFH

MOV IP,#02H;

MOV IE,#82H;

MOV TMOD,#01H;

MOV TL0,#0B0H;

MOV TH0,#3CH;

SETB TR0;

MOV SP,#50H;

NEXT:

LCALL DISP;

LCALL KEY;

JZ NEXT;

LCALL ANKEY;

SJMP NEXT;

NOP

NOP;

NOP;

TIME:

PUSH ACC;

PUSH PSW;

MOV TL0,#0B4H;

MOV TH0,#3CH;

INC 20H;

MOV A,20H;

CJNE A,#20,RETI1;

MOV 20H,#00H;

MOV A,21H;

INC A;

MOV 21H,A;

CJNE A,#3CH,RETI1;

MOV 21H,#00H;

MOV A,22H;

ADD A,#01H;

MOV 22H,A;

CJNE A,#3CH,RETI1;

MOV 22H,#00H;

MOV A,23H;

ADD A,#01H;

MOV 23H,A;

CJNE A,#18H,RETI1;

MOV 23H,#00H;

RETI1:

POP PSW;

POP ACC;

RETI;

NOP

NOP

DISP:

MOV A,21H;

MOV B,#10;

DIV AB;

MOV 41H,A;

MOV 40H,B;

MOV A,22H;

MOV B,#10;

DIV AB;

MOV 43H,A;

MOV 42H,B;

MOV A,23H;

MOV B,#10;

DIV AB;

MOV 45H,A;

MOV 44H,B;

MOV R0,#40H

LCALL DISP2; 1

CLR P2.0;

LCALL DELAY;

SETB P2.0;

INC R0;

LCALL DISP2;

CLR P2.1;

LCALL DELAY;

SETB P2.1;

MOV P0,#0bfh;

CLR P2.2;

LCALL DELAY;

SETB P2.2;

INC R0;

LCALL DISP2;

CLR P2.3;

LCALL DELAY;

SETB P2.3;

INC R0;

LCALL DISP2;

CLR P2.4;

LCALL DELAY;

SETB P2.4;

MOV P0,#0BFH;

CLR P2.5;

LCALL DELAY;

SETB P2.5;

INC R0;

LCALL DISP2;

CLR P2.6;

LCALL DELAY;

SETB P2.6;

INC R0;

LCALL DISP2;

CLR P2.7;

LCALL DELAY;

SETB P2.7;

MOV R0,#40H;

DISP2:

MOV DPTR,#TABLE;

MOV A,@R0;

MOVC A,@A+DPTR;

MOV P0,A;

RET

DELAY:

MOV R6,#255;

D2:DJNZ R6,D2;

RET;

TABLE:DB 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h

; 0 1 2 3 4 5 6 7 8 9

;按键判断程序

KEY:

MOV A,P3;

CPL A;

ANL A,#3CH;

JZ RETX;无键按下则返回

LCALL DISP;

LCALL DELAY;

MOV A,P3;

CPL A;

ANL A,#3CH;

JZ RETX;无键按下则返回

MOV R6,A;将键值存入R6。

LOOP2: LCALL DISP;

MOV A,P3;

CPL A;

ANL A,#3CH;

JNZ LOOP2;等待键释放

MOV A,R6;

RETX:

MOV P3,#0FFH;

RET;

NOP

NOP

;按键处理子程序

ANKEY: CLR EA;关中断

LX: MOV A,R6;

JB ACC.2,L1;是功能键转L1

JB ACC.3,L2;是确认键转L2

JB ACC.4,L3;是减1键转L3

JNB ACC.5,L12;不是增1键,转L12

JB 2BH.4,L6;判断使哪一位(时、分、秒)的值加1

JB 2DH.4,L8;

JB 2FH.4,L9;

L12: LCALL DISP;

LCALL DISP;

LCALL KEY;判断有无键按下。

JZ L12;

LJMP LX;

L2: MOV 25H,#00H;确认键处理程序

CLR 2BH.4;

CLR 2DH.4;

CLR 2FH.4;

SETB EA;

RET;

L3: JB 2BH.4,L61;减一键处理程序

JB 2DH.4,L81;

JB 2FH.4,L91;

AJMP L12;

L1: MOV A,25H;功能键处理程序

JZ LB1;

JB ACC.0,LB2;

JB ACC.1,LB3;

JNB ACC.2,L12;

LB1: MOV 25H,#01H;25H单元是标志位,(25H)=01H调节时单元的值

SETB 2BH.4;

CLR 2DH.4;

CLR 2FH.4;

AJMP L12;

LB3: MOV 25H,#04H;25H单元是标志位,(25H)=04H调节秒单元的值

SETB 2FH.4;

CLR 2DH.4;

CLR 2BH.4;

AJMP L12;

LB2: MOV 25H,#02H;25H单元是标志位,(25H)=02H调节分单元的值

SETB 2DH.4;

CLR 2BH.4;

CLR 2FH.4;

AJMP L12;

L61: AJMP L611;

L81: AJMP L811;

L91: AJMP L911;

L112:AJMP L12;

L6: MOV A,23H;时加一

INC A;

MOV 23H,A;

CJNE A,#24H,L12;

MOV 23H,#00H;

AJMP L12;

L8: MOV A,22H;分加一

INC A;

MOV 22H,A;

CJNE A,#60H,L12;

MOV 22H,#00H;

AJMP L12;

L9: MOV A,21H;秒加一

INC A;

MOV 21H,A;

CJNE A,#60H,L12;

MOV 21H,#00H;

AJMP L12;

L611: MOV A,23H;时减一

DEC A;

MOV 23H,A;

CJNE A,#00H,L112;

MOV 23H,#23H;

AJMP L12;

L811: MOV A,22H;分减一

DEC A;

MOV 22H,A;

CJNE A,#00H,L112;

MOV 22H,#59H

AJMP L12;

L911: MOV A,21H;秒减一

DEC A;

MOV 21H,A;

CJNE A,#00H,L112;

MOV 21H,#59H;

AJMP L12;

NOP

NOP

END

单片机数字时钟设计

#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();

}

}

}

}

办理pos机加微信:13029808955

本文链接:https://www.changshapos.com/post/1592.html

发表评论

评论列表

还没有评论,快来说点什么吧~