題目
流程圖
文章來源:http://www.zghlxwxcb.cn/news/detail-407667.html
關(guān)鍵點復(fù)盤
- 設(shè)備檢測——移位
L1~L8在板子上是從左至右,但是在對P0口賦值時是16進制從高位(L8)—>低位(L0)
根據(jù)原理圖,LED賦值0亮1滅
為了方便賦值,可以把板子轉(zhuǎn)一下,讓LED排序與賦值順序相同
左移<< 右移>>控制移位補0
,使LED依次點亮、依次熄滅
unsigned char i 作為下文表格中的循環(huán)變量
賦值 L8 L7 L6 L5 L4 L3 L2 L1 備注 0xff 1 1 1 1 1 1 1 1 全滅 0xff << i for(i = 1;i <= 8;i++)
左移補0~ (0xff) 0 0 0 0 0 0 0 0 全亮 ~ (0xff) << i for(i = 1;i <= 8;i++)
左移補1
- 運行時間的邏輯處理——if語句
- if語句嵌套:秒——>分——>時
- 定義unsigned chat count = 0; 將50ms作為計數(shù)初值,20次為1s
- 判斷 秒、分 是否到60,而不是59
- 按鍵控制LED時不影響數(shù)碼管運行——按鍵消抖 檢測松手(現(xiàn)場保護)
if(S5 == 0) //發(fā)現(xiàn)按鍵S5信號 { SMG_Display(); //刷新數(shù)碼管 作為 去抖動處理 if(S5 == 0) //確認按鍵S5信號 { while(S5 == 0) //等待按鍵S5松開 { SMG_Display(); //刷新數(shù)碼管使其不受按鍵影響 } XXXXXXXXXXX其他操作XXXXXXXXXXXX; } }
- 串口遠程控制——switch-case-break語句
根據(jù)同信規(guī)約:高位
——命令類型
A 或 B低位
——執(zhí)行函數(shù)
LED顯示 或 讀取時間if(command != 0x00) //接收到一個上位機命令 { switch(command & 0xf0) //將命令類型(高4位)取出 { case 0xa0: XXXXXXXXX其他操作XXXXXXXXXX; break; command = 0x00; //command清零,防止重復(fù)執(zhí)行 case 0xb0: XXXXXXXXX其他操作XXXXXXXXXX; break; command = 0x00; } }
- LED控制語句解析——與、或
- 與或關(guān)系
0 | any = any 用作取數(shù)
1 | any = 1 用作置1
0 & any = 0 用作置0
1 & any = any 用作取數(shù)
為了使“本地控制”(高位)與“遠程控制”(低位)互不干擾,引入狀態(tài)變量stat_led = 0xff
- 本地控制
- S5控制L7(判斷S5按下后)
Select_HC573(4);
stat_led = (stat_led | 0x40) & (~stat_led | 0xbf);
P0 = stat_led;![]()
- 遠程控制(判斷為case 0xa0以后)
Select_HC573(4);
stat_led = (stat_led | 0x0f) & (~command | 0xf0);
P0 = stat_led;![]()
- 讀取時間——發(fā)送數(shù)據(jù)HEX16進制的BCD碼格式(0xMM)
(hour / 10) << 4 | (hour % 10)
(min / 10) << 4 | (min % 10)
(sec / 10) << 4 | (sec % 10)
原數(shù)取整放高位(左移4位
),原數(shù)取余放低位
- 注釋規(guī)范性
- 標明定義變量
- 定義輔助寄存器(使用串口時)
- 定義獨立按鍵管腳(使用獨立按鍵時)
- 定義狀態(tài)機(LED狀態(tài)變量)
- 定義數(shù)碼管段碼表(有無小數(shù)點)
- 表明定義函數(shù)
/* ==================== XXX函數(shù) =======================
功能:XXX
參數(shù):XXX
返回:XXX
設(shè)計:XXX(20XX年XX月XX日)
======================================================= */
參考代碼(IO模式)
J13接2~3
J5接2~3文章來源地址http://www.zghlxwxcb.cn/news/detail-407667.html
#include "reg52.h"
sfr AUXR = 0x8e; //定義輔助寄存器
sbit S5 = P3^2; //定義按鍵S5引腳
sbit S4 = P3^3; //定義按鍵S4引腳
unsigned char count = 0; //定義50ms定時中斷累計變量
unsigned char sec = 0; //定義運行時間的“秒”變量
unsigned char min = 0; //定義運行時間的“分”變量
unsigned char hour = 0; //定義運行時間的“時”變量
unsigned char command = 0x00; //定義串口命令字接受變量
unsigned char stat_led = 0xff; //定義LED燈當前開關(guān)狀態(tài)
//-----共陽數(shù)碼管的段碼編碼表(無小數(shù)點)-----
code unsigned char SMG_NoDot[10] = {0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90};
/*====================鎖存器選擇函數(shù)=======================
功能:選擇要打通的鎖存器
參數(shù):channel 輸出通道
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
=======================================================*/
void Select_HC573(unsigned char channel)
{
switch(channel)
{
case 4: P2 = P2 & 0x1f | 0x80; break; //Y4輸出0,選擇LED控制
case 5: P2 = P2 & 0x1f | 0xa0; break; //Y5輸出0,選擇蜂鳴器和繼電器控制
case 6: P2 = P2 & 0x1f | 0xc0; break; //Y6輸出0,選擇數(shù)碼管位選
case 7: P2 = P2 & 0x1f | 0xe0; break; //Y7輸出0,選擇數(shù)碼管段碼
case 0: P2 = P2 & 0x1f | 0x00; break; //所有鎖存器不選擇
}
}
/*=================數(shù)碼管專用延時函數(shù)==================
功能:數(shù)碼管動態(tài)顯示專用延時函數(shù)
參數(shù):t 延時長度
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
=====================================================*/
void SMG_Delay(unsigned char t)
{
while(t--);
}
/*===============單個數(shù)碼管顯示函數(shù)===================
功能:在指定的數(shù)碼管位置上顯示指定的內(nèi)容
參數(shù):pos——位選,即要點亮的數(shù)碼管的顯示位置
dat——段選,即要點亮的數(shù)碼管的顯示內(nèi)容
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
=====================================================*/
void SMG_Bit(unsigned char pos,unsigned char dat)
{
Select_HC573(7); //消影
P0 = 0xff;
Select_HC573(6); //位選(低位—>高位 即 數(shù)碼管左—>數(shù)碼管右)
P0 = 0x01 << pos;
Select_HC573(7); //段選(內(nèi)容由“定義的數(shù)碼管段碼數(shù)組內(nèi)容”決定)
P0 = dat;
}
/*================全部數(shù)碼管顯示函數(shù)===================
功能:控制所有數(shù)碼管顯示相同內(nèi)容,放在數(shù)碼管顯示函數(shù)后用于消影
參數(shù): dat 段選,數(shù)碼管顯示內(nèi)容
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
====================================================*/
void SMG_All(unsigned char dat)
{
Select_HC573(6); //位選全部
P0 = 0xff;
Select_HC573(7); //段選
P0 = dat;
}
/*=================普通延時函數(shù)=======================
功能:逐個檢測LED與數(shù)碼管的工作狀態(tài)
參數(shù):t 延時長度
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
=====================================================*/
void Delay(unsigned int t)
{
while(t--);
while(t--);
}
/*=================設(shè)備檢測函數(shù)=====================
功能:逐個檢測LED與數(shù)碼管的工作狀態(tài)
參數(shù):無
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
=====================================================*/
void Device_Detect()
{
unsigned char i; //循環(huán)變量
Select_HC573(4);
for(i = 1;i <= 8;i++)
{
P0 = 0xff << i; //逐個點亮LED
Delay(60000);
}
for(i = 1;i <= 8;i++)
{
P0 = ~(0xff << i); //逐個熄滅LED
Delay(60000);
}
Select_HC573(0); //關(guān)閉所有鎖存器
Select_HC573(7); //數(shù)碼管a~dp所有段點亮
P0 = 0x00;
for(i = 0;i <= 7;i++)
{
Select_HC573(6);
P0 = ~(0xfe << i); //逐個點亮數(shù)碼管
Delay(60000);
}
for(i = 0;i <= 7;i++)
{
Select_HC573(6);
P0 = (0xfe << i); //逐個熄滅數(shù)碼管
Delay(60000);
}
Select_HC573(0); //關(guān)閉所有鎖存器
}
/*=================定時器T0初始化函數(shù)===================
功能:將定時器T0設(shè)置為16位自動重裝模式(模式00),計數(shù)初值為50ms
參數(shù):無
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
=====================================================*/
void Init_Time0()
{
TMOD = 0x20; //注意?。。0與T1的工作模式必須一起賦值
TH0 = (65535 - 50000) / 256; //計數(shù)初值為50ms
TL0 = (65535 - 50000) % 256;
ET0 = 1; //使能定時器T0
EA = 1; //使能總中斷
TR0 = 1; //啟動定時器T0
}
/*=================定時器T0中斷服務(wù)函數(shù)=================
功能:進行系統(tǒng)運行時間的邏輯處理
參數(shù):無
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
=====================================================*/
void Service_Time0() interrupt 1
{
count++;
if(count == 20)
{
count = 0;
sec++;
if(sec == 60)
{
sec = 0;
min++;
if(min == 60)
{
min = 0;
hour++;
{
if(hour == 99)
hour = 0;
}
}
}
}
}
/*=================串口初始化函數(shù)===================
功能:將串口初始化為波特率發(fā)生器(模式01),波特率為9600,允許接收
參數(shù):無
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
=====================================================*/
void Init_Uart()
{
TMOD = 0x20; //注意?。?!T0與T1的工作模式必須一起賦值
TH1 = 0xfd; //設(shè)置9600波特率的參數(shù)
TH1 = 0xfd;
SCON = 0x50; //8位UART模式,允許接收
AUXR = 0x00; //輔助寄存器設(shè)置
ES = 1; //使能串口中斷
EA = 1; //使能總中斷
TR1 = 1; //啟動定時器T1
}
/*=================串口中斷服務(wù)函數(shù)===================
功能:接收上位機的數(shù)據(jù)并保持在command變量中
參數(shù):無
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
=====================================================*/
void Service_Uart() interrupt 4
{
if(RI == 1)
{
command = SBUF; //將接收到的數(shù)據(jù)保存在command變量中
RI = 0; //將接收完成標志RI清0
}
}
/*=================串口發(fā)送單字節(jié)函數(shù)===================
功能:串口向上位機發(fā)送一個字節(jié)
參數(shù):dat 要發(fā)送的字節(jié)
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
=====================================================*/
void Sent_Byte(unsigned char dat)
{
SBUF = dat;
while(TI == 0);
TI = 0;
}
/*=================系統(tǒng)運行時間顯示函數(shù)=================
功能:在數(shù)碼管上顯示系統(tǒng)運行的時間
參數(shù):無
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
=====================================================*/
void SMG_Display()
{
SMG_Bit(0,SMG_NoDot[hour / 10]); //時十位
SMG_Delay(500);
SMG_Bit(1,SMG_NoDot[hour % 10]); //時個位
SMG_Delay(500);
SMG_Bit(2,0xbf); //分隔符
SMG_Delay(500);
SMG_Bit(3,SMG_NoDot[min / 10]); //分十位
SMG_Delay(500);
SMG_Bit(4,SMG_NoDot[min % 10]); //分個位
SMG_Delay(500);
SMG_Bit(5,0xbf); //分隔符
SMG_Delay(500);
SMG_Bit(6,SMG_NoDot[sec / 10]); //秒十位
SMG_Delay(500);
SMG_Bit(7,SMG_NoDot[sec % 10]); //分個位
SMG_Delay(500);
SMG_All(0xff);
}
/*================獨立按鍵控制本地燈光函數(shù)===============
功能:掃描S5和S4按鍵并執(zhí)行本地燈光控制
參數(shù):無
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
=====================================================*/
void Key_LED()
{
if(S5 == 0) //發(fā)現(xiàn)按鍵S5信號
{
SMG_Display(); //去抖動處理
if(S5 == 0) //確認按鍵S5信號
{
while(S5 == 0) //等待按鍵S5松開
{
SMG_Display();
}
Select_HC573(4);
stat_led = (stat_led | 0x40) & (~stat_led | 0xbf);
P0 = stat_led; //執(zhí)行現(xiàn)場燈光控制
Select_HC573(0);
}
}
if(S4 == 0) //發(fā)現(xiàn)按鍵S4信號
{
SMG_Display(); //去抖動處理
if(S4 == 0) //確認按鍵S4信號
{
while(S4 == 0) //等待按鍵S4松開
{
SMG_Display();
}
Select_HC573(4);
stat_led = (stat_led | 0x80) & (~stat_led | 0x7f);
P0 = stat_led; //執(zhí)行現(xiàn)場燈光控制
Select_HC573(0);
}
}
}
/*==================串口遠程控制LED函數(shù)=====================
功能:上位機命令解析與執(zhí)行,接收上位機數(shù)據(jù)并保存在command變量中
參數(shù):無
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
=========================================================*/
void Execute_Command()
{
if(command != 0x00) //接收到一個上位機命令
{
switch(command & 0xf0) //將命令類型(高4位)取出來
{
case 0xa0: //遠程燈光控制命令
Select_HC573(4);
stat_led = (stat_led | 0x0f) & (~command | 0xf0);
P0 = stat_led;
Select_HC573(0);
command = 0x00;
break;
case 0xb0: //讀取本地系統(tǒng)運行時間命令
Sent_Byte((hour / 10) << 4 | (hour % 10));
Sent_Byte((min / 10) << 4 | (min % 10));
Sent_Byte((sec / 10) << 4 | (sec % 10));
command = 0x00;
break;
}
}
}
/*==================系統(tǒng)初始化函數(shù)=====================
功能:將蜂鳴器與繼電器燈無關(guān)設(shè)備關(guān)閉
參數(shù):無
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
=====================================================*/
void Init_System()
{
Select_HC573(5);
P0 = 0x00;
Select_HC573(4);
P0 = 0xff;
Select_HC573(0);
}
/*=====================主函數(shù)==========================
功能:工廠燈光控制系統(tǒng)的主函數(shù)
參數(shù):無
返回:空
設(shè)計:饑餓的半導(dǎo)體(2023年1月30日)
=====================================================*/
void main()
{
Init_System();
Device_Detect();
Init_Time0();
Init_Uart();
while(1)
{
Execute_Command();
SMG_Display();
Key_LED();
}
}
到了這里,關(guān)于【藍橋杯單片機】工廠燈光控制系統(tǒng)案例解析(小蜜蜂老師基礎(chǔ)綜合實訓(xùn))的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!