單片機c語言計時器
Ⅰ 用51單片機c語言版設計秒錶倒計時
K1 EQU P1.0
K2 EQU P1.1
K3 EQU P1.2
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0ISR
ORG 0030H
MAIN:
MOV TMOD,#01H
MOV TH0,#HIGH(65536-10000)
MOV TL0,#LOW(65536-10000)
SETB ET0
SETB TR0
SETB EA
MOV R0,#9
MOV R1,#9
MOV R2,#0
MOV R3,#99
CLR 00H
CLR 01H
LOOP:
JB K1,LP01
JNB K1,$
CLR 01H
INC R3
CJNE R3,#100,LOOP0
MOV R3,#0
SJMP LOOP0
LP01:
JB K2,LP02
JNB K2,$
CLR 01H
CJNE R3,#0,LP011
MOV R3,#99
SJMP LOOP0
LP011:
DEC R3
SJMP LOOP0
LP02:
JB K3,LOOP
JNB K3,$
SETB 01H
SJMP LOOP
LOOP0:
MOV A,R3
MOV B,#10
DIV AB
MOV R0,B
MOV R1,A
SJMP LOOP
T0ISR:
CLR TR0
MOV TH0,#HIGH(65536-10000)
MOV TL0,#LOW(65536-10000)
SETB TR0
MOV DPTR,#TABLE
T0C:
CPL 00H
JB 00H,T001
MOV P3,#0FDH
MOV A,R1
MOVC A,@A+DPTR
MOV P2,A
SJMP T002
T001:
MOV P3,#0FEH
MOV A,R0
MOVC A,@A+DPTR
MOV P2,A
T002:
JNB 01H,T0E
INC R2
MOV A,R2
CJNE A,#100,T0E
MOV R2,#0
MOV A,R0
JZ T003
DEC R0
SJMP T0E
T003:
MOV A,R1
JZ T004
DEC R1
MOV R0,#9
T0E:
RETI
T004:
CLR 01H
MOV R4,#16
T005:
CPL P0.0
LCALL DELAY
DJNZ R4,T005
RETI
DELAY:
MOV R6,#200
DLY:
MOV R7,#250
DJNZ R7,$
DJNZ R6,DLY
RET
TABLE: ; 共陰極數碼管顯示代碼表
DB 3FH,06H,5BH,4FH,66H ;01234
DB 6DH,7DH,07H,7FH,6FH ;56789
END
Ⅱ 單片機秒錶計時器c語言程序圖 需要圖和程序
#include<reg51.h> // 時鍾與秒錶
#define uchar unsigned char
#define uint unsigned int
sbit qingling=P1^0; //清零
sbit tiaofen=P1^1; //調分
sbit tiaoshi=P1^2; //調時
sbit sounder=P1^7; //naozhong
uint a,b;
uchar hour,minu,sec, //時鍾
hour0,minu0,sec0, //秒錶
hour1,minu1,sec1;
h1,h2,m1,m2,s1,s2, //顯示位
k,s; //狀態轉換標志
uchar code select[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
/*****************函數聲明***********************/
void keyscan();
void init();
void delay(uchar z);
void display(uchar,uchar,uchar);
void sounde();
/*****************主函數*************************/
void main()
{
init();
while(1)
{
while(TR1)
{
keyscan(); // 掃描函數
while(s==1) // s是狀態標志,當s=0時,鬧鍾取消。s=1時,設定鬧鍾時間
//(也是通過調時,調分函數);
{ //s=2時,鬧鍾工作,時間與設定時刻一致時,鬧鍾響
// (一分鍾後自動關閉,可手動關閉)。再次切換,s=0.
keyscan(); //s狀態切換(0-》1-》2-》0)通過外部中斷1實現。
display(hour1,minu1,sec1); //鬧鍾時刻顯示
}
display(hour0,minu0,sec0);//時鍾表顯示
while(k) /*k是秒錶狀態(0-》1-》2-》0)通過外部中斷0實現。
0秒錶關;1秒錶從零計時;2秒錶停,顯示計時時間*/
{
display(hour,minu,sec); //秒錶顯示
}
}
}
}
/*****************初始化函數***********************/
void init()
{
a=0;
b=0;
k=0;
s=0;
hour0=0;
minu0=0;
sec0=0;
hour=0;
minu=0;
sec=0;
hour1=0;
minu1=0;
sec1=0;
TMOD=0x11; //定時器0,1工作於方式1;賦初值
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
EA=1;
EX0=1; //秒錶中斷
EX1=1; //鬧鍾設定中斷
ET0=1;
ET1=1;
IT0=1; //邊沿觸發方式
IT1=1;
PX0=1;
PX1=1;
TR0=0; //初始,秒錶不工作
TR1=1; //時鍾一開始工作
}
/*****************定時器0中斷*************/
void timer0_int() interrupt 1 //秒錶
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
a++;
if(a==2)
{
a=0;
sec++;
if(sec==100)
{
sec=0; //毫秒級
minu++;
if(minu==60)
{
minu=0; //秒
hour++;
if(hour==60) //分
{
hour=0;
}
}
}
}
}
/*************外部中斷0中斷函數************/
void ex0_int() interrupt 0
{
k++;
if(k==3)
k=0;
if(k==1)
{
TR0=~TR0;
if(TR0==1)
{
hour=0;
minu=0;
sec=0;
}
}
if(k==2)
{
TR0=~TR0;
}
}
/*************外部中斷1中斷函數************/
void ex1_int() interrupt 2
{
s++;
if(s==3)
s=0;
}
/*************定時器1中斷****************/
void timer1_int() interrupt 3 //控制時鍾工作
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
if(s==2)
{
if(hour1==hour0 && minu0==minu1)
sounde();
}
b++;
if(b==20)
{
b=0;
sec0++;
if(sec0==60)
{
sec0=0;
minu0++;
if(minu0==60)
{
minu0=0;
hour0++;
if(hour0==24)
hour0=0;
}
}
}
}
/*************鍵盤掃描****************/
void keyscan()
{
if(s==1)
{
if(qingling==0)
{
delay(10);
if(qingling==0)
{
sec1=0;
minu1=0;
hour1=0;
}
}
if(tiaofen==0)
{
delay(10);
if(tiaofen==0)
{
minu1++;
if(minu1==60)
{
minu1=0;
}
while(!tiaofen);
}
}
if(tiaoshi==0)
{
hour1++;
if(hour1==24)
{
hour1=0;
}
while(!tiaoshi);
}
}
else //調整時鍾時間
{
if(qingling==0)
{
delay(10);
if(qingling==0)
{
sec0=0;
minu0=0;
hour0=0;
}
}
if(tiaofen==0)
{
delay(10);
if(tiaofen==0)
{
minu0++;
if(minu0==60)
{
minu0=0;
}
while(!tiaofen);
}
}
if(tiaoshi==0)
{
hour0++;
if(hour0==24)
{
hour0=0;
}
while(!tiaoshi);
}
}
}
/*************顯示函數****************/
void display(uchar hour,uchar minu,uchar sec)
{
h1=hour/10;
h2=hour%10;
m1=minu/10;
m2=minu%10;
s1=sec/10;
s2=sec%10;
P0=0xff;
P2=table[h1];
P0=select[7];
delay(5);
P0=0xff;
P2=table[h2];
P0=select[6];
delay(5);
P0=0xff;
P2=0x40;;
P0=select[5];
delay(5);
P0=0xff;
P2=table[m1];
P0=select[4];
delay(5);
P0=0xff;
P2=table[m2];
P0=select[3];
delay(5);
P0=0xff;
P2=0x40;
P0=select[2];
delay(5);
P0=0xff;
P2=table[s1];
P0=select[1];
delay(5);
P0=0xff;
P2=table[s2];
P0=select[0];
delay(5);
}
/*************鬧鍾函數****************/
void sounde()
{
sounder=~sounder;
}
/*************延時函數****************/
void delay(uchar z)
{
int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
Ⅲ 單片機C語言關於定時計數器程序運行時序問題
這個和你設置的定時器的工作模式有關系,你要在定時時間到後,依然想要TH0=0xfc; TL0=0x18。這兩個寄存器值存在的話,你就要設置定時器的工作模式為:自動重裝初值
Ⅳ 單片機c語言里怎麼用2個定時器
是51單片機嗎?
如果是51單片機,你可以使用tmod設置兩個定時器,然後使用tr0、tr1分別啟動兩個定時器。pt0置為「1」,就可以中斷定時器1的服務函數,相反,如果pt1置為「1」就可以中斷定時器0的服務函數。
如果不設置pt的值,默認為「0」,這樣的話,t0和t1誰也不能中斷誰。
Ⅳ 請教一個單片機時鍾計時器c語言程序和原理圖 注:不要復制的
//------------------------------------------------------------------
//名稱:DS1302時鍾
//------------------------------------------------------------------
//說明:從DS1302
中讀取時鍾數據,在LCD上顯示日期和時間
//------------------------------------------------------------------
#include
<reg51.h>
#include
<intrins.h>
#include
<string.h>
#define
uchar
unsigned
char
#define
uint
unsigned
int
sbit
IO=P1^0;
//DS1302數據線
sbit
SCLK=P1^1;
//DS1302時鍾線a
sbit
RST=P1^2;
//DS1302復位線
uchar
WEEK[][4]={
"***","SUN","MON","TUS","WEN","THU","FRI","SAT"};
//亦可定義成指針數組*WEEK[]
uchar
LCD_DSY_BUFFER1[]={"DATE
00-00-00
"};
uchar
LCD_DSY_BUFFER2[]={"TIME
00:00:00
"};
uchar
DateTime[7];
void
Initialize_LCD();
void
Display_LCD_String(uchar
p,uchar
*s);
void
DelayMS(uint
ms);
//------------------------------------------------------------------
//函數名稱:Write_A_Byte_TO_DS1302(uchar
x)
//函數功能:向DS1302寫入一個位元組
//輸入參數:x
將要寫入的數據
//返回值:無
//時序原理:在控制指令字輸入後的下一個SCLK時鍾的上升沿時數據被寫入DS1302,數據輸入從第0位開始
//------------------------------------------------------------------
void
Write_A_Byte_TO_DS1302(uchar
x)
{
uchar
i;
SCLK=0;
//拉低SCLK,為脈沖上升沿寫入數據做好准備
for
(i=0;i<8;i++)
{
IO=x
&
0x01;
//取出x的第0位數據寫入1302
SCLK=1;
//上升沿寫入數據
SCLK=0;
//重新拉低SCLK,形成脈沖
x
>>=1;
//將x的各數據位右移1位,准備寫入下一個數據位
}
}
//------------------------------------------------------------------
//函數名稱:Get_A_Byte_FROM_DS1302()
//函數功能:從DS1302讀取一個位元組
//輸入參數:無
//返回值:讀取的數據
//時序原理:在緊跟8位的控制指令字後的下一個SCLK時鍾的下降沿時讀出DS1302的數據,讀出數據時從低位0位到高位7
//注意:DS1302中所存放的數據是BCD碼,在讀寫時要注意轉換
//例如:00011000,當把它視為二進制數時,其值為24;但作為2位BCD碼時,其值為18。
//------------------------------------------------------------------
uchar
Get_A_Byte_FROM_DS1302()
{
uchar
i,b=0x00;
for
(i=0;i<8;i++)
{
b
|=
_crol_((uchar)IO,i);//將uchar類型的IO數據左移i位
SCLK=1;
//將SCLK置於高電平,為下降沿讀出
SCLK=0;
//時鍾下降沿讀取
}
return
(b/16)*10+b%16;
//從二進制數返回BCD碼
}
//------------------------------------------------------------------
//函數名稱:Read_Data(uchar
addr)
//函數功能:從DS1302的指定寄存器讀數據
//輸入參數:addr
為讀寄存器的地址
//返回值:dat
讀取的數據
//命令字:也即讀寄存器的地址
最高位位7必須為1,位6如果為0表示存取日歷數據,位5至位1表示操作單元的地址,位0為1表示讀操作
//------------------------------------------------------------------
uchar
Read_Data(uchar
addr)
{
uchar
dat;
RST=0;
//拉低RST
SCLK=0;
//確保寫數據前SCLK被拉低
RST=1;
//啟動數據傳輸,只有在SCLK為低電平時才能將RST置為高電平
Write_A_Byte_TO_DS1302(addr);
//寫入命令字
dat=Get_A_Byte_FROM_DS1302();
SCLK=1;
//將時鍾電平置於已知狀態
RST=0;
//禁止數據傳遞
return
dat;
}
//------------------------------------------------------------------
//函數名稱:GetTime()
//函數功能:讀取當前日期時間,將秒、分鍾、小時、日期、月份、周日、年份七個數值分//別存入數組DateTime[0]~
DateTime[6]
//輸入參數:無
//返回值:無
//------------------------------------------------------------------
void
GetTime()
{
uchar
i,addr
=0x81;
for
(i=0;i<7;i++)
{
DateTime[i]
=
Read_Data(addr);
addr+=2;
}
}
//------------------------------------------------------------------
//日期與時間值轉換為數字字元
//------------------------------------------------------------------
void
Format_DataTime(uchar
d,uchar
*a)
{
a[0]=d/10+'0';
a[1]=d%10+'0';
}
//------------------------------------------------------------------
//主程序
//------------------------------------------------------------------
void
main()
{
Initialize_LCD();
while(1)
{
GetTime();
Format_DataTime(DateTime[6],LCD_DSY_BUFFER1+5);
//0x8D
年份寄存器
Format_DataTime(DateTime[4],LCD_DSY_BUFFER1+8);
//0x89
月份寄存器
Format_DataTime(DateTime[3],LCD_DSY_BUFFER1+11);
//0x87
日期寄存器
//星期
strcpy
(LCD_DSY_BUFFER1+13,WEEK[DateTime[5]]);//將字元串WEEK[DateTime[5]]復制到字元數組LCD_DSY_BUFFER1+13中
//0x8B
周日寄存器
Format_DataTime(DateTime[2],LCD_DSY_BUFFER2+5);
//0x85
小時寄存器
Format_DataTime(DateTime[1],LCD_DSY_BUFFER2+8);
//0x83
分鍾寄存器
Format_DataTime(DateTime[0],LCD_DSY_BUFFER2+11);
//0x81
秒寄存器
Display_LCD_String(0x00,LCD_DSY_BUFFER1);
//第一行顯示年、月、日、星期幾
Display_LCD_String(0x40,LCD_DSY_BUFFER2);
//第二行顯示小時、分鍾、秒
}
}
//--------------------------------------------------------
//注意:1.本例中DS1302的屬性設置為:自動根據PC的時間初始化。
//可以編程寫入某個自定的初始時間,然後由該時間開始顯示時鍾。
//
//
//--------------------------------------------------------
Ⅵ 請問單片機C語言定時器程序怎麼寫
你看過匯編嗎?與匯編的格式是一樣的。具體就是先開中斷允許標志位(IE裡面對應的各個位)在設定TMOD工作方式。下一步就是設定初始值了(TH、TL)。設置完這些就可以開定時器了。寫中斷中段函數是是需要另加interrupt 加上一個常數(比如是定時器0就在後面加上1)。我用89S52晶元編過一個定時器程序你參考一下,希望對你有一點幫助。
//功能:感應外界溫度並用數碼管顯示
//時間:2005年6月20日
//設計人:
#include<reg52.h>
#define uchar unsigned char
sbit ad0809_oe=P1^0; //定義各個位
sbit ad0809_start=P1^1;
sbit ad0809_ale=P1^2;
sbit ls595_rclk=P1^3;
sbit ad0809_eoc=P1^5;
sbit ls595_oe=P1^4;
sbit ls595_ser=P3^0;
sbit ls595_srclr=P3^1;
uchar nn,mm;
uchar code tab[]={0x81,0xcf,0x92,0x86,0xcc,0xa4,0xa0,0x8f,0x80,0x84};
send(uchar); //聲明函數
AD(uchar);
void display(uchar);
void init();
//********普通口輸入數據*****************
send(uchar shu) //普通口串列輸入
{
unsigned char i,k;
k=0x01;
for(i=0;i<8;i++)
{
if(k==(k&shu)) //判斷每位上是否為1
ls595_ser=1;
else
ls595_ser=0;
k<<=1; //左移一位
ls595_srclr=0; //輸入一個上升沿講數送入595中
ls595_srclr=1;
}
}
//*****************595顯示子程序********************
void display(uchar )
{
uchar ge,shi,flge; //ge拆字後個位的存放處shi拆字後十位的存放處flge ℃的存放處
shi=tab[/10]; //拆字
send(shi); //給595送數
ge=tab[%10];
send(ge);
flge=0xb1;
send(flge);
ls595_rclk=0; //上升沿送出數據
ls595_rclk=1;
}
//*******************初始化程序********************
void init() //初始化AD、定時器
{
ad0809_start=0; //Start管教上升沿將AD內部寄存器清零
ad0809_start=1;
ad0809_ale=1; //ALE高電平選擇通道
nn=0;
mm=0;
TMOD=0x01; //定時器初始化
//IE=0x82;
EA=1;
ET0=1;
TCON=0x00;
TL0=(65536-50000)%256; //定時50ms
TH0=(65536-50000)/256;
}
AD(uchar wen)
{
// unsigned char tt=0;
// ad0809_ale=1; //選擇通道
ad0809_start=1;
ad0809_start=0; //start下降沿啟動轉換信號
while(ad0809_eoc==0); //判斷轉換是否結束
ad0809_oe=1; //轉換結束送出轉換數據
wen=P2;
return (wen);
}
//**************中斷服務程序*********************
void tiam0() interrupt 1 using 1 //中斷服務程序
{
TL0=(65536-50000)%256; //定時50ms
TH0=(65536-50000)/256;
nn++;
if(nn==10) //0.5秒M加一
{
mm++;
nn=0;
}
}
//****************主程序***************************
void main()
{
unsigned char bb,aa,cc; //bb=計算後得到溫度,aa=AD輸出數據
unsigned char wen; //wen存放轉換的得到的數據
init();
// wen=17;
ls595_oe=0;
cc=0;
TR0=1;
while(1)
{
aa=AD(wen);
// ad0809_oe=0;
aa=~aa;
bb=aa/4;
if(mm==2)
{
mm=0;
cc=bb;
}
display(cc); //調用顯示子程序
}
}
Ⅶ 單片機C語言定時器如何調用
單片機中通過中斷的方式來調用定時器。
具體的調用方式可以參考通過如下程序:
程序功能:利用定時器進行定時,實現每秒中led閃爍一次
#include<reg52.h>
sbitled=P0^0;
unsignedintnum;
voidmain(void)
{
TMOD=0x00;//工作方式0
TH0=(8192-5000)/32;//12M晶振下定時5ms
TL0=(8192-5000)%32;
EA=1; //開總中斷
ET0=1; //開定時器中斷
TR0=1; //啟動定時器
while(1)
{
if(num==200) //定時1秒鍾到
{
num=0; //計數器清零
led=~led; //led燈取反,實現1秒閃爍一次
}
}
}
voidtimer()interrupt1//定時器1工作與方式0
{
TH0=(8192-5000)/32;//重裝初值
TL0=(8192-5000)%32;
num++; //計數器加1
}
Ⅷ 單片機計時器程序(c語言)急急急!!!
#include<reg51.h>
voiddelay(unsignedinti);
unsignedinta[]={0XEF,0X8C,0XB7,0XBE,0XDC,0X7E,0X7F,0XAC,0XFF,0XFE};
unsignedintm=0,v=0,k=0,b[5];
voidmain()
{
TMOD=0X01;
TH0=0X3C;
TL0=0XB0;
EA=1;
IE=0X87;
IT0=1;
IT1=1;
TR0=0;
while(1)
{
P2=0x40;
P0=a[m%1000%100%10];
delay(3);
P2=0x20;
P0=a[m%1000%100/10];
delay(3);
P2=0x10;
P0=a[m%1000/100];
delay(3);
P2=0x08;
P0=a[m/1000];
delay(3);
}
}
voidan()interrupt1
{
TH0=0X3C;
TL0=0XB0;
k++;
if(k==20)
{m++;
k=0;
}
}
voidan2()interrupt2
{m=0;
}
voidan1()interrupt0
{v++;
if(v==1)TR0=1;
if(v==2)b[v]=m;
if(v==3)
{b[v]=m;
TR0=0;
}
if(v==4)m=b[2];
if(v==5)m=b[3];
if(v==6)v=0;
}
voiddelay(unsignedinti)
{unsignedintj,k;
for(k=0;k<i;k++)
for(j=0;j<255;j++);
}
Ⅸ 單片機c語言編計時器
#include<AT89X51.H>
unsignedcharcodedispcode[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00};
unsignedcharsecond;
unsignedchartcount;
voidmain(void)
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;
tcount=0;
second=0;
P0=dispcode[second/10];
P2=dispcode[second%10];
while(1)
{
if(TF0==1)
{
tcount--;
if(tcount==0)
{
tcount=15;
second--;
if(second==0)
{
second=15;
}
P0=dispcode[second/10];
P2=dispcode[second%10];
}
TF0=0;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
}
}
}
Ⅹ 求單片機定時器簡單程序(C語言)詳解。不勝感激~
用定時器0中斷做流水燈,程序如下:#include<reg52.h>#include<intrins.h> //包含_crol_()循環左移函數
unsigned char temp,count;void init() //初始化函數{ TMOD=0x01;//設置定時器0為工作方式1 TH0=(65536-50000)/256;//裝初值,高8位 TL0=(65536-50000)%256;//裝初值,低8位 EA=1;//開總中斷 ET0=1;//開定時器0中斷 TR0=1;//啟動定時器0 temp=0xfe; count=0;//記數值清0}void main(){ init(); while(1){ P1=temp;}}void timer0() interrupt 1 using 1 //定時器0中斷函數{ TH0=(65536-50000)/256;//重裝初值,同上 TL0=(65536-50000)%256; count++;//計數值加1 if(count==10)//500ms{ count=0;//計數值清0 temp=_crol_(temp,1);循環左移一位}