前言
这也是由于 身边的人 的相关需求
了解一下 单片机的相关的东西
呵呵 当然 这里仅仅是一些 简单的测试用例
仅仅是为了学习之用, 当然 还可以 做一些 其他的东西
我这里的是 做一个 花里胡哨 的 生日快乐
主控制程序
整体程序的结构如下, Test01LedPrint 是主控制程序, utils 是公共的东西
birthdayLed 是 led 点阵输出祝福的图案处理
lightToggleLed 是控制 led 灯泡的闪烁的相关处理
lightTube 是控制输出 数码管 的相关信息
birthdaySong 是输出 基于蜂鸣管 生日快乐, 但是 消耗有点大, 不能组合 其他三个使用
主要是 组装 各个业务程序
#include "utils.h"
#include "birthdayLed.h"
#include "lightToggleLed.h"
#include "lightTube.h"
#include "birthdaySong.h"
/**
* main related
*/
long counter = 1;
void main() {
while (1) {
// printLed(counter);
// lightToggleLed(counter);
lightTube(counter);
// playMusic(counter);
delay_ms(5);
counter++;
}
}
utils.h
#ifndef _utils_H
#define _utils_H
#include "reg52.h"
typedef unsigned int u16;
typedef unsigned char u8;
typedef unsigned long u32;
/**
* delay $delayIn10Us us
* @param ten_us
*/
void delay_10us(u16 ten_us);
/**
* delay $delayInMs ms
* @param ms
*/
void delay_ms(u16 ms);
/**
* control led[pos] on/off
* @param pos
* @param on
*/
void ledCtl(u8 pos, u8 on);
/**
* toggle led[pos] on/off
* @param pos
* @param on
*/
void ledToggle(u8 pos);
#endif
utils.c
#include "utils.h"
void delay_10us(u16 ten_us) {
while (ten_us--);
}
void delay_ms(u16 ms) {
u16 i, j;
for (i = ms; i > 0; i--)
for (j = 110; j > 0; j--);
}
void ledCtl(u8 pos, u8 on) {
if(on == 0) {
P2 |= (1 << pos);
return;
}
P2 &= (~(1 << pos));
}
void ledToggle(u8 pos) {
P2 ^= (1 << pos);
}
led 点阵的控制
birthdayLed.h
#ifndef _birthday_led_H
#define _birthday_led_H
#include "utils.h"
sbit SHIFT_REG_INPUT = P3 ^6;
sbit STORE_REG_INPUT = P3 ^5;
sbit SERIAL_PORT_INPUT = P3 ^4;
#define LEDDZ_COL_PORT P0
/**
* do biz for printLed
*/
void printLed(int);
/**
* output word 2 led
*/
void hc595_write_data(u8);
/**
* output word 2 led
*/
void printLedWord(int, u8 *);
#endif
birthdayLed.c
就是 依次输出 各个图案
#include "birthdayLed.h"
/**
* led related
*/
u8 gled_words[][8] = {
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
{0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38},
};
u8 gled_col[8] = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe};
long ledTurnNextThreshold = 30;
int ledMaxRowCount = 17;
int ledCurrentRowIdx = 0;
void printLed(int counter) {
u8 *word;
if (counter % ledTurnNextThreshold == 0) {
ledCurrentRowIdx = (ledCurrentRowIdx + 1) % ledMaxRowCount;
}
if(counter % 2 == 0) {
word = gled_words[ledCurrentRowIdx];
printLedWord(8, word);
}
}
void hc595_write_data(u8 dat) {
u8 i = 0;
for (i = 0; i < 8; i++) {
SERIAL_PORT_INPUT = dat >> 7;
dat <<= 1;
SHIFT_REG_INPUT = 0;
delay_10us(1);
SHIFT_REG_INPUT = 1;
delay_10us(1);
}
STORE_REG_INPUT = 1;
delay_10us(1);
STORE_REG_INPUT = 0;
}
void printLedWord(int wordLength, u8 *word) {
u8 i;
for (i = 0; i < wordLength; i++) {
LEDDZ_COL_PORT = gled_col[i];
hc595_write_data(word[i]);
delay_10us(10);
hc595_write_data(0x00);
}
}
实际效果如下图
led 灯的控制
lightToggleLed.h
#ifndef _light_toggle_led_H
#define _light_toggle_led_H
#include "utils.h"
/**
* do biz for lightToggleLed
*/
void lightToggleLed(int);
#endif
lightToggleLed.c
主要是 编排一个周期, 然后 控制这个周期内的 led 的状态 切换
#include "lightToggleLed.h"
long lightToggleTurnNextThreshold = 10;
int lightToggleMaxRowCount = 10;
int lightToggleCurrentRowIdx = 0;
u16 ledToggleConfigs[][10] = {
{3, 5, 8, 9},
{2, 4, 7, 8, 9},
{0},
{0},
{0},
{1, 3, 8, 9},
{4, 5, 6, 9},
{3, 6, 7 ,8, 9},
};
u16 ledToggleConfigLengths[8] = {4, 5, 0, 0, 0, 4, 4, 5};
void lightToggleLed(int counter) {
u8 ledIdx;
int i, length;
u16 *toggleConfig;
if (counter % lightToggleTurnNextThreshold == 0) {
lightToggleCurrentRowIdx = ((lightToggleCurrentRowIdx + 1) % lightToggleMaxRowCount);
}
for(ledIdx = 0; ledIdx < 8; ledIdx ++) {
if(ledIdx >= 2 && ledIdx <= 4) {
continue ;
}
toggleConfig = ledToggleConfigs[ledIdx];
length = ledToggleConfigLengths[ledIdx];
for(i=0; i<length; i++) {
if((toggleConfig[i] == lightToggleCurrentRowIdx) && (counter % lightToggleTurnNextThreshold == 1)) {
ledToggle(ledIdx);
}
}
}
}
实际效果如下
数码管的控制
lightTube.h
#ifndef _light_tube_H
#define _light_tube_H
#include "utils.h"
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
#define SMG_A_DP_PORT P0
/**
* do biz for lightTube
*/
void lightTube(int);
#endif
lightTube.c
这个就是 控制数码管的数字的展示了
索引 相关控制 和 led的控制 重合了
#include "lightTube.h"
u8 gsmg_code[17]={0x3f,0x86,0x3f,0x6d,0x23,0x08,0x08,0x23};
void lightTube(int counter) {
u8 i=0;
for(i=0;i<8;i++)
{
switch(i)//位选
{
case 0: LSC=1;LSB=1;LSA=1;break;
case 1: LSC=1;LSB=1;LSA=0;break;
case 2: LSC=1;LSB=0;LSA=1;break;
case 3: LSC=1;LSB=0;LSA=0;break;
case 4: LSC=0;LSB=1;LSA=1;break;
case 5: LSC=0;LSB=1;LSA=0;break;
case 6: LSC=0;LSB=0;LSA=1;break;
case 7: LSC=0;LSB=0;LSA=0;break;
}
SMG_A_DP_PORT=gsmg_code[i];
delay_10us(10);
SMG_A_DP_PORT=0x00;
}
}
实际效果如下图
蜂鸣管控制
birthdaySon.h
#ifndef _birthday_song_H
#define _birthday_song_H
#include <utils.h>
sbit BEEP = P2^5;
void playMusic(int);
#endif
birthdaySon.c
#include "birthdaySong.h"
u8 code SONG_TONE[]={ 212, 212, 190, 212, 159, 169, 212, 212, 190, 212, 142, 159, 212, 212, 106, 126, 159, 169, 190, 119, 119, 126, 159, 142, 159, 0 };
u8 code SONG_LONG[]={ 9, 3, 12, 12, 12, 24, 9, 3, 12, 12, 12, 24, 9, 3, 12, 12, 12, 12, 12, 9, 3, 12, 12, 12, 24, 0 };
long birthdaySongTurnNextThreshold = 1;
int birthdaySongMaxRowCount = 26;
int birthdaySongCurrentRowIdx = 0;
long birthdaySongNextAvailableCounter = -1;
long birthdaySongSleepAfterEndIn5Ms = 1000;
void playMusic(int counter) {
u16 toneNow, longNow;
u16 j, k;
if(counter < birthdaySongNextAvailableCounter) {
return ;
}
if (counter % birthdaySongTurnNextThreshold == 0) {
birthdaySongCurrentRowIdx = birthdaySongCurrentRowIdx + 1;
birthdaySongCurrentRowIdx = birthdaySongCurrentRowIdx % birthdaySongMaxRowCount;
}
toneNow = SONG_TONE[birthdaySongCurrentRowIdx];
longNow = SONG_LONG[birthdaySongCurrentRowIdx];
if(toneNow == 0) {
birthdaySongNextAvailableCounter = counter + birthdaySongSleepAfterEndIn5Ms;
BEEP = 0;
return ;
}
for (j = 0; j < longNow * 20; j++) {
BEEP = !BEEP;
for (k = 0; k < toneNow / 5; k++);
}
}
这个无法展示, 可以自己听
数码管, led灯, led点阵 大合计
完