|
自從上次發(fā)了帖子: [C51]低成本制作32個LED的搖搖棒,用stc15w104可能么?是不是采用tm1628比74hc595要更好? 之后,一直琢磨著本著自己的狗糧自己吃的原則,自己提出的問題就自己DIY一把,
為了簡化制作,就偷懶沒有采用32 LED的方案,轉(zhuǎn)而采用了簡化版的16 LED的方案(采用天微的TM1617數(shù)碼管驅(qū)動芯片 【 支持3位7段或者2位8段共陰數(shù)碼管顯示,同時還支持6個獨立按鍵的掃描, 淘寶上幾毛錢一片】),
實踐證明,我當時寫帖子時,壇友傻羊羊和devcang 提的意見非常有先見之明,TM1617這類數(shù)碼管驅(qū)動芯片的刷新率是不夠高的,所以導(dǎo)致制作出來的搖搖棒無法一次同時顯示多個字符,只能逐個字符地顯示,
因此稱這次的搖搖棒制作是不夠成功的(TM1617的說明書里寫的是顯示的周期在4ms到20ms之間,本以為是夠的,但實踐證明顯示的刷新不夠高,對于數(shù)碼管也許是足夠了,但對于搖搖棒多列顯示還是遠遠不夠),
但從積極地一面來看,本次制作歷盡艱辛,但鍛煉了自己狗屎的焊接技術(shù),同時也加強了自己對數(shù)碼管驅(qū)動編程的學(xué)習(xí)(感謝張工的無私指導(dǎo),沒有他,我?guī)缀跻恢睉岩勺约旱碾娐肥欠窈附佑袉栴})
這次的搖搖棒采用了16個藍色高亮LED,因此開始打算采用一節(jié)5號電池的計劃破產(chǎn)了(空載時有5.02V,但一帶負載就不行了,降到了3.2V,無奈只好追加了一節(jié)5號電池,采用淘寶上1.4元的升壓模塊0.9V~5V升5V,
我拆掉了模塊原本自帶的USB母座,這樣才好放置到洞洞板上焊接),TM1617芯片是SOP16的貼片封裝,無法焊接到洞洞板上,因此用了一片PCB轉(zhuǎn)接板加排針。切割洞洞板雖說用上了鋒利的勾刀,但依然累得我半死。
板子之間的拼接用了M3的螺釘和螺栓,鉆孔也是非常累人的活,尤其對一個初玩單片機的新手來說。
原本打算采用水銀開關(guān)作為運動方向檢測的傳感器,但考慮到水銀開關(guān)容易氧化,而且有玻璃打破,水銀泄露的風(fēng)險,考慮家中小兒的安全,換成了滾珠震動開關(guān)(代碼中也付出了代價,要增加開關(guān)消抖部分)。
下面照例先上電路圖吧:
呼應(yīng)一下我之前的帖子,也算是一個交代:
那就是,真正從低成本的角度來說,想用8腳的STC單片機配合數(shù)碼管驅(qū)動芯片并不合適,似乎配合74HC595更恰當(淘寶上才兩毛多一片, 16 LED就用兩片),要想編程簡單些,干脆使用二手的STC89C52RC(40個管腳)更省事,
淘寶上的價格也就比STC15W104貴幾毛,還省得用外圍擴展電路,一片搞定。
接下來應(yīng)該是代碼:(雖說從搖搖棒的角度來說是不成功的,但代碼對如何驅(qū)動TM1617這個3位7段或者2位8段的數(shù)碼管的芯片編程還是有點幫助的,正所謂有心栽花,無心插柳)
- /*
- *版權(quán)信息: sadate
- *文件名: 搖搖棒
- *當前版本: 1.0
- *單片機型號: STC15W104
- *開發(fā)環(huán)境: Keil uVision4
- *晶震頻率: 11.0592M
- *完成日期: 2016-09-08
- 功能: 驅(qū)動兩路共陰8 LED組(8 * 2 = 16LED)做搖搖棒的點陣列顯示,可由按鍵控制相關(guān)功能
- */
- #include
- #include
- #define NOP _nop_();_nop_();_nop_();_nop_();_nop_();_nop_()
- #define uchar unsigned char
- #define uint unsigned int
- #define ulint unsigned long int
- sbit direct = P3^2; //定義水銀方向開關(guān)
- sbit dio = P3^3; //定義數(shù)據(jù)輸入/輸出通訊口
- sbit clk = P3^4; //定義時鐘通訊口
- sbit stb = P3^5; //定義片選通訊口
- uchar ledlight = 0x00; //全局LED亮度定義,初始化為最低亮度
- bdata uchar showmode = 0x08; //全局顯示模式定義,默認開機以最低亮度顯示
- uchar showflag = 1; //全局圖像是否顯示的標識,初始化為顯示
- uchar word_index = 0;
- uchar cyc_count = 0;
- bdata uchar keybuf[5] = { 0 }; //鍵盤緩沖區(qū)
- sbit Key1 = keybuf[2]^0; //Key1 減弱LED亮度
- sbit Key2 = keybuf[2]^3; //Key2 增強LED亮度
- sbit Key3 = keybuf[3]^0; //Key3 選擇前一幅文本
- sbit Key4 = keybuf[3]^3; //Key4 選擇后一幅文本
- sbit Key5 = keybuf[4]^0; //Key5 圖像顯示乒乓開關(guān)
- sbit Key6 = keybuf[4]^3; //Key6
- uchar contentid = 0; //顯示內(nèi)容索引ID
- ulint TimeCount =0;
- uint DelayN =0; //延時臨時計數(shù)
- uint DelayTime =0; //每次延時的周期個數(shù)
- uchar code TEXT1[]={ // (16 X 16 , 新宋體 )
- 0x00,0x00,0x00,0x00,0x0F,0xF0,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xFF,0xFF,
- 0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x0F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,/*"中",0*/
- 0x04,0x20,0x08,0x20,0x10,0x20,0x3F,0xA0,0xC0,0x20,0x04,0x20,0x04,0x20,0x08,0xFF,
- 0xFE,0x20,0x11,0x20,0x11,0x20,0x21,0x20,0x41,0x20,0x07,0x20,0x00,0x20,0x00,0x00,/*"華",1*/
- 0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x30,0x00,0xC0,0x03,0x00,0xFC,0x00,
- 0x03,0x00,0x00,0xC0,0x00,0x30,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x00,/*"人",2*/
- 0x00,0x00,0x00,0x00,0x7F,0xFF,0x44,0x82,0x44,0x84,0x44,0x88,0x44,0x80,0x44,0x80,
- 0x47,0xC0,0x44,0xB0,0x44,0x88,0x44,0x84,0x7C,0x82,0x00,0x8F,0x00,0x00,0x00,0x00,/*"民",3*/
- 0x00,0x00,0x00,0x20,0x08,0x21,0x08,0x22,0x08,0x24,0xFF,0xE8,0x08,0x20,0x08,0x20,
- 0x08,0x20,0x08,0x20,0xFF,0xE8,0x08,0x24,0x08,0x22,0x08,0x21,0x00,0x20,0x00,0x00,/*"共",4*/
- 0x04,0x08,0x24,0x10,0x24,0x60,0x25,0x80,0x7F,0xFF,0xC4,0x80,0x44,0x60,0x04,0x00,
- 0x00,0x00,0x1F,0xFC,0x10,0x08,0x10,0x08,0x10,0x08,0x1F,0xFC,0x00,0x00,0x00,0x00,/*"和",5*/
- 0x00,0x00,0x7F,0xFF,0x40,0x02,0x48,0x12,0x49,0x12,0x49,0x12,0x49,0x12,0x4F,0xF2,
- 0x49,0x12,0x49,0x52,0x49,0x32,0x48,0x12,0x40,0x02,0x7F,0xFF,0x00,0x00,0x00,0x00,/*"國",6*/
- };
- uchar code TEXT2[]={ // (16 X 16 , 新宋體 )
- 0x20,0x00,0x27,0xFF,0x24,0x00,0x24,0x10,0x26,0x90,0x25,0x90,0x24,0x90,0xFC,0xFE,
- 0x24,0x90,0x25,0x90,0x26,0x90,0x24,0x12,0x24,0x01,0x27,0xFE,0x20,0x00,0x00,0x00,/*"南",0*/
- 0x20,0x00,0x20,0x02,0x20,0x04,0x27,0xD8,0x24,0x40,0x24,0x42,0xA4,0x41,0x64,0x7E,
- 0x24,0x40,0x24,0x40,0x24,0x40,0x27,0xD0,0x20,0x08,0x20,0x06,0x20,0x00,0x00,0x00,/*"京",1*/
- };
- /*********************************
- 延時函數(shù)
- 功能: 1ms延時
- **********************************/
- void delay_ms(uchar cyc)
- {
- uchar i, j, k;
- for (k = 1; k <= cyc; k++)
- {
- _nop_();
- _nop_();
- _nop_();
- i = 11;
- j = 190;
- do
- {
- while (--j);
- } while (--i);
- }
- }
- /*********************************
- 功能: TM1617寫數(shù)據(jù)
- **********************************/
- void send_8bit(uchar dat) //發(fā)送8位數(shù)據(jù),從低位開始
- {
- uchar i;
- for (i = 0; i < 8; i++)
- {
- clk = 0;
- if (dat & 0x01)
- {
- dio = 1;
- }
- else
- {
- dio = 0;
- }
- _nop_();
- _nop_();
- _nop_();
- clk = 1;
- dat >>= 1;
- }
- clk = 0;
- dio = 0;
- }
- /******************發(fā)送控制命令***********************/
- void send_command(uchar com) //發(fā)送命令字節(jié)
- {
- stb = 1; //stb置高
- NOP;
- stb = 0; //stb置低
- send_8bit(com); //發(fā)送8bit數(shù)據(jù)
- }
- /*********************************
- TM1617控制指令
- 功能: 驅(qū)動LED顯示一列16個點)
- **********************************/
- void dispcol(uchar highcol, uchar lowcol)
- {
- send_command(0x00); //顯示模式設(shè)置,設(shè)置為8段2位的顯示模式(8 x 2 = 16LED)
- send_command(0x40); //寫數(shù)據(jù)到顯示寄存器,采用地址自動加一
- send_command(0xc0); //顯示寄存器的00H單元開始
- //給顯示寄存器送數(shù)據(jù)(一列16bit,拆分為4個字節(jié)發(fā)送)
- send_8bit((lowcol & 0xf0)); //地址0xC0
- send_8bit((lowcol & 0x0f)); //地址0xC1
- send_8bit((highcol & 0xf0)); //地址0xC2
- send_8bit((highcol & 0x0f)); //地址0xC3
- send_command((0x80 | showmode)); //顯示控制參數(shù),開關(guān)顯示用位4,亮度可以通過改變位3~0
- stb = 1;
- }
- void showtext(uchar code *text, uchar len)//顯示text中的所有字符
- {
- uchar i;
- uint offset;
- offset = word_index * 32;
- if (offset >= len)
- {
- word_index = 0;
- offset = 0;
- }
- DelayN = DelayTime / (100 * 40);
- for (i = offset; i < offset + 32; i += 2)
- {
- dispcol(text[ i], text[i + 1]);
- delay_ms(DelayN); //列顯示之間的延時,可控制字符顯示寬度
- }
- if (cyc_count < 3)
- {
- cyc_count++;
- }
- else
- {
- cyc_count = 0;
- word_index++;
- }
- }
- void display(unsigned char index) //根據(jù)ID選擇要顯示的文本內(nèi)容
- {
- switch (index)
- {
- case 0:
- {
- showtext(TEXT1, sizeof(TEXT1));
- }
- break;
- case 1:
- {
- showtext(TEXT2, sizeof(TEXT2));
- }
- break;
- //default:
- //{
- // display_word(TEXT1);
- //}
- }
- }
- /*********************************
- 功能:讀取TM1617按鍵數(shù)據(jù)到鍵盤緩沖區(qū)
- **********************************/
- void readkey()
- {
- uchar i, j;
- send_command(0x42); //送讀按鍵命令(42H)
- dio = 1;
- for (i = 0; i < 5; i++)
- { //讀TM1617的5BYTE按鍵數(shù)據(jù)到鍵盤緩沖區(qū)
- for (j = 0; j < 8; j++)
- {
- clk = 0;
- keybuf[ i] = keybuf[ i] >> 1;
- clk = 1;
- if (dio == 1)
- {
- keybuf[ i] = keybuf[ i] | 0x80;
- }
- NOP;
- }
- NOP;
- NOP;
- }
- clk = 0;
- dio = 0;
- stb = 1;
- }
- void exint0() interrupt 0 //INT0中斷入口
- {
- EX0 = 0;
- if (direct == 1) //INT0口的狀態(tài), INT0=0(下降沿); INT0=1(上升沿)
- {
- if (showflag == 1)
- {
- delay_ms(15);
- if (direct == 1)
- {
- delay_ms(20);
- DelayTime=TimeCount;
- TimeCount=0; //延時周期計數(shù)清零
- display(contentid); //根據(jù)contentid給顯示寄存器送相應(yīng)的顯示數(shù)據(jù)
- }
- }
- }
- else
- {
- dispcol(0x00, 0x00); //反向揮動時消影,立即關(guān)閉顯示
- }
- EX0 = 1;
- }
- void timer0() interrupt 1 //定時器0中斷子程序
- {
- TimeCount++;
- }
- /*********************************
- 主函數(shù)
- **********************************/
- void main()
- {
- dispcol(0x00, 0x00); //初始化顯示寄存器
- direct = 1;
- IT0 = 0; //設(shè)置INT0的中斷類型 (1:僅下降沿 0:上升沿和下降沿)
- EX0 = 1; //使能INT0中斷
- IP = 0x02; //設(shè)置中斷優(yōu)先級
- AUXR |= 0x80; //定時器時鐘1T模式
- TMOD = 0x02; //定時器0方式2,8位重裝載
- TH0 = 0x80; //設(shè)定定時器初值
- TL0 = 0x80;
- EA = 1; //開放中斷
- ET0 = 1; //開放定時器1中斷
- TF0 = 0;
- TR0 = 1; //啟動定時器0,開始計時*/
- while(1) //循環(huán)
- {
- readkey(); //讀鍵盤
- if ((Key1 == 1) && (ledlight < 7))
- {
- ledlight++; //按Key1表示升高LED亮度
- showmode = (showmode & 0xf8) | ledlight;
- }
- if ((Key2 == 1) && (ledlight > 0))
- {
- ledlight--; //按Key2表示降低LED亮度
- showmode = (showmode & 0xf8) | ledlight;
- }
- if (Key3 == 1) //按Key3表示顯示前一幅文本
- {
- if (contentid > 0)
- {
- contentid--;
- }
- else
- {
- contentid = 1;
- }
- }
- if (Key4 == 1) //按Key4表示顯示后一幅文本
- {
- if (contentid < 1)
- {
- contentid++;
- }
- else
- {
- contentid = 0;
- }
- }
- if (Key5 == 1) //Key5是控制文本是否顯示的乒乓開關(guān)
- {
- if (showflag == 1)
- {
- showflag = 0;
- showmode = ledlight & 0x07; //立即關(guān)閉顯示
- dispcol(0x00, 0x00);
- }
- else
- {
- showflag = 1;
- showmode = ledlight | 0x08; //打開顯示
- }
- }
- }
- }
復(fù)制代碼
|
-
-
TM1617_ V1.2.pdf
2016-10-19 17:37 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
639.9 KB, 下載次數(shù): 6, 下載積分: 黑幣 -5
|