痞子衡嵌入式半月刊: 第 88 期 這裡分享嵌入式領域有用有趣的項目/工具以及一些熱點新聞,農曆年分二十四節氣,希望在每個交節之日準時發佈一期。 本期刊是開源項目(GitHub: JayHeng/pzh-mcu-bi-weekly),歡迎提交 issue,投稿或推薦你知道的嵌入式那些事兒。 上期回顧 ...
51單片機【點陣屏】
我們有一個8*8的點陣屏,裡面是64個發光二極體。
二極體的陽極我們給它接了74HC595的八個輸出引腳,陰極接P00-P07引腳。
74HC595的八個引腳控制八個行,P00-P07控制八個列,行為1,列為0 對應的那個LED燈會亮,其他的組合不行。
如何讓74HC595的八個輸出引腳輸出不同的值,我們需要查看手冊。
查看手冊得知:這個晶元對我們有用的輸入管腳有三個,一個SCK當它下降沿時使得移位寄存器右移一位,一個RCK當它下降沿時將移位鎖存器里的值放到存儲寄存器並輸出到引腳上,一個SER將每次右移後前面缺出的位置補上它。移位前,移位寄存器每位都是0,通過SER給它加上1。
我們的板子上,P34控制SCK,P35控制RCK,P36控制SER。
我們想要在點陣屏繪製一幅圖片,我們需要定義三個函數,一個初始化,一個寫顯存(這裡的顯存是個數組,接收外部傳過來的,一個元素為一行的點亮的燈),最後一個函數是讓通過595晶元的兩個下降沿一行一行地控制,每一行有效時,把對應的顯存賦給P0,就能讓對應的亮起來。如果想使用回調函數,則每行一毫米刷新。以下是用定時器實現的代碼。
#include "Int_LedMatrix.h"
// 移位寄存器時鐘(上升沿有效,右移)
#define SCK P34
// 數據寄存器時鐘
#define RCK P35
// IO線,補的位
#define SER P36
static u8 s_buffer[8] = 0;
static u8 s_pc = 0;
void LedMatrix_Init()
{
SCK = 0;
RCK = 0;
SER = 1;
}
void LedMatrix_SetPic(u8 *pic)
{
u16 i;
for (i = 0; i < 8; i++) {
s_buffer[i] = pic[i];
}
}
void LedMatrix_Refresh()
{
s_pc = s_pc>=8 ? SER=1, 0 : s_pc;
// 列引腳
P0 = 0xff;
// 上升沿
SCK = 1;
RCK = 1;
// 列引腳
P0 = ~s_buffer[s_pc++];
// Delay1ms(1);
// 關掉補位1
SER = 0;
//
SCK = 0;
RCK = 0;
}
// 主函數
#include "Int_LedMatrix.h"
// 下麵的兩個數組可以合併為一個,就是每次+8
// 這個沒有實現什麼效果,一個亂的圖
static u8 s_pic[] = {1, 2, 4, 8, 16, 32, 64, 128};
static u8 s_pic1[] = {2, 12, 34, 58, 166, 372, 694, 1028};
void main() {
LedMatrix_Init();
// LedMatrix_SetPic(s_pic);
Dri_Timer0_Init();
Dri_Timer0_RegisterCallback(LedMatrix_Refresh);
while(1){
LedMatrix_SetPic(s_pic);
Delay1ms(500);
LedMatrix_SetPic(s_pic1);
Delay1ms(200);
}
}
如果一個數組裡每8個是一個圖,想讓它流動起來,可以定義函數,讓它從第六行圖賦給第七行,第五行圖賦給第四行...... 第0行補傳過來的值,這個傳過來的值就是數組(這個數組是main中的數組,不是顯存)的下一個元素,這樣的話,剛開始屏幕為0(顯存就為0),也可以從第一行數組的第一個往下刷,刷完一次後,可以再刷幾次空行,然後重覆(這個重覆是指主函數中的while(1)。)代碼略。