这也是由于 身边的人 的相关需求
了解一下 单片机的相关的东西
呵呵 当然 这里仅仅是一些 简单的测试用例
仅仅是为了学习之用, 当然 还可以 做一些 其他的东西
我这里的是 做一个 花里胡哨 的 生日快乐
整体程序的结构如下, Test01LedPrint 是主控制程序, utils 是公共的东西
birthdayLed 是 led 点阵输出祝福的图案处理
lightToggleLed 是控制 led 灯泡的闪烁的相关处理
lightTube 是控制输出 数码管 的相关信息
birthdaySong 是输出 基于蜂鸣管 生日快乐, 但是 消耗有点大, 不能组合 其他三个使用
c="https://img-blog.csdnimg.cn/7463bcfe2d5f473ca0e121de9de75b8f.png" width="196" />
主要是 组装 各个业务程序
<code> #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++;} }code>
utils.h
<code>#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 code>
utils.c
<code>#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); }code>
birthdayLed.h
<code>#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 code>
birthdayLed.c
就是 依次输出 各个图案
<code>#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);} }code>
实际效果如下图
c="https://img-blog.csdnimg.cn/795c7c3208bd43e0aecda0fab8fddc2d.jpeg" width="1200" />
lightToggleLed.h
<code>#ifndef _light_toggle_led_H #define _light_toggle_led_H#include "utils.h"/*** do biz for lightToggleLed*/ void lightToggleLed(int);#endif code>
lightToggleLed.c
主要是 编排一个周期, 然后 控制这个周期内的 led 的状态 切换
<code>#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);}}} }code>
实际效果如下
c="https://img-blog.csdnimg.cn/08a883baa27a4c16bbfe426dbbbcc5b8.png" width="905" />
c="https://img-blog.csdnimg.cn/d57bb4ba761b4426a78ce132e56a787c.png" width="904" />
lightTube.h
<code>#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 code>
lightTube.c
这个就是 控制数码管的数字的展示了
索引 相关控制 和 led的控制 重合了
<code>#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; } }code>
实际效果如下图
c="https://img-blog.csdnimg.cn/395b8bfe4ff4498891fd09770f74ea4d.png" width="904" />
birthdaySon.h
<code>#ifndef _birthday_song_H #define _birthday_song_H#include <utils.h>sbit BEEP = P2^5;void playMusic(int);#endifcode>
birthdaySon.c
<code>#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++);}}code>
这个无法展示, 可以自己听
c="https://img-blog.csdnimg.cn/a27ceb77d526414e9c54b1af3bbe5b52.png" width="905" />
完