㈠ 51單片機的4位數碼管做簡易秒錶C語言程序
#include"dz110306140.h"這是什麼頭文件
㈡ 51單片機C語言編程
// 51單片機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--);
}
㈢ 51單片機定時中斷C語言的寫法步驟,可追加分數
程序說明:51單片機定時器0工作於方式一,定時50ms中斷一次
晶振為12M
#include
void
main
{
TOMD
=
0X01;
//配置定時器0工作於方式一
TH1
=
(65536-50000)/256;
//高八位裝入初值
TL1
=
(65536-50000)%256;
//低八位裝入初值
ET0
=
1;
//開定時器0中斷
EA
=
1;
//開總中斷
TR0
=
1;
//啟動定時器0
while(1)
{
;
}
}
void
Timer0_int()
interrupt
1
{
//重新裝初值
TH1
=
(65536-50000)/256;
//高八位裝入初值
TL1
=
(65536-50000)%256;
//低八位裝入初值
}
/***************************************************************************************************************/
上面是比較好理解的。如果實在要求簡潔的話,看下面的,跟上面功能一樣
#include
void
main
{
TOMD
=
0X01;
//配置定時器0工作於方式一
TH1
=
0x3c;
//高八位裝入初值
TL1
=
0xb0;
//低八位裝入初值
IE
=
0x82;//開總中斷並開定時器0中斷
TR0
=
1;
//啟動定時器0
while(1)
{
;
}
}
void
Timer0_int()
interrupt
1
{
//重新裝初值
TH1
=
0x3c;
//高八位裝入初值
TL1
=
0xb0;
//低八位裝入初值}
㈣ 51單片機編程,用C語言。
給你一個矩陣鍵盤的參考程序
行列掃描:通過高四位全部輸出低電平,低四位輸出高電平。當接收到的數據,低四位不全為高電平時,說明有按鍵按下,然後通過接收的數據值,判斷是哪一列有按鍵按下,然後再反過來,高四位輸出高電平,低四位輸出低電平,然後根據接收到的高四位的值判斷是那一行有按鍵按下,這樣就能夠確定是哪一個按鍵按下了。
/****************************************************************************
*函數名
:KeyDown
*函數功能
:
檢測有按鍵按下並讀取鍵值
*輸入
:
無
*輸出
:
無
****************************************************************************/
voidKeyDown(void)
{
char
a=0;
GPIO_KEY=0x0f;
if(GPIO_KEY!=0x0f)//讀取按鍵是否按下
{
Delay10ms();//延時10ms進行消抖
if(GPIO_KEY!=0x0f)//再次檢測鍵盤是否按下
{
GPIO_KEY=0X0F;
//測試列
switch(GPIO_KEY)
{
case(0X07):
KeyValue=0;break;
case(0X0b):
KeyValue=1;break;
case(0X0d):
KeyValue=2;break;
case(0X0e):
KeyValue=3;break;
}
//測試行
GPIO_KEY=0XF0;
switch(GPIO_KEY)
{
case(0X70):
KeyValue=KeyValue;break;
case(0Xb0):
KeyValue=KeyValue+4;break;
case(0Xd0):
KeyValue=KeyValue+8;break;
case(0Xe0):
KeyValue=KeyValue+12;break;
}
while((a<50)&&(GPIO_KEY!=0xf0))//按鍵鬆手檢測
{
Delay10ms();
a++;
}
}
}
}
㈤ 用51單片機編寫城市道路交通燈c語言程序,有左轉右轉
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit RED_A=P3^0; //東西向指示燈
sbit YELLOW_A=P3^1;
sbit GREEN_A=P3^2;
sbit RED_B=P3^3; //南北向指示燈
sbit YELLOW_B=P3^4;
sbit GREEN_B=P3^5;
sbit KEY1=P1^0;
sbit KEY2=P1^1;
sbit KEY3=P1^2;
//延時倍數,閃爍次數,操作類型變數
uchar Flash_Count=0,Operation_Type=1,LEDsng,LEDsns,LEDewg,LEDews,discnt;
uint Time_Count=0,time;
uchar ledtab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};
void displaysn()
{
LEDsng=((time-Time_Count)/20)%10;
LEDsns=((time-Time_Count)/20)/10;
LEDewg=0x10;
LEDews=0x10;
}
void displayew()
{
LEDewg=((time-Time_Count)/20)%10;
LEDews=((time-Time_Count)/20)/10;
LEDsng=0x10;
LEDsns=0x10;
}
//定時器0 中斷函數
void T0_INT() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
switch(Operation_Type)
{
case 1: //東西向綠燈與南北向紅燈亮
if((Time_Count%20)==0)displayew();
RED_A=0;YELLOW_A=0;GREEN_A=1;
RED_B=1;YELLOW_B=0;GREEN_B=0;
if(++Time_Count!=time) return;
Time_Count=0;
Operation_Type=2;
break;
case 2: //東西向黃燈開始閃爍,綠燈關閉
LEDewg=0x0;
LEDews=0x0;
if(++Time_Count!=8) return;
Time_Count=0;
YELLOW_A=~YELLOW_A;GREEN_A=0;
if(++Flash_Count!=10) return; //閃爍
Flash_Count=0;
Operation_Type=3;
break;
case 3: //東西向紅燈與南北向綠燈亮
if((Time_Count%20)==0)displaysn();
RED_A=1;YELLOW_A=0;GREEN_A=0;
RED_B=0;YELLOW_B=0;GREEN_B=1;
if(++Time_Count!=time) return;
Time_Count=0;
Operation_Type=4;
break;
case 4: //南北向黃燈開始閃爍,綠燈關閉
LEDsng=0x0;
LEDsns=0x0;
if(++Time_Count!=8) return;
Time_Count=0;
YELLOW_B=~YELLOW_B;GREEN_A=0;
if(++Flash_Count!=10) return; //閃爍
Flash_Count=0;
Operation_Type=1;
break;
}
}
void t1_isr() interrupt 3
{
TR1=0;
TH1=(65536-3000)/256;
TL1=(65536-3000)%256;
TR1=1;
switch(discnt)
{
case 0:
P2=0x02;
P0=ledtab[LEDewg];
break;
case 1:
P2=0x01;
P0=ledtab[LEDews];
break;
case 2:
P2=0x08;
P0=ledtab[LEDsng];
break;
case 3:
P2=0x04;
P0=ledtab[LEDsns];
break;
default:discnt=0;break;
}
discnt++;
discnt&=0x03;
}
void delay()
{
uint i;
for(i=0;i<1000;i++);
}
//主程序
void main()
{
TMOD=0x11; //T0 方式1
EA=1;
ET0=1;
TR0=1;
TH1=(65536-3000)/256;
TL1=(65536-3000)%256;
TR1=1;
ET1=1;
time=100;
Time_Count=100;
Time_Count=0;
Operation_Type=1;
while(1)
{
if(KEY1==0) //按一下加1S
{
delay();
if(KEY1==0)
{
while(KEY1==0);
TR0=0;
time+=20;
LEDsng=(time/20)%10;
LEDsns=(time/20)/10;
LEDewg=0x10;
LEDews=0x10;
}
}
if(KEY2==0) //按一下減1S
{
delay();
if(KEY2==0)
{
while(KEY2==0);
TR0=0;
time-=20;
if(time==0)time=20;
LEDewg=(time/20)%10;
LEDews=(time/20)/10;
LEDsng=0x10;
LEDsns=0x10;
}
}
if(KEY3==0) //啟動
{
delay();
if(KEY3==0)
{
while(KEY2==0);
TR0=1;
Time_Count=0;
}
}
}
}
㈥ 新概念51單片機C語言教程的作品目錄
第1篇入門篇
1.1單片機概述
1.1.1什麼是單片機
1.1.2單片機標號信息及封裝類型
1.1.3單片機能做什麼
1.1.4如何開始學習單片機
1.251單片機外部引腳介紹
1.3電平特性
1.4二進制與十六進制
1.4.1二進制
1.4.2十六進制
1.5二進制的邏輯運算
1.5.1與
1.5.2或
1.5.3非
1.5.4同或
1.5.5異或
1.6單片機的C51基礎知識介紹
1.6.1利用C語言開發單片機的優點
1.6.2C51中的基本數據類型
1.6.3C51數據類型擴充定義
1.6.4C51中常用的頭文件
1.6.5C51中的運算符
1.6.6C51中的基礎語句
1.6.7學習單片機應該掌握的主要內容
2.1Keil工程建立及常用按鈕介紹
2.1.1Keil工程的建立
2.1.2常用按鈕介紹
2.2點亮第一個發光二極體
2.3while語句
2.4for語句及簡單延時語句
2.5Keil模擬及延時語句的精確計算
2.6不帶參數函數的寫法及調用
2.7帶參數函數的寫法及調用
2.8利用C51庫函數實現流水燈
第2篇內外部資源操作篇
3.1數碼管顯示原理
3.2數碼管靜態顯示
3.3數碼管動態顯示
3.4中斷概念
3.5單片機的定時器中斷
4.1獨立鍵盤檢測
4.2矩陣鍵盤檢測
5.1模擬量與數字量概述
5.2A/D轉換原理及參數指標
5.3ADC0804工作原理及其實現方法
5.4D/A轉換原理及其參數指標
5.5DAC0832工作原理及實現方法
5.6DAC0832輸出電流轉換成電壓的方法
第6章串列口通信原理及操作流程
6.1並行與串列基本通信方式
6.2RS-232電平與TTL電平的轉換
6.3波特率與定時器初值的關系
6.451單片機串列口結構描述
6.5串列口方式1編程與實現
6.6串列口列印在調試程序中的應用
第7章通用型1602,12232,12864液晶操作方法
7.1液晶概述
7.2常用1602液晶操作實例
7.3常用12232液晶操作實例
7.4常用12864液晶操作實例
第8章I2C匯流排AT24C02晶元應用
8.1I2C匯流排概述
8.2單片機模擬I2C匯流排通信
8.3E2PROMAT24C02與單片機的通信實例
第9章基礎運放電路專題
9.1運放概述及參數介紹
9.2反相放大器
9.3同相放大器
9.4電壓跟隨器
9.5加法器
9.6差分放大器
9.7微分器
9.8積分器
第3篇提高篇
第10章定時器/計數器應用提高
10.1方式0應用
10.2方式2應用
10.3方式3應用
10.452單片機定時器2介紹
10.5計數器應用
第11章串列口應用提高
11.1方式0應用
11.2方式2和方式3應用
11.3單片機雙機通信
11.4單片機多機通信
第12章指針
12.1指針與指針變數
12.1.1內存單元、地址和指針
12.1.2指針變數的定義、賦值與引用
12.2指針變數的運算
12.3指針與數組
12.3.1指針與一維數組
12.3.2指針與多維數組
12.4指針與函數
12.4.1指針作為函數的參數
12.4.2指向函數的指針
12.4.3指針型函數
12.5指針與字元串
12.5.1字元串的表達形式
12.5.2字元指針作為函數參數
12.5.3使用字元指針與字元數組的區別
12.6指針數組與命令行參數
12.6.1指針數組的定義和使用
12.6.2指向指針的指針
12.6.3指針數組作為main()函數的命令行參數
12.7指針小結
12.7.1指針概念綜述
12.7.2指針運算小結
12.7.3等價表達式
12.8C51中指針的使用
12.8.1指針變數的定義
12.8.2指針應用
第13章STC系列51單片機功能介紹
13.1單片機空閑與掉電模式應用
13.2「看門狗」概念及其應用
13.3用軟體實現系統復位
13.4內部擴展RAM的應用
13.5擴展P4口的應用
13.6內部E2PROM的應用
13.7STC89系列單片機內部A/D應用
13.8STC12系列單片機內部A/D應用
13.9STC12系列單片機的PCA/PWM介紹
13.10STC12系列單片機的SPI介面介紹
13.11STC12系列單片機的「576MHz」超速運行
第4篇實戰篇
第14章利用51單片機的定時器設計一個時鍾
14.1如何從矩陣鍵盤中分解出獨立按鍵
14.2原理圖分析
14.3實例講解
第15章使用DS12C887時鍾晶元設計高精度時鍾
15.1時鍾晶元概述
15.2DS12C887時鍾晶元介紹
15.3如何用TX-1C實驗板擴展本實驗
15.4原理圖分析
15.5實例講解
第16章使用DS18B20溫度感測器設計溫控系統
16.1溫度感測器概述
16.2DS18B20溫度感測器介紹
16.3實例講解
第17章太陽能充/放電控制器
17.1控制器原理圖分析
17.2控制器板上元件介紹
17.3實例講解
第18章VC、VB(MSCOMM控制項)與單片機通信實現溫度顯示
18.1VCMSCOMM控制項與單片機通信實現溫度顯示
18.2VBMSCOMM控制項與單片機通信實現溫度顯示
第5篇拓展篇
第19章使用Protell99繪制電路圖全過程
19.1繪制電路板概述
19.2建立工程
19.3製作元件庫
19.4添加封裝及製作PCB封裝庫
19.5錯誤檢查及生成PCB
19.6布線電氣特性設置
19.7自動布線和手動布線
第20章ISD400x系列語音晶元應用
20.1ISD400x系列語音晶元介紹
20.2ISD400x系列語音晶元操作規則
20.3ISD400x系列語音晶元應用實現
第21章電機專題
21.1直流電機原理及應用
21.2步進電機原理及應用
21.3舵機原理及其應用
第22章常用元器件介紹
22.1二極體
22.2電容
22.3場效應管
22.4光耦
22.5蜂鳴器
22.6繼電器
22.7自恢復保險
22.8瞬態電壓抑制器
22.9晶閘管(可控硅)
22.10電荷泵
第23章直流穩壓電源專題
23.1整流電路
23.2濾波電路
23.3穩壓電路
23.4集成穩壓模塊的使用
23.5串聯開關型穩壓電源
第24章運放擴展專題
24.1簡單低通濾波器
24.2「電流-電壓」轉換電路
24.3光電放大器
24.4精密電流源
24.5可調參考電壓源
24.6復位穩定放大器
24.7模擬乘法器
24.8全波整流器和平均值濾波器
24.9正弦波振盪器
24.10三角波發生器
24.11自動跟蹤對稱電源
24.12可調實驗電源
24.13運放相關術語表
附錄A天祥電子開發實驗板簡介
A.1TX-1C51單片機開發板(配套詳細視頻教程)
A.2AVR單片機開發板(配套詳細視頻教程)
A.3PIC單片機開發板(配套詳細視頻教程)
A.4J-Link全功能ARM模擬器
A.5三星S3C44B0ARM7入門級開發板
A.6三星S3C44B0ARM7提高級開發板
A.7TX-51STAR51單片機開發板(配套詳細視頻教程)
參考文獻
㈦ c51單片機c語言交通燈的程序
Proteus模擬原理圖:
程序如下:
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar data buf[4];
uchar data sec_dx=20;//東西數默認
uchar data sec_nb=30;//南北默認值
uchar data set_timedx=20;
uchar data set_timenb=30;
int n;
uchar data b;//定時器中斷次數
sbit k1=P1^6;//定義5組開關
sbit k2=P1^7;
sbit k3=P2^7;
sbit k4=P3^0;
sbit k5=P3^1;
sbit Yellow_nb=P2^5; //南北黃燈標志
sbit Yellow_dx=P2^2; //東西黃燈標志
sbit Green_nb=P2^4;
sbit Green_dx=P2^1;
sbit Buzz=P3^7;
bit Buzzer_Indicate;
bit time=0;//燈狀態循環標志
bit set=1;//調時方向切換鍵標志
uchar code table[11]={ //共陰極字型碼
0x3f, //--0
0x06, //--1
0x5b, //--2
0x4f, //--3
0x66, //--4
0x6d, //--5
0x7d, //--6
0x07, //--7
0x7f, //--8
0x6f, //--9
0x00 //--NULL
};
//函數的聲明部分
void delay(int ms);//延時子程序
void key();//按鍵掃描子程序
void key_to1();//鍵處理子程序
void key_to2();
void key_to3();
void display();//顯示子程序
void logo(); //開機LOGO
void Buzzer();
//主程序
void main()
{
TMOD=0X01;
TH0=0XD8;
TL0=0XF0;
EA=1;
ET0=1;
TR0=1;
EX0=1;
EX1=1;
logo();
P2=0Xc3;// 開始默認狀態,東西綠燈,南北黃燈
sec_nb=sec_dx+5;
while(1)
{
key(); //調用按鍵掃描程序
display(); //調用顯示程序
Buzzer();
}
}
//函數的定義部分
void key() //按鍵掃描子程序
{
if(k1!=1)
{
delay(10);
if(k1!=1)
{
while(k1!=1)
{
key_to1();
for(n=0;n<40;n++)
{ display();}
}
}
}
if(k2!=1)
{
delay(10);
if(k2!=1)
{
while(k2!=1)
{
key_to2();
for(n=0;n<40;n++)
{ display();}
}
}
}
if(k3!=1)
{
TR0=1; //啟動定時器
Buzzer_Indicate=0;
sec_nb=set_timenb; //從中斷回復,仍顯示設置過的數值
sec_dx=set_timedx;
if(time==0)
{ P2=0X99;sec_nb=sec_dx+5; }
else { P2=0xC3;sec_dx=sec_nb+5; }
}
if(k4!=1)
{
delay(5);
if(k4!=1)
{
while(k4!=1);
set=!set;
}
}
if(k5!=1)
{
delay(5);
if(k5!=1)
{
while(k5!=1)
key_to3();
}
}
}
void display() //顯示子程序
{
buf[1]=sec_dx/10; //第1位 東西秒十位
buf[2]=sec_dx%10; //第2位 東西秒個位
buf[3]=sec_nb/10; //第3位 南北秒十位
buf[0]=sec_nb%10; //第4位 南北秒個位
P1=0xff; // 初始燈為滅的
P0=0x00;
P1=0xfe; //片選LCD1
P0=table[buf[1]];
delay(1);
P1=0xff;
P0=0x00;
P1=0xfd; //片選LCD2
P0=table[buf[2]];
delay(1);
P1=0xff;
P0=0x00;
P1=0Xfb; //片選LCD3
P0=table[buf[3]];
delay(1);
P1=0xff;
P0=0x00;
P1=0Xf7;
P0=table[buf[0]]; //片選LCD4
delay(1);
}
void time0(void) interrupt 1 using 1 //定時中斷子程序
{
b++;
if(b==19) // 定時器中斷次數
{ b=0;
sec_dx--;
sec_nb--;
if(sec_nb<=5&&time==0) //東西黃燈閃
{ Green_dx=0;Yellow_dx=!Yellow_dx;}
if(sec_dx<=5&&time==1) //南北黃燈閃
{ Green_nb=0;Yellow_nb=!Yellow_nb;}
if(sec_dx==0&&sec_nb==5)
sec_dx=5;
if(sec_nb==0&&sec_dx==5)
sec_nb=5;
if(time==0&&sec_nb==0)
{ P2=0x99;time=!time;sec_nb=set_timenb;sec_dx=set_timenb+5;}
if(time==1&&sec_dx==0)
{P2=0Xc3;time=!time;sec_dx=set_timedx;sec_nb=set_timedx+5;}
}
}
void key_to1() //鍵盤處理子程序之+
{
TR0=0; //關定時器
if(set==0)
set_timenb++; //南北加1S
else
set_timedx++; //東西加1S
if(set_timenb==100)
set_timenb=1;
if( set_timedx==100)
set_timedx=1; //加到100置1
sec_nb=set_timenb ; //設置的數值賦給東西南北
sec_dx=set_timedx;
}
void key_to2() //鍵盤處理子程序之-
{
TR0=0; //關定時器
if(set==0)
set_timenb--; //南北減1S
else
set_timedx--; //東西減1S
if(set_timenb==0)
set_timenb=99;
if( set_timedx==0 )
set_timedx=99; //減到1重置99
sec_nb=set_timenb ; //設置的數值賦給東西南北
sec_dx=set_timedx;
}
void key_to3() //鍵盤處理之緊急車通行
{
TR0=0;
P2=0Xc9;
sec_dx=00;
sec_nb=00;
Buzzer_Indicate=1;
}
void int0(void) interrupt 0 using 1 //只允許東西通行
{
TR0=0;
P2=0Xc3;
Buzzer_Indicate=0;
sec_dx=00;
sec_nb=00;
}
void int1(void) interrupt 2 using 1 //只允許南北通行
{
TR0=0;
P2=0X99;
Buzzer_Indicate=0;
sec_nb=00;
sec_dx=00;
}
void logo()//開機的Logo "- - - -"
{ for(n=0;n<50;n++)
{
P0=0x40;
P1=0xfe;
delay(1);
P1=0xfd;
delay(1);
P1=0Xfb;
delay(1);
P1=0Xf7;
delay(1);
P1 = 0xff;
}
}
void Buzzer()
{
if(Buzzer_Indicate==1)
Buzz=!Buzz;
else Buzz=0;
}
void delay(int ms) //延時子程序
{
uint j,k;
for(j=0;j<ms;j++)
for(k=0;k<124;k++);
}
㈧ at89c51單片機 如何用c語言編程啊
隨著單片機硬體性能的提高,編寫應用程序更著重於程序本身的效率。
Franklin或KEII.C51交叉編譯器是專為51系列單片機設計的一種高效的C語言編譯器,用其開發的應用程序易於維護,可移植性好,是目前較流行的51系列單片機的開發工具。
一、C51語言程序設計的基本技巧
首先,C51語言程序設計要盡可能採用結構化的設計方法。可將整個程序按功能分成若干個模塊,不同的模塊完成不同的功能。對於不同的功能模塊,分別指定相應的入口參數和出口參數,而經常使用的一些程序最好編成函數,這樣既不會引起整個程序管理的混亂,還可使程序的可讀性、移植性增強。
C51語言的主程序結構:
#include
main0{while(1);}
這是最小的C程序,包括頭部文件和程序主體。頭部文件為引用的外部資源文件,包括硬體信息和外部模塊提供的可使用的函數和變數的說明。
語句定義後,就可以在C語言程序中像匯編一樣使用這些硬體設備。
在C5l中常用項目來管理,項目一般分為C文件塊和頭部文件塊,常把不同的功能寫在不同的C文件中,依靠項目的管理,最後把所有文件連接起來,這樣就可以得到燒錄的HEX文件或BIN文件。沒有在頭部文件中列出的文件,可以算是該C文件的內部函數和變數,外部C不能使用。另外,在程序設計過程中要充分利用C51語言的預處理命令。
對於一些常用的常數,如TRUE、FAlSE、PI,以及各種特殊功能寄存器,或程序中一些重要的依據外界條件可變的常量,可採用宏定義(#de-fine)或集中起來放在一個頭文件中進行定義,再採用文件包含命令(#in-elude)將其加入到程序中,這樣當需要修改某個參量時,只需修改相應的包含文件或宏定義,而不必對使用它們的每個程序文件都進行修改,有利於文件的維護和更新。
舉例:利用宏定義和條件編譯,源程序不作任何修改就可適用於不同時鍾頻率的單片機系統,並可根據情況的不同取不同的delay值,完成不同的目的。程序如下:
#define flag 1#ifdef flag==l#define fose 6Mdelay=10;#elif flag==0#define fose 8Mdelay=12;#else#define fosc 12Mdelay=20;#endiFMain0{ for(I=O;l
㈨ 51單片機擴展外部數據存儲器6264,怎麼用C語言實現對其操作
2.擴展RAM編程基礎
(1)弄清擴展器件的地址
在圖7.2.5中,U3的ABC接單片機A13,A14,A15,所以片選信號對應地址最高位,即:「CBAxxxxx xxxxxxxx」(x為任意)。U4片選接CS1,即Y1,CBA=001,可得U4的地址范圍是0x2000~0x3fff。U5接CS3,即Y3,CBA=011,地址為0x6000~0x7fff。U6接CS4,即Y4,CBA=100,地址為0x8000~0x9fff。知道了器件地址,可以利用直接地址、外部數據指針來訪問存儲器。通過設置,也可以讓編譯器在擴展RAM中自動分配存儲單元。
(2)直接地址訪問
①向U4寫數據:
XBYTE[0x2000+addr]=dat; //addr為U4內部地址,取值為0~0x1fff;dat為數據。
②讀出U4數據:
dat=XBYTE[0x2000+addr];
也可以用頁訪問方式。頁訪問方式,實際就是先把16位地址高8位送P2口,通過低8位地址讀寫。
③按頁讀寫U4:
P2=0x20+page; // page為頁,取值為0x00~0x1F。
PBYTE[addr]=dat; // addr為頁內地址,取值為0x00~0xFF。
dat=PBYTE[addr];
④讀U6
dat=XBYTE[0x8000];//讀U6,地址取0x8000~0x9fff任何值,都一樣。
⑤寫U5
XBYTE[0x6000]=dat; //寫U5,地址取0x6000~0x7fff任何值,都一樣。
(3)數據指針
如,讀寫U4,可以這樣寫:
unsigned char xdata *p=0x3000; //聲明指針p,並初始指向0x3000單元
x=*p; //讀指針所指向的位置
p=p+1; //指針指向下一單元
*p=0x16; //向指針所指向的位置寫入數據
(4)讓編譯器自動分配存儲空間
①為了能讓編譯器自動分配存儲空間,並使用擴展RAM,必須設置擴展RAM地址。在Keil編程軟體中,點擊工具欄快捷圖標「 」,彈出目標選項對話框。按圖7.2.6所示,設置RAM起始地址和長度。
②變數聲明時使用xdata關鍵詞。如:
unsigned char xdata a;//變數a使用擴展RAM空間。
特別注意,擴展RAM直接地址訪問方式與自動分配存儲空間方式最好不要混用,否則可能產生沖突。
摘自《單片機控制裝置安裝與調試》下冊,雷林均主編