基于STC51單片機的霓虹燈
設計要求:
- 使用PWM驅動8個LED燈
- 人眼不能觀察到燈光全滅
- 燈光要有影片效果
設計概述:
???按照設計要求,為了更直觀的說明脈沖寬度調制技術(PWM),所以霓虹燈的影片效果為流水燈形式,所需要的單片機芯片為STC89C52,所用的硬體工具是由華清遠見開發的基于STC89C52的智能小車,該小車配備所需要的LED燈模塊,8個LED燈由P1口來控制,STC89C52是一種低功耗,高性能的8位微控制器,是加強版的80C51單片機,但是與80C51單片機一樣不具備PWM硬體模塊,所以我們需要自己寫一個程式來軟體模擬PWM方波,
????PWM是一種方波,可以實作數字信號控制模擬電路,它有兩個重要引數周期或頻率,占空比,占空比 = 高電平時間/周期,最小為0%,最大為100%,通過調整占空比來控制高電平,低電平所占比例,進而調控LED燈的亮滅與明暗變化,STC89C52中P1口為低電平有效,將P1口置0,LED燈亮,置1燈滅,若將P1口的電平輸出信號調整成高低電平各占50%,即在一個周期內高電平,低電平所占比例都是50%,P1口控制的LED燈將會明暗閃爍,
????市面上的許多51單片機開發板大同小異,都是用P1口控制LED燈,所以在此就不提供智能小車的原理圖和實物圖,
源代碼:
軟體模擬PWM方波通常利用定時器來實作,
參考代碼1:
#include <reg52.h>
//定義一個全域變數pwm,通過對全域變數的累加來控制PWM的占空比
unsigned int pwm = 0;
/*
利用定時器和I/O口來輸出PWM方波實作8個LED燈的明暗變化
*/
/*定時器中斷服務函式*/
void Timer0() interrupt 1
{
pwm++;
if(pwm == 500)
{
P1 = 0xfe;//第1盞燈亮
}
else if(pwm == 1000)
{
P1 = 0xff;//第1盞燈滅
}
else if(pwm == 1500)
{
P1 = 0xfd;//第2盞燈亮
}
else if(pwm == 2000)
{
P1 = 0xff;
}
else if(pwm == 2500)
{
P1 = 0xfb;//第3盞燈亮
}
else if(pwm == 3000)
{
P1 = 0xff;
}
else if(pwm == 3500)
{
P1 = 0xf7;//第4盞燈亮
}
else if(pwm == 4000)
{
P1 = 0xff;
}
else if(pwm == 4500)
{
P1 = 0xef;//第5盞燈亮
}
else if(pwm == 5000)
{
P1 = 0xff;
}
else if(pwm == 5500)
{
P1 = 0xdf;//第6盞燈亮
}
else if(pwm == 6000)
{
P1 = 0xff;
}
else if(pwm == 6500)
{
P1 = 0xbf;//第7盞燈亮
}
else if(pwm == 7000)
{
P1 = 0xff;
}
else if(pwm == 7500)
{
P1 = 0x7f;//第8盞燈亮
}
else if(pwm == 8000)
{
P1 = 0xff;
pwm = 0;
}
}
void main()
{
TMOD |= 1<<1; //通過移位運算子"<<"來改變位的狀態
TMOD &= ~(1<<0); //置定時器/計數器的作業方式為方式2
TMOD &= ~(1<<2); //選擇定時作業方式
TMOD &= ~(1<<3); //門控位:由運行控制位TR啟動定時器
TL0 = 156;
TH0 = 156; //100us進入一次中斷,0.1毫秒
ET0 = 1; //定時器0開中斷
EA = 1; //CPU開中斷
TR0 = 1; //啟動定時器0
while(1) //防止程式跑飛
;
}
參考代碼2:
/*第一個檔案為自定義頭檔案
此頭檔案里宣告pwm_led_ctl函式
*/
#ifndef _LED_H
#define _LED_H
//控制某一盞燈亮
char pwm_led_ctl(unsigned int led_num);
#endif
/*
第二個檔案
此源檔案用于實作pwm_led_ctl函式
*/
#include <reg52.h>
#include "led.h"
//軟體模擬PWM方波,通過變數pwm調控PWM占空比
char pwm_led_ctl(unsigned int led_num)
{
unsigned int pwm;
for(pwm = 0;pwm <= 2000;pwm++)
{
if(pwm == 1000)
{
P1 &= ~(1<<led_num);//通過移位運算子"<<"逐個點亮LED燈
}
else if(pwm == 2000)
{
P1 |= 1<<led_num;
}
}
return 0;
}
/*
第三個檔案
主函式源檔案
*/
#include <reg52.h>
#include "led.h"
/*定時器中斷服務函式*/
void Timer0() interrupt 1
{
unsigned int i;
for(i=0;i<8;i++)
{
pwm_led_ctl(i);
}
}
void main()
{
TMOD |= 1<<1; //通過移位運算子"<<"來改變位的狀態
TMOD &= ~(1<<0); //置定時器/計數器的作業方式為方式2
TMOD &= ~(1<<2); //選擇定時作業方式
TMOD &= ~(1<<3); //門控位:由運行控制位TR啟動定時器
TL0 = 156;
TH0 = 156; //100us進入一次中斷,0.1毫秒
ET0 = 1; //定時器0開中斷
EA = 1; //CPU開中斷
TR0 = 1; //啟動定時器0
while(1) //防止程式跑飛
;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/295889.html
標籤:Windows
