1. 一部分用C語言編寫的C51單片機時鍾程序,求加註釋
//定義共陰極數碼管,對應顯示0-F
uchar code seven_seg[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
0x6f,0x77,0x7C,0x39,0x5e,0x79,0x71};
uchar keyState = 0 ; // 0表示沒有操作 1 修改秒 2 修改分鍾 3 修改小時 4 定鬧 小時 5定鬧分鍾
uint ledState =0;
uchar ledStateNum=0;
uint num = 0 ;
sbit KEY1=P3^0; //定義IO口
sbit KEY2=P3^1;
sbit KEY3=P3^2;
sbit KEY4=P3^3;
char timer[] ={ 0 , 0 , 0} ; //時,分,秒
char n_timer[2]={11,0};
//延時程序 ,當調用此函數時,需要傳遞參數ms,用於設置延時時間
//若為12M晶振,每條指令對應1us的時間 ,要對應1ms的時間,就要選擇
//0.012M的晶振,也就是12K的晶振(有嗎?)
// 若要用12M的晶振,實現1ms的延時,程序需要做修改。如下面注釋的語句
void DelayMS(uint ms)
{
ms *= 1000; //加上此語句,實現延時1ms
while(ms--);
}
void Display()
{
uchar i = 0,flags;
uchar count = 0;
uchar temp [6] ={ 0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
if( 4 == keyState || 5 == keyState )
//從程序看,應該有外部中斷處理函數用於設置keystate參數
//這個if寫得比較另類,正常應把參數放在前面,
//判斷按鍵是否按下,兩個有一個按下即執行
{
P2 = temp[0]; //向P2口寫數據
P0 = 0x00; //有了下面一條指令,這條語句沒有用
P0 = 0x40; //向P0口寫數據
DelayMS(1); //延時1ms
P2 = temp[1];
P0 = 0x00;
P0 = 0x40;
DelayMS(1);
P2 = temp[2];
P0 = 0x00;
if(ledState && 4 == keyState)
P0 = seven_seg[ n_timer[0] / 10 ];
else
P0 = seven_seg[ n_timer[0] / 10 ] | 0x80;
DelayMS(1);
P2 = temp[3];
P0 = 0x00;
if(ledState && 4 == keyState)
P0 = seven_seg[ n_timer[0] % 10 ];
else
P0 = seven_seg[ n_timer[0] % 10 ] | 0x80;
DelayMS(1);
P2 = temp[4];
P0 = 0x00;
if(ledState && 5 == keyState)
P0 = seven_seg[ n_timer[1] / 10 ];
else
P0 = seven_seg[ n_timer[1] / 10 ] | 0x80;
DelayMS(1);
P2 = temp[5];
P0 = 0x00;
if(ledState && 5 == keyState)
P0 = seven_seg[ n_timer[1] % 10 ];
else
P0 = seven_seg[ n_timer[1] % 10 ] | 0x80;
DelayMS(1);
P2 = 0XFF;
return ;
}
//沒有主程序和外部中斷處理函數,這段程序讀起來不太好讀懂
//應該是根據ledstate的狀態,也就是4或5來進行時間的校對。
if( 0 == keyState)
{
P2 = temp[0];
P0 = 0x00;
P0 = seven_seg[ timer[0] / 10 ];
DelayMS(1);
P2 = temp[1];
P0 = 0x00;
P0=seven_seg[ timer[0] % 10 ];
DelayMS(1);
P2 = temp[2];
P0 = 0x00;
P0 = seven_seg[ timer[1] / 10 ];
DelayMS(1);
P2 = temp[3];
P0 = 0x00;
P0 = seven_seg[ timer[1] % 10 ];
DelayMS(1);
P2 = temp[4];
P0 = 0x00;
P0 = seven_seg[ timer[2] / 10 ];
DelayMS(1);
P2 = temp[5];
P0 = 0x00;
P0 = seven_seg[ timer[2] % 10 ];
DelayMS(1);
P2 = 0XFF;
return ;
}
//若不需要設置時間,顯示時間
while( i < 6 )
{
if(3- keyState == i/2 && ledState == 0)
{
flags = 0;
}
else
{
flags = 1;
}
if( flags)
{
P2 = temp[i];
P0=0x00;
if(0 == i % 2)
{
P0 = seven_seg[ timer[i/2] / 10 ];
}
else
{
P0 = seven_seg[ timer[i/2] % 10 ];
}
}
i++;
}
//這個程序不全,沒有看懂
}
這個程序不復雜的。如果懂單片機和C語言很容易讀懂的。
有不懂的地方,用Keil或Proteus模擬一下。就讀懂了
自己動手操作一下,總比在這里等強。
再說你給的懸賞分也不高啊
2. 誰能告訴我51單片機簡單的led數碼管時鍾程序 24小時制的(c語言版的)
#include "reg52.h"
#define uint unsigned int
#define uchar unsigned char
uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar shi,fen,miao;
uchar time;
void delay(uint x)
{
uint y;
for(;x>0;x--)
{
for(y=0;y<124;y++);
}
}
void display(uchar shi,uchar fen,uchar miao)
{
P2=0; //位碼
P0=(tab[shi/10]); //段碼
delay(2);
P2=1;
P0=(tab[shi%10]);
delay(2);
P2=2; //位碼
P0=0x40; //段碼
delay(2);
P2=3; //位碼
P0=(tab[fen/10]); //段碼
delay(2);
P2=4;
P0=(tab[fen%10]);
delay(2);
P2=5; //位碼
P0=0x40; //段碼
delay(2);
P2=6; //位碼
P0=(tab[miao/10]); //段碼
delay(2);
P2=7;
P0=(tab[miao%10]);
delay(2);
}
void main()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
while(1)
{
if(time==20)
{
time=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
shi=0;
}
}
}
display(shi,fen,miao);
}
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
time++;
}
/*還有什麼不明白繼續追加*/
3. 求 C51單片機 時鍾程序 用C 語言編寫 顯示分秒 復位鍵重新記時
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
uchar code segcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};//0,1,2,3,4,5,6,7,8,9,-
uchar code dispbit[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//數碼管位選碼
uchar buffer[]={0,0,0,0,0,0,0,0};
uint hour,min,sec;
uint status;
//函數聲明
void delayMS(uint t) ;
void keyprocess(unsigned char key);
void display();
void timer0();
main() //主函數
{
bit keyrelease;
uchar buf;
uchar keyinput;
keyrelease=1;
buf=0xff;
TMOD=0x01; //T0工作在方式1,16位計數器
TH0=(65536-1000)/256; // 定時器0設置延時1ms中斷初始值
TL0=(65536-1000)%256;
TR0=1;
IE=0x82; //開定時器0中斷
status=0;
while(1)
{ //鍵掃描程序
keyinput=P1&0xf0;
if(keyinput!=0xf0)
{
delayMS(10);
if(keyinput!=0xf0)
{
if(keyrelease==1)
{
keyrelease=0;
buf = keyinput; //buf用來暫時存放鍵值
}
}
else
{
keyrelease=1;
keyprocess(buf); //調用按鍵處理函數
buf = 0xff;
}
}
else
{
keyrelease=1;
keyprocess(buf);
buf=0xff;
}
display();
}
}
//延時函數
void delayMS(uint t) // 晶振頻率12M
{
uint i;
while(t--)
for(i=0;i<125;i++);
}
//按鍵處理函數
void keyprocess(unsigned char key) //鍵值處理,正常計時,設置時分秒
{ switch (key)
{
case 0xe0:status++; //按下設置鍵
if (status>=4) status = 0;
break;
case 0xd0:switch(status) //按下加1鍵,3種模式下加1
{
case 0x01:if(hour<23) hour++;
else hour=0; break;
case 0x02:if(min<59) min++;
else min=0; break;
case 0x03:if(sec<59) sec++;
else sec=0; break;
}
break;
case 0xb0:switch(status) //按下減1鍵
{
case 0x01:if(hour>0) hour--;
else hour=23; break;
case 0x02:if(min>0) min--;
else min=59; break;
case 0x03:if(sec>0) sec--;
else sec=59; break;
}
break;
default:break;
}
}
//數碼管顯示函數
void display()
{
uchar i;
//正常計時顯示
{
buffer[0]=hour/10; // 顯示時的十位
buffer[1]=hour%10; // 顯示時的個位
buffer[2]=10; // 顯示『-』
buffer[3]=min/10; // 顯示分的十位
buffer[4]=min%10; // 顯示分的個位
buffer[5]=10;
buffer[6]=sec/10; // 顯示秒的十位
buffer[7]=sec%10; // 顯示秒的個位
for(i=0;i<8;i++)
{
P0=segcode[buffer[i]];
P2=dispbit[i];
delayMS(1); //防止數碼管顯示的時候閃動
P2=0x0;
}
}
}
//定時器0中斷函數
void timer0() interrupt 1 using 2
{
static uint count;
TH0=(65536-1000)/256; // 定時器0設置初始值1ms中斷初始值
TL0=(65536-1000)%256;
TR0=1;
count++; //正常計時
if(count>=1000) // 定時 1S 到,以下為時鍾的正常走鍾邏輯
{
count=0;
sec++;
if(sec>= 60)
{
sec=0; min++;
if(min>= 60)
{
min=0; hour++;
if(hour>= 24)
{
hour=0;
}
}
}
}
}
4. 請高人幫我看看51單片機寫的關於數碼顯示時鍾的C語言程序
你所有調用display()和 delay()函數時候都沒在後面加個分號。漏了還是???
還有:
uchar code table[]={ //顯示編碼
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71}
也應該在後面加個分號!!
你的分不好拿啊,該用分號的不用,不該用的地方用了,還有括弧你用了很多中文的括弧。
現在幫你改了,你自己好好對一下了,反正編譯通過了,運行結果你自己看吧,我沒你的目標板,運行不了。
#include<reg51.h>
#define uchar unsigned char//宏定義
#define uint unsigned int
sbit la=P2^6; //段控制位
sbit wela=P2^7; //位控制位
uchar miao,fen,aa,n1,n2,n3,n4;
uchar code table[]={ //顯示編碼
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delay(uint z); //延時程序聲明
void init(void);//初始化程序聲明
void display(uchar n1 ,uchar n2,uchar n3,uchar n4); //顯示程序聲明
void main() //主程序
{
init(); //調用初始化程序
while(1) //進入大循環
{
if(aa==20) //判斷是否到了1S
{
miao++; //秒數加1
if(miao==60) //判斷是否到了60秒
{
miao=0; //秒數清0
fen++; //分數加1
if(fen==60) //判斷是否到了60分
{
fen=0; //分數到60則清0
}
n1=fen/10; //第一個數碼管顯示分的十位
n2=fen%10; //第二個數碼管顯示分的個位
n3=miao/10; //第三個數碼管顯示秒的十位
n4=miao%10; //第四個數碼管顯示秒的個位
}
display(n1,n2,n3,n4);
}
}
}
void delay(uint z) //延時程序
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void display(uchar n1 ,uchar n2,uchar n3,uchar n4)
{
la=1; //開段選
P0=table[n1]; //送分的十位
la=0; //關段選
P0=0xff; //消隱
wela=1; //開位選
P0=0xfe; //選通分的十位
wela=0; //關位選
P0=0xff; //消隱
delay(1); //延時
la=1; //開段選
P0=table[n2]; //送分的個位
la=0; //關段選
P0=0xff; //消隱
wela=1; //開位選
P0=0xfd; //選通分的個位
wela=0; //關位選
P0=0xff; //消隱
delay(1); //延時
la=1; //開段選
P0=table[n3]; //送秒的十位
la=0; //關段選
P0=0xff; //消隱
wela=1; //開位選
P0=0xfb; //選通秒的十位
wela=0; //關位選
P0=0xff; //消隱
delay(1); //延時
la=1; //開段選
P0=table[n4]; //送秒的個位
la=0; //關段選
P0=0xff; //消隱
wela=1; //開位選
P0=0xf7; //選通秒的個位
wela=0; //關位選
P0=0xff; //消隱
delay(1); //延時
}
void init(void)
{
}
void timer0(void) interrupt 1 using 1
{
TH0=(65536-50000)/256; //求模
TL0=(65536-50000)%256; //求余
aa++;
}
5. 51單片機時鍾程序,C語言,匯編都行
我給你個,你試試把。
#include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
#include <intrins.h>
sbit SCK=P3^; //時鍾
sbit SDA=P3^4; //數據
sbit RST = P3^5;// DS1302復位
sbit LS138A=P2^2;
sbit LS138B=P2^3;
sbit LS138C=P2^4;
bit ReadRTC_Flag;//定義讀DS1302標志
unsigned char l_tmpdate[7]={0,0,12,15,5,3,8};//秒分時日月周年08-05-15 12:00:00
unsigned char l_tmpdisplay[8];
code unsigned char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分時日月周年 最低位讀寫位
code unsigned char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
//共陰數碼管 0-9 '-' '熄滅『表
/******************************************************************/
/* 函數聲明 */
/******************************************************************/
void Write_Ds1302_byte(unsigned char temp);
void Write_Ds1302( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302 ( unsigned char address );
void Read_RTC(void);//read RTC
void Set_RTC(void); //set RTC
void InitTIMER0(void);//inital timer0
/******************************************************************/
/* 主函數 */
/******************************************************************/
void main(void)
{
InitTIMER0(); //初始化定時器0
Set_RTC(); //寫入時鍾值,如果使用備用電池時候,不需要沒每次上電寫入,此程序應該屏蔽
while(1)
{
if(ReadRTC_Flag)
{
ReadRTC_Flag=0;
Read_RTC();
l_tmpdisplay[0]=l_tmpdate[2]/16; //數據的轉換,因我們採用數碼管0~9的顯示,將數據分開
l_tmpdisplay[1]=l_tmpdate[2]&0x0f;
l_tmpdisplay[2]=10; //加入"-"
l_tmpdisplay[3]=l_tmpdate[1]/16;
l_tmpdisplay[4]=l_tmpdate[1]&0x0f;
l_tmpdisplay[5]=10;
l_tmpdisplay[6]=l_tmpdate[0]/16;
l_tmpdisplay[7]=l_tmpdate[0]&0x0f;
}
}
}
/******************************************************************/
/* 定時器0初始化 */
/******************************************************************/
void InitTIMER0(void)
{
TMOD|=0x01;//定時器設置 16位
TH0=0xef;//初始化值
TL0=0xf0;
ET0=1;
TR0=1;
EA=1;
}
/******************************************************************/
/* 寫一個位元組 */
/******************************************************************/
void Write_Ds1302_Byte(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++) //循環8次 寫入數據
{
SCK=0;
SDA=temp&0x01; //每次傳輸低位元組
temp>>=1; //右移一位
SCK=1;
}
}
/******************************************************************/
/* 寫入DS1302 */
/******************************************************************/
void Write_Ds1302( unsigned char address,unsigned char dat )
{
RST=0;
_nop_();
SCK=0;
_nop_();
RST=1;
_nop_(); //啟動
Write_Ds1302_Byte(address); //發送地址
Write_Ds1302_Byte(dat); //發送數據
RST=0; //恢復
}
/******************************************************************/
/* 讀出DS1302數據 */
/******************************************************************/
unsigned char Read_Ds1302 ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0;
_nop_();
_nop_();
SCK=0;
_nop_();
_nop_();
RST=1;
_nop_();
_nop_();
Write_Ds1302_Byte(address);
for (i=0;i<8;i++) //循環8次 讀取數據
{
if(SDA)
temp|=0x80; //每次傳輸低位元組
SCK=0;
temp>>=1; //右移一位
_nop_();
_nop_();
_nop_();
SCK=1;
}
RST=0;
_nop_(); //以下為DS1302復位的穩定時間
_nop_();
RST=0;
SCK=0;
_nop_();
_nop_();
_nop_();
_nop_();
SCK=1;
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
return (temp); //返回
}
/******************************************************************/
/* 讀時鍾數據 */
/******************************************************************/
void Read_RTC(void) //讀取 日歷
{
unsigned char i,*p;
p=read_rtc_address; //地址傳遞
for(i=0;i<7;i++) //分7次讀取 秒分時日月周年
{
l_tmpdate[i]=Read_Ds1302(*p);
p++;
}
}
/******************************************************************/
/* 設定時鍾數據 */
/******************************************************************/
void Set_RTC(void) //設定 日歷
{
unsigned char i,*p,tmp;
for(i=0;i<7;i++){ //BCD處理
tmp=l_tmpdate[i]/10;
l_tmpdate[i]=l_tmpdate[i]%10;
l_tmpdate[i]=l_tmpdate[i]+tmp*16;
}
Write_Ds1302(0x8E,0X00);
p=write_rtc_address; //傳地址
for(i=0;i<7;i++) //7次寫入 秒分時日月周年
{
Write_Ds1302(*p,l_tmpdate[i]);
p++;
}
Write_Ds1302(0x8E,0x80);
}
/******************************************************************/
/* 定時器中斷函數 */
/******************************************************************/
void tim(void) interrupt 1 using 1
//中斷,用於數碼管掃描
{
static unsigned char i,num;
TH0=0xf5;
TL0=0xe0;
P0=table[l_tmpdisplay[i]]; //查表法得到要顯示數字的數碼段
switch(i)
{
case 0:LS138A=0; LS138B=0; LS138C=0; break;
case 1:LS138A=1; LS138B=0; LS138C=0; break;
case 2:LS138A=0; LS138B=1; LS138C=0; break;
case 3:LS138A=1; LS138B=1; LS138C=0; break;
case 4:LS138A=0; LS138B=0; LS138C=1; break;
case 5:LS138A=1; LS138B=0; LS138C=1; break;
case 6:LS138A=0; LS138B=1; LS138C=1; break;
case 7:LS138A=1; LS138B=1; LS138C=1; break;
}
i++;
if(i==8)
{
i=0;
num++;
if(10==num) //隔段時間讀取1302的數據。時間間隔可以調整
{
ReadRTC_Flag=1; //使用標志位判斷
num=0;
}
}
}
6. 求一個51單片機定時鬧鍾程序。要C語言。能夠調時間
我來發一個C語言51單片機時鍾程序,希望能幫到你
/*程序功能:帶定時鬧鈴時鍾*/
/*---------------------------------------------------------------*/
#include<AT89X51.H>/*包含器件配置文件*/
#defineucharunsignedchar
#defineuintunsignedint
charDATA_7SEG[10]={0xC0,0xF9,0xA4,0xB0,0x99,
0x92,0x82,0xF8,0x80,0x90,};/*0~9的數碼管段碼*/
ucharhour=0,min=0,sec=0;/*時、分、秒單元清零*/
uchardeda=0;/*5mS計數單元清零*/
bitd_05s=0;/*0.5秒標志*/
ucharset=0;/*模式設定標志*/
ucharm=0;
ucharflag=0;/*RAM掉電標志*/
voiddelay(uintk);/*延時?函數*/
voidconv();/*走時單元轉換*/
voiddisp();/*走時時間顯示?函數*/
/*------------------------走時?函數部分----------------------*/
/*定時器T05mS初始化*/
voidinit_timer()
{
TMOD=0x01;
TH0=-(4800/256);
TL0=-(4800%256);
IE=0x82;
TR0=1;
}
/*---------------------------------*/
/*5mS定時中斷服務?函數*/
voidT0_srv(void)interrupt1
{
TH0=-(4800/256);
TL0=-(4800%256);
deda++;
}
/*----------------------------------*/
/*時、分、秒單元及走時單元轉換*/
voidconv()
{
if(deda<=100)d_05s=0;
elsed_05s=1;
if(deda>=200){sec++;deda=0;}
if(sec==60){min++;sec=0;}
if(min==60){hour++;min=0;}
if(hour==24){hour=0;}
}
/*------------------------顯示?函數部分----------------------*/
/*走時時間顯示?函數*/
voiddisp()
{
P0=DATA_7SEG[hour/10];P2=0xf7;delay(1);
P0=DATA_7SEG[hour%10];P2=0xfb;delay(1);
if(d_05s==1){if(P2_2==0)P0_7=0;elseP0_7=1;}
delay(1);
P0=DATA_7SEG[min/10];P2=0xfd;delay(1);
P0=DATA_7SEG[min%10];P2=0xfe;delay(1);
}
/*----------------------調整時間?函數部分-------------------*/
/*調整走時時間*/
voidset_time()
{ucharm;
if(P2_5==0)delay(1);
if(P2_5==0)hour++;
if(hour==24)hour=0;
for(m=0;m<30;m++)
{
disp();
if(P2_2==0)P0_7=0;
elseP0_7=1;
delay(1);
}
if(P2_6==0)delay(1);
if(P2_6==0)min++;
if(min==60)min=0;
for(m=0;m<30;m++)
{
disp();
if(P2_2==0)P0_7=0;
elseP0_7=1;
delay(1);
}
}
/*------------------按鍵掃描、延時等?函數部分-------------------*/
/*走時時間程序?函數*/
voidtime()
{
conv();/*走時單元轉換?函數*/
disp();/*走時時間顯示?函數*/
}
/*------------------------------------*/
/*掃描按鍵?函數*/
voidscan_key()
{
delay(1);
if(P2_4==0)set++;
if(set>=2)set=0;
if(set==1)flag=0x55;
F0:if(P2_4==0)gotoF0;/*按鍵未釋放,在此等候*/
}
/*------------------------------*/
/*延時?函數*/
voiddelay(uintk)
{
uinti,j;
for(i=0;i<k;i++){
for(j=0;j<121;j++)
{;}}
}
/*-----------------------主函數-------------------------*/
/*主函數*/
voidmain()
{
init_timer();/*定時器T0初始化*/
while(1)/*無限循環*/
{
if(P2_4==0)scan_key();/*有按鍵,調用按鍵掃描?函數*/
switch(set)/*根據set鍵值散轉*/
{
case0:time();break;/*走時時間程序*/
case1:set_time();break;/*走時時間調整*/
default:break;/*其它退出*/
}
if(flag!=0x55)/*判斷掉電標志*/
{
P0=0xc0;P2=0xc0;delay(100);
P2=0xff;delay(400);
}
}
}
7. 51單片機求這個時鍾的c語言程序
以下是四位數碼管可調時帶秒閃爍的c51單片機電子鍾程序(c語言)。
/**** 本程序中,晶振為12MHz, ****/
/**** 時間控制採用定時中斷控制方式。 ****/
/**** 模式和時間調整採用查詢方式。 ****/
#include<reg52.h>
sbit P20=P2^0; //分個位控制端
sbit P21=P2^1; //分十位控制端
sbit P22=P2^2; //時個位控制端
sbit P23=P2^3; //時十位控制端
sbit led=P2^7; //second display led
sbit key0=P3^0; //模式設置
sbit key1=P3^1; //加
sbit key2=P3^2; //減
unsigned char hour,min,sec,T50ms;
unsigned char modstate; //模式狀態
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//段碼
void init(); //初始化子程序聲明
void delay500us(unsigned char X); //延時子程序聲明
void display(); //顯示子程序聲明
void display001(); //顯示子程序聲明
void display002(); //顯示子程序聲明
void keyscan(); //按鍵識別子程序聲明
void main()
{
init();
while(1)
{
keyscan();
}
}
void init() //初始化子程序
{
TMOD=0x01;
TH0=(65536-49990)/256;
TL0=(65536-49990)%256;
ET0=1;
EA=1;
TR0=1;
}
void delay500us(unsigned char X)
{
unsigned char i,j;
for(i=X;i>0;i--)
for(j=248;j>0;j--);
}
void timer0() interrupt 1 //timer0中斷服務子程序,定時時間為50ms,本程序加了10us的時間修正量
{
TMOD=0x01;
TH0=(65536-49990)/256;
TL0=(65536-49990)%256;
T50ms++;
if(T50ms>=20)
{
T50ms=0;
sec++;
if(sec>=60)
{
sec=0;
min++;
if(min>=60)
{
min=0;
hour++;
if(hour>=24)hour=0;
}
}
}
}
void display()
{
P20=1;
P21=1;
P22=1;
P23=1;
P0=table[hour/10];
P23=0;
delay500us(5);
P20=1;
P21=1;
P22=1;
P23=1;
P0=table[hour%10];
P22=0;
delay500us(5);
P20=1;
P21=1;
P22=1;
P23=1;
P0=table[min/10];
P21=0;
delay500us(5);
P20=1;
P21=1;
P22=1;
P23=1;
P0=table[min%10];
P20=0;
delay500us(5);
if(T50ms<=10)led=0;
if(T50ms>10)led=1;
}
void display001()
{
P20=1;
P21=1;
P22=1;
P23=1;
P0=table[hour/10];
P23=0;
delay500us(10);
P20=1;
P21=1;
P22=1;
P23=1;
P0=table[hour%10];
P22=0;
delay500us(10);
}
void display002()
{
P20=1;
P21=1;
P22=1;
P23=1;
P0=table[min/10];
P21=0;
delay500us(10);
P20=1;
P21=1;
P22=1;
P23=1;
P0=table[min%10];
P20=0;
delay500us(10);
}
void keyscan() //按鍵識別鍾程序
{
while(modstate==0)
{
display();
if(key0==0)
{
display();
if(key0==0)modstate++; //這兩句加在一起為延時10ms軟體防抖設計。
while(key0==0)display001(); //等待按鍵釋放。
}
}
//****************************************************************************//
while(modstate==1)
{
display001();
if(key0==0)
{
display001();
if(key0==0)modstate++; //這兩句加在一起為延時10ms軟體防抖設計。
while(key0==0)display002(); //等待按鍵釋放。
}
if(key1==0)
{
display001();
if(key1==0)
{
hour++;
if(hour>=24)hour=0;
while(key1==0)display001();
}
}
if(key2==0)
{
display001();
if(key2==0)
{
hour--;
if(hour>=24)hour=0;
while(key2==0)display001();
}
}
}
//****************************************************************************//
while(modstate==2)
{
display002();
if(key0==0)
{
display002();
if(key0==0)modstate=0; //這兩句加在一起為延時10ms軟體防抖設計。
while(key0==0)display(); //等待按鍵釋放。
}
if(key1==0)
{
display002();
if(key1==0)
{
min++;
if(min>=60)min=0;
while(key1==0)display002();
}
}
if(key2==0)
{
display002();
if(key2==0)
{
min--;
if(min>=60)min=0;
while(key2==0)display002();
}
}
}
}
8. 51單片機 c語言寫的電子時鍾程序 請幫忙指正!
單片機程序抄是基於硬體基礎上開襲發的,你至少添加註釋和硬體環境說明,不然大家都不知道怎麼幫你。
你直接給出代碼,也不清楚需要指正什麼,這里也沒有設置時間/鬧鍾的代碼,發文前應該清楚表達要問的內容。
1)假設你的晶振是12MHz,那一個機器周期是1MHz,定時器的最長定時周期是(65535/10^6)你想要1/6秒觸發一次中斷就必須結合軟體計時,為了盡量精確:硬體計時40000次,軟體計時25次那麼定時器的設這應該是TH1=(65535-40000)%256;TL1=(65535-40000)%256,(注意計數器大部分是加法計數)
2)按鍵監聽沒有給出思路,也沒有處理按鍵抖動,我只能分析程序:
有一個外部中斷觸發時間設置,P34設置小時、P35設置分鍾,但是調整時間後沒有進行顯示,你至少要讓數碼管顯示結果才能知道怎麼調整。
9. 用C語言寫51單片機鬧鍾程序
//*********************************************************
//實現功能:本程序實現在P1口模擬一個流水燈程序
//*********************************************************
#include <reg51.h>
#define p_out P1 //宏定義輸出的i/o口為P1
//******************時間延遲函數**********************
//描 述:用指令實現延時一段時間
//入口參數:int i,為時間延遲參數
//****************************************************
void delay_time(int i)
{
while(i)
i--;
}
//******************主函數***************************
//描 述:實現在P1口模擬一個流水燈程序
//****************************************************
void main(void)
{unsigned char i=0; //初始化一個局部變數為0
p_out=0xff; //初始化將要輸出的i/o口,輸出高電平,熄滅所有燈
while(1)
{
for(i=0;i<8;i++)
{
p_out=~(1<<i);//點亮一個燈,
delay_time(50000); //延遲一段時間
p_out=0xff;//熄滅所有燈
}
}
}
//**************************************
//****************************************************
//實現功能:把鍵盤輸入的鍵盤碼,用led顯示出來
//****************************************************
#include <reg51.h>
#define p_key P1
#define led_date P0
#define choose_p P2
unsigned char change(unsigned char i);
unsigned int display_num=0;
//******************時間延遲函數**********************
//描 述:用指令實現延時一段時間
//入口參數:int i,為時間延遲參數
//****************************************************
void delay_time(int i)
{
while(i)
i--;
}
//******************按鍵掃描函數**********************
//描 述:對4*4鍵盤進行掃描,程序只適合4*4鍵盤使用,
// 鍵盤佔用一組完整的i/o口,在使用這個程序前
// 要宏定義p_key為用戶實際連接鍵盤的i/o口
// #define p_key Pn;//(n=0、1、2、3)
//返回參數:若有檢測到按鍵就返回按鍵的編號,否則返回0xff
//****************************************************
unsigned char read_key(void)
{
unsigned char j,key,key_buf=0;
p_key=0xff;
//檢測是否有建按下//
p_key=0xf0;
key=p_key;
if(key==0xf0)
{
return(0xff);//沒按鍵按下,返回0xff
}
//有按下,延時去抖//
delay_time(5000);
//確認是否有建按下//
p_key=0xf0;
key=p_key;
if(key==0xf0)
{
return(0xff);//沒按鍵按下,返回0xff
}
//真的有按鍵按下,掃描是哪一行有按鍵按下//
for(j=0;j<4;j++)
{key=p_key&(0x10<<j);
if (key)
{
key=p_key;
}
else
{
key_buf=j*4;
p_key=~(0x10<<j);//第j行的按鍵按下了,第j行輸出0,其他的i/o口輸出1
//掃描是第j行的哪個按鍵按下//
for(j=0;j<4;j++)
{
key=p_key&(1<<j);
if (key)
{
key=p_key;
}
else
{
key_buf+=j;
return(key_buf);//掃描到按鍵的確定位置,返回按鍵的編號
}
}
}
}
//沒掃描到按鍵,//
return(0xff);
}
//***************七段數碼管顯示函數*******************
//描 述:對四位的掃描型七段數碼管進行掃描顯示,在使用
// 前要定義一個全局變數display_num
// unsigned int display_num;
//入口參數:unsigned int num,要顯示的數字(0-9999)
//****************************************************
void display(unsigned int num)
{
if(num<10000)
{
display_num=num;
}
choose_p|=3;//先關顯示
led_date=change(display_num/1000);//得到千位的數字,並轉換成七段碼型
choose_p&=0xfe;//選通千位
delay_time(50);//延時一段時間
choose_p|=1;//關顯示
display_num=display_num%1000;
led_date=change(display_num/100);//得到百位的數字,並轉換成七段碼型
choose_p&=0xfd;//選通百位
delay_time(50);//延時一段時間
choose_p|=2;//關顯示
display_num=display_num%100;
led_date=change(display_num/10);//得到十位的數字,並轉換成七段碼型
choose_p&=0xfb;//選通十位
delay_time(50);//延時一段時間
choose_p|=4;//關顯示
led_date=change(display_num%10);//得到個位的數字,並轉換成七段碼型
choose_p&=0xf7;//選通十位
delay_time(50);//延時一段時間
choose_p|=8;//關顯示
}
//****************數字-碼型轉換函數*******************
//描 述:把數字轉換成七段碼型,此程序僅配合共陽的七
// 段數碼管使用
//入口參數:unsigned char i,要轉換的數字(0-9),
//返回參數:轉換後的七段碼型,0xff表示轉換失敗
//****************************************************
unsigned char change(unsigned char i)
{
switch(i)
{
case 0:
return(0xc0);//0的七段碼型
case 1:
return(0xf9);//1的七段碼型
case 2:
return(0xa4);//2的七段碼型
case 3:
return(0xb0);//3的七段碼型
case 4:
return(0x99);//4的七段碼型
case 5:
return(0x92);//5的七段碼型
case 6:
return(0x82);//6的七段碼型
case 7:
return(0xf8);//7的七段碼型
case 8:
return(0x80);//8的七段碼型
case 9:
return(0x90);//9的七段碼型
default:
return(0xff);//轉換失敗
}
}
//*********************主函數*************************
//描 述:把鍵盤輸入的鍵盤碼,用led顯示出來
//****************************************************
int main(void)
{unsigned char i;
while(1)
{
i=read_key();//掃描鍵盤
if(i<16)
display((unsigned int)i);//有效的鍵盤值
else
display(0xffff);//數據無效
}
}
//兩個程序加起來就可以完成你要求的功能,有說明,你認真看一下吧。
10. 51單片機時鍾程序設計
朋友以下是本人歷時一個月殫精竭慮自主開發的一個8位51單片機時鍾程序,望吾之兄弟姐妹習之,此程序乃採用一鍵控制,通過感知按下鍵持續時間的長短來進行調整時間,鬧鈴,6隻共陽數碼管輸出顯示,此外還包括整點鈴聲功能,在看程序之前我先交代一下運行該程序的硬體要求:12M晶振,P0埠驅動顯示,P2.0到P2.5控制顯示掃描,P2.7輸出鈴聲,注意:鈴聲功放三極體應採用pnp管。以下是該程序:
ORG 00H
SETB TR0
JMP START
ORG 000BH
LJMP T0
START: MOV IE,#82H
MOV TMOD,#01H
MOV DPTR,#TAB
MOV SP,#60H
MOV 20H,#0
MOV R0,#0
MOV R1,#0
MOV R2,#0
MOV R3,#0
MOV R4,#0
MOV R5,#0
MOV R6,#0
MOV R7,#0
MOV 50H,#0
MOV 51H,#0
MOV 52H,#0
MOV 53H,#0
MOV 54H,#0
MOV 55H,#0
MOV A,TL0
ADD A,0B5H
MOV TL0,A
MOV TH0,#3CH
LOOP: ANL 20H,#08H
UNSV: MOV R1,#0
LCALL DISPLAY
JB 03H,LOP1
LCALL SOUND
LCALL HDLY
LOP1: MOV P3,#0FEH ;按鍵監視
MOV A,P3
CJNE A,#0FEH,LOP2
MOV R1,#0
JMP LOOP
LOP2: MOV R1,#2 ;誤按判斷
LOP3: LCALL HD
DJNZ R1,LOP3
JNB 04H,LOOP
CLR 04H
LOP4: INC R1
MOV C,00H ;調秒
CPL C
MOV 00H,C
LCALL HDLY
CJNE R1,#40,LOP5
JMP LOOP
LOP5: JNB 05H,LOP4
CLR 05H
MOV R1,#0
LCALL HD
CLR 00H
JB 04H,TF
MOV R2,#0
MOV R3,#0
JMP LOP4
TF: CLR 04H
LOP6: INC R1
MOV C,01H ;調分
CPL C
MOV 01H,C
LCALL HDLY
CJNE R1,#40,LOP7
JMP LOOP
LOP7: JNB 05H,LOP6
CLR 05H
MOV R1,#0
LCALL HD
CLR 01H
JB 04H,TS
INC R4
MOV R1,#0
CJNE R4,#10,LOP6
MOV R4,#0
INC R5
CJNE R5,#6,LOP6
MOV R5,#0
JMP LOP6
TS: CLR 04H
LOP8: INC R1
MOV C,02H ;調時
CPL C
MOV 02H,C
LCALL HDLY
CJNE R1,#40,LOP9
JMP LOOP
LOP9: JNB 05H,LOP8
CLR 05H
MOV R1,#0
LCALL HD
CLR 02H
JB 04H,TN
INC R6
CJNE R7,#2,NO2
CJNE R6,#4,LOP8
MOV R7,#0
MOV R6,#0
NO2: CJNE R6,#10,LOP8
MOV R6,#0
INC R7
JMP LOP8
TN: CLR 04H ;調鬧鈴
SETB RS0
CLR RS1
MOV R2,#0
MOV R3,#0
MOV R4,#0
MOV R5,#0
MOV R6,#0
MOV R7,#0
NS: INC R1 ;鬧鈴秒調整
MOV C,00H
CPL C
MOV 00H,C
LCALL HDLY
CJNE R1,#40,NS1
JMP NH2
NS1: JNB 05H,NS
CLR 05H
MOV R1,#0
LCALL HD
CLR 00H
JB 04H,NF
INC R2
CJNE R2,#10,NS
MOV R2,#0
INC R3
CJNE R3,#6,NS
MOV R3,#0
JMP NS
NF: CLR 04H ;鬧鈴分
NF1: INC R1
MOV C,01H
CPL C
MOV 01H,C
LCALL HDLY
CJNE R1,#40,NF2
LJMP NH2
NF2: JNB 05H,NF1
CLR 05H
MOV R1,#0
LCALL HD
CLR 01H
JB 04H,NH
INC R4
CJNE R4,#10,NF1
MOV R4,#0
INC R5
CJNE R5,#6,NF1
MOV R5,#0
JMP NF1
NH: CLR 04H ;鬧鈴時調整
NH1: INC R1
MOV C,02H
CPL C
MOV 02H,C
LCALL HDLY
CJNE R1,#40,NH3
NH2: MOV 50H,R2
MOV 51H,R3
MOV 52H,R4
MOV 53H,R5
MOV 54H,R6
MOV 55H,R7
CLR RS0
CLR RS1
LJMP LOOP
NH3: JNB 05H,NH1
CLR 05H
MOV R1,#0
LCALL HD
CLR 02H
JB 04H,NH2
INC R6
CJNE R7,#2,NOT2
CJNE R6,#4,NH1
MOV R6,#0
MOV R7,#0
JMP NH1
NOT2: CJNE R6,#10,NH1
MOV R6,#0
INC R7
JMP NH1
;子程序區
TIMES: CJNE R0,#20,LOOP16
MOV R0,#0
INC R2
CJNE R2,#10,LOOP16
MOV R2,#0
INC R3
CJNE R3,#6,LOOP16
MOV R3,#0
ADMINI: INC R4
CJNE R4,#10,LOOP16
MOV R4,#0
INC R5
CJNE R5,#6,LOOP16
MOV R5,#0
HOUR: INC R6
LCALL SOUND ;整點鈴聲
CJNE R7,#2,LOOP14
CJNE R6,#4,LOOP16
MOV R6,#0
MOV R7,#0
JMP LOOP16
LOOP14: CJNE R6,#10,LOOP16
MOV R6,#0
INC R7
LOOP16: RET
DISPLAY:MOV P2,#0FFH
MOV A,R2
MOVC A,@A+DPTR
MOV P0,A
MOV C,00H
MOV P2.0,C
MOV P2,#0FFH
MOV A,R3
MOVC A,@A+DPTR
MOV P0,A
MOV P2.1,C
MOV P2,#0FFH
MOV A,R4
MOVC A,@A+DPTR
MOV P0,A
MOV C,01H
MOV P2.2,C
MOV P2,#0FFH
MOV A,R5
MOVC A,@A+DPTR
MOV P0,A
MOV P2.3,C
MOV P2,#0FFH
MOV A,R6
MOVC A,@A+DPTR
MOV P0,A
MOV C,02H
MOV P2.4,C
MOV P2,#0FFH
MOV A,R7
MOVC A,@A+DPTR
MOV P0,A
MOV P2.5,C
MOV P2,#0FFH
RET
HDLY: MOV 40H,#2
HDL1: MOV 41H,#25
HDL2: MOV 42H,#100
HDL3: DJNZ 42H,HDL4
DJNZ 41H,HDL2
DJNZ 40H,HDL1
JMP HDOT
SOUT: SETB 05H
HDOT: RET
HDL4: MOV P3,#0FEH
MOV A,P3
CJNE A,#0FEH,SOUT
CLR 05H
LCALL DISPLAY
JMP HDL3
HD: MOV 30H,#5
HD1: MOV 31H,#50
HD2: MOV 32H,#100
HD3: LCALL DISPLAY
DJNZ 32H,HD4
DJNZ 31H,HD2
DJNZ 30H,HD1
SETB 04H ;計滿標志位
JMP HDOUT
HD4: MOV P3,#0FEH
MOV A,P3
CJNE A,#0FEH,HD3
MOV 33H,#50
HD5: MOV 34H,#100
DJNZ 34H,$
DJNZ 33H,HD5
MOV P3,#0FEH
MOV A,P3
CJNE A,#0FEH,HD3
CLR 04H
HDOUT: RET
SOUND: MOV 30H,#10
SO1: MOV 31H,#100
SO2: MOV 32H,#3
MOV C,P2.7
CPL C
MOV P2.7,C
SO3: MOV 33H,#25
DJNZ 33H,$
DJNZ 32H,SO3
DJNZ 31H,SO2
DJNZ 30H,SO1
RET
T0: PUSH PSW
PUSH ACC
CLR RS1
CLR RS0
MOV A,TL0
ADD A,#0B5H
MOV TL0,A
MOV TH0,#3CH
INC R0
LCALL TIMES
MOV A,R2
CJNE A,50H,TO
SETB 03H
MOV A,R3
CJNE A,51H,TO
MOV A,R7
CJNE A,55H,TO
MOV A,R6
CJNE A,54H,TO
MOV A,R5
CJNE A,53H,TO
MOV A,R4
CJNE A,52H,TO
MOV A,R2
ADD A,R3
ADD A,R4
ADD A,R5
ADD A,R6
ADD A,R7
JZ TO
CLR 03H
TO: POP ACC
POP PSW
RETI
TAB: DB 0C0H 0F9H 0A4H 0B0H 099H
DB 092H 082H 0F8H 080H 090H
END