記錄一下首個獨立完成的小專案(雖然沒有什么技術含量)
- 硬體方面:入門級的單片機點燈電路
- 軟體方面:主要利用了c語言的位操作
整個專案的下載鏈接放在了文章最后
一、成品展示
- 正面

- 反面

二、元器件清單
STC89C52RC(51單片機)x 1單排彎針(4Pin)x 1IC插座(40Pin)x1LEDx 33電阻(1KΩ)x 34自鎖按鍵x 1電容(33P)x 2電容(104P)x 1晶振(12MB)x 1導線
三、原理圖
- 首先是
51最小系統

- LED 的接線方式:陽極接
VCC,陰極接IO口

- LED 的布局

四、思路
LED 的陽極接正極,陰極接IO口,所以
- 將對應的IO口置為低電平即可點亮 LED
- 將對應的IO口置為高電平即可熄滅LED
只需要對一個32位無符號整數 (C51中是unsigned long) 進行操作,最后將它的值分為4組,分別賦值給P0、P1、P2、P3 IO口,
void setLed(u32 res)
{
P2 = (res & 0x000000FF) >> (0*4);
P0 = (res & 0x0000FF00) >> (2*4);
P1 = (res & 0x00FF0000) >> (4*4);
P3 = (res & 0xFF000000) >> (6*4);
}
一定要注意 LED 的連接順序
五、程式
a. 程式框架
/**
* Author:BY @ DLU Intelligent Control
* Time: 2020-12-13
* Version: 1.0
*/
#include <reg52.h>
#include <intrins.h>
#define DELAY_MS 10
typedef unsigned long u32;
void setLed(u32 res);
void delay(u32 ms);
void main()
{
u32 a = ~(0x00000001), b = 0;
u32 k = 0, i = 0;
while(1)
{
// 將特效代碼粘貼在這里
}
}
void setLed(u32 res)
{
P2 = (res & 0x000000FF) >> (0*4);
P0 = (res & 0x0000FF00) >> (2*4);
P1 = (res & 0x00FF0000) >> (4*4);
P3 = (res & 0xFF000000) >> (6*4);
}
void delay(u32 n)
{
u32 i = 0, j = 0;
for (i = 0; i < n; i++)
for (j = 0; j < 123; j++);
}
程式說明:
- 宏定義
DELAY_MS是延遲時間,單位是毫秒,可以通過它控制流水燈的頻率- 變數
i是特效的執行次數,只需改變i的值,就能改變對應特效的持續次數和時間- 變數
a是將要操作的32位整數,改變a的初值,可以實作不同的特效
b. 特效代碼

// 閃爍
i = 20;
a = 0;
for(k = 0; k < i; k++)
{
delay(DELAY_MS * 2);
a = ~a;
setLed(a);
}

// 正轉1圈
i = 32;
a = ~(0x00000001);
for(k = 0; k < i; k++)
{
delay(DELAY_MS / 2);
a = _lrol_(a, 1);
setLed(a);
}
// 反轉1圈
i = 32;
a = ~(0x80000000);
for(k = 0; k < i; k++)
{
delay(DELAY_MS / 2);
a = _lror_(a, 1);
setLed(a);
}

// 逐個點亮
i = 32;
a = ~(0x00000001);
for(k = 0; k < i; k++)
{
delay(DELAY_MS);
a = a >> 1;
setLed(a);
}
// 逐個滅掉
i = 32;
a = 0;
for(k = 0; k < i; k++)
{
delay(DELAY_MS);
a = (a + 1) << 1;
setLed(a);
}

// 只滅一個,正轉1圈
i = 32;
a = 0x00000001;
for(k = 0; k < i; k++)
{
delay(DELAY_MS / 2);
a = _lrol_(a, 1);
setLed(a);
}
// 只滅一個,反轉1圈
i = 32;
a = (0x80000000);
for(k = 0; k < i; k++)
{
delay(DELAY_MS / 2);
a = _lror_(a, 1);
setLed(a);
}

// 兩邊逐個點亮
i = 16;
a = ~(0xFFFF0001);
b = ~(0xFFFF8000);
for(k = 0; k < i; k++)
{
delay(DELAY_MS);
a = a << 1;
b = b >> 1;
setLed((a << 16) | b);
}

// 回圈閃爍(只滅8個)
i = 100;
a = (0x11111111);
for(k = 0; k < i; k++)
{
delay(DELAY_MS);
a = _lrol_(a, 1);
setLed(a);
}

// 回圈閃爍(只亮8個)
i = 100;
a = ~(0x11111111);
for(k = 0; k < i; k++)
{
delay(DELAY_MS);
a = _lrol_(a, 1);
setLed(a);
}
特效當然不只這么多,你可以自己思考一下,做出更多有意思的特效
c. 完整的程式
/**
* Author:BY @ DLU Intelligent Control
* Time: 2020-12-13
* Version: 1.0
*/
#include <reg52.h>
#include <intrins.h>
#define DELAY_MS 10
typedef unsigned long u32;
void setLed(u32 res);
void delay(u32 ms);
void main()
{
u32 a = ~(0x00000001), b = 0;
u32 k = 0, i = 320;
while(1)
{
// 正轉1圈
i = 32;
a = ~(0x00000001);
for(k = 0; k < i; k++)
{
delay(DELAY_MS / 2);
a = _lrol_(a, 1);
setLed(a);
}
// 反轉1圈
i = 32;
a = ~(0x80000000);
for(k = 0; k < i; k++)
{
delay(DELAY_MS / 2);
a = _lror_(a, 1);
setLed(a);
}
// 逐個點亮
i = 32;
a = ~(0x00000001);
for(k = 0; k < i; k++)
{
delay(DELAY_MS);
a = a >> 1;
setLed(a);
}
// 逐個滅掉
i = 32;
a = 0;
for(k = 0; k < i; k++)
{
delay(DELAY_MS);
a = (a + 1) << 1;
setLed(a);
}
// 逐個點亮
i = 32;
a = ~(0x00000001);
for(k = 0; k < i; k++)
{
delay(DELAY_MS);
a = a >> 1;
setLed(a);
}
// 閃爍幾下
i = 20;
a = 0;
for(k = 0; k < i; k++)
{
delay(DELAY_MS * 2);
a = ~a;
setLed(a);
}
// 只滅一個,正轉1圈
i = 32;
a = 0x00000001;
for(k = 0; k < i; k++)
{
delay(DELAY_MS / 2);
a = _lrol_(a, 1);
setLed(a);
}
// 只滅一個,反轉1圈
i = 32;
a = (0x80000000);
for(k = 0; k < i; k++)
{
delay(DELAY_MS / 2);
a = _lror_(a, 1);
setLed(a);
}
// 兩邊逐個點亮
i = 16;
a = ~(0xFFFF0001);
b = ~(0xFFFF8000);
for(k = 0; k < i; k++)
{
delay(DELAY_MS);
a = a << 1;
b = b >> 1;
setLed((a << 16) | b);
}
// 兩邊逐個點亮
i = 16;
a = ~(0xFFFF0001);
b = ~(0xFFFF8000);
for(k = 0; k < i; k++)
{
delay(DELAY_MS);
a = a << 1;
b = b >> 1;
setLed((a << 16) | b);
}
// 回圈閃爍(只滅8個)
i = 100;
a = (0x11111111);
for(k = 0; k < i; k++)
{
delay(DELAY_MS);
a = _lrol_(a, 1);
setLed(a);
}
// 兩邊逐個點亮
i = 16;
a = ~(0xFFFF0001);
b = ~(0xFFFF8000);
for(k = 0; k < i; k++)
{
delay(DELAY_MS);
a = a << 1;
b = b >> 1;
setLed((a << 16) | b);
}
// 兩邊逐個點亮
i = 16;
a = ~(0xFFFF0001);
b = ~(0xFFFF8000);
for(k = 0; k < i; k++)
{
delay(DELAY_MS);
a = a << 1;
b = b >> 1;
setLed((a << 16) | b);
}
// 閃幾下
i = 20;
a = 0;
for(k = 0; k < i; k++)
{
delay(DELAY_MS * 2);
a = ~a;
setLed(a);
}
// 回圈閃爍(只亮8個)
i = 100;
a = ~(0x11111111);
for(k = 0; k < i; k++)
{
delay(DELAY_MS);
a = _lrol_(a, 1);
setLed(a);
}
}
}
void setLed(u32 res)
{
P2 = (res & 0x000000FF) >> (0*4);
P0 = (res & 0x0000FF00) >> (2*4);
P1 = (res & 0x00FF0000) >> (4*4);
P3 = (res & 0xFF000000) >> (6*4);
}
void delay(u32 n)
{
u32 i = 0, j = 0;
for (i = 0; i < n; i++)
for (j = 0; j < 123; j++);
}
六、擴展
1、還可以利用PWM做出呼吸燈的效果
2、可以使用下面這種彩色的 LED ,效果會更好

七、完整專案下載
點擊下載完整專案(基于Keil)
板子焊完了
程式寫出來了
就等國家分配物件了
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/242452.html
標籤:其他
上一篇:[STM32] Stm32f103c8t6+RC522 實作讀卡寫卡功能(超詳細,零基礎,小白)
下一篇:API介面:車輛維修保養記錄查詢
