找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 11193|回復: 0
收起左側(cè)

一次不算成功的16 LED搖搖棒制作經(jīng)歷分享

[復制鏈接]
ID:134687 發(fā)表于 2016-10-19 17:38 | 顯示全部樓層 |閱讀模式
       自從上次發(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ū)動芯片的刷新率是不夠高的,所以導致制作出來的搖搖棒無法一次同時顯示多個字符,只能逐個字符地顯示,
因此稱這次的搖搖棒制作是不夠成功的(TM1617的說明書里寫的是顯示的周期在4ms到20ms之間,本以為是夠的,但實踐證明顯示的刷新不夠高,對于數(shù)碼管也許是足夠了,但對于搖搖棒多列顯示還是遠遠不夠),
但從積極地一面來看,本次制作歷盡艱辛,但鍛煉了自己狗屎的焊接技術(shù),同時也加強了自己對數(shù)碼管驅(qū)動編程的學習(感謝張工的無私指導,沒有他,我?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)容易氧化,而且有玻璃打破,水銀泄露的風險,考慮家中小兒的安全,換成了滾珠震動開關(guān)(代碼中也付出了代價,要增加開關(guān)消抖部分)。
       下面照例先上電路圖吧:
108_1540354_8cbe8609b97d6dc.png




       呼應一下我之前的帖子,也算是一個交代:
       那就是,真正從低成本的角度來說,想用8腳的STC單片機配合數(shù)碼管驅(qū)動芯片并不合適,似乎配合74HC595更恰當(淘寶上才兩毛多一片, 16 LED就用兩片),要想編程簡單些,干脆使用二手的STC89C52RC(40個管腳)更省事,
淘寶上的價格也就比STC15W104貴幾毛,還省得用外圍擴展電路,一片搞定。

        接下來應該是代碼:(雖說從搖搖棒的角度來說是不成功的,但代碼對如何驅(qū)動TM1617這個3位7段或者2位8段的數(shù)碼管的芯片編程還是有點幫助的,正所謂有心栽花,無心插柳)

  1. /*
  2. *版權(quán)信息:   sadate
  3. *文件名:      搖搖棒
  4. *當前版本:   1.0
  5. *單片機型號: STC15W104
  6. *開發(fā)環(huán)境:   Keil uVision4
  7. *晶震頻率:   11.0592M
  8. *完成日期:   2016-09-08
  9. 功能:        驅(qū)動兩路共陰8 LED組(8 * 2 = 16LED)做搖搖棒的點陣列顯示,可由按鍵控制相關(guān)功能
  10. */
  11. #include
  12. #include




  13. #define NOP    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_()
  14. #define uchar  unsigned char
  15. #define uint   unsigned int
  16. #define ulint  unsigned long int




  17. sbit  direct   = P3^2;                 //定義水銀方向開關(guān)
  18. sbit  dio      = P3^3;                 //定義數(shù)據(jù)輸入/輸出通訊口
  19. sbit  clk      = P3^4;                 //定義時鐘通訊口
  20. sbit  stb      = P3^5;                 //定義片選通訊口




  21. uchar ledlight       = 0x00;           //全局LED亮度定義,初始化為最低亮度
  22. bdata uchar showmode = 0x08;           //全局顯示模式定義,默認開機以最低亮度顯示
  23. uchar showflag       = 1;              //全局圖像是否顯示的標識,初始化為顯示                  
  24. uchar word_index     = 0;
  25. uchar cyc_count      = 0;




  26. bdata uchar keybuf[5] = { 0 };         //鍵盤緩沖區(qū)
  27. sbit  Key1     = keybuf[2]^0;          //Key1 減弱LED亮度
  28. sbit  Key2     = keybuf[2]^3;          //Key2 增強LED亮度
  29. sbit  Key3     = keybuf[3]^0;          //Key3 選擇前一幅文本
  30. sbit  Key4     = keybuf[3]^3;          //Key4 選擇后一幅文本
  31. sbit  Key5     = keybuf[4]^0;          //Key5 圖像顯示乒乓開關(guān)
  32. sbit  Key6     = keybuf[4]^3;          //Key6




  33. uchar contentid = 0;                   //顯示內(nèi)容索引ID




  34. ulint   TimeCount =0;
  35. uint     DelayN    =0;        //延時臨時計數(shù)
  36. uint    DelayTime =0;        //每次延時的周期個數(shù)




  37. uchar code TEXT1[]={                   // (16 X 16 , 新宋體 )
  38.         0x00,0x00,0x00,0x00,0x0F,0xF0,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0xFF,0xFF,
  39.         0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x0F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,/*"中",0*/

  40.         0x04,0x20,0x08,0x20,0x10,0x20,0x3F,0xA0,0xC0,0x20,0x04,0x20,0x04,0x20,0x08,0xFF,
  41.         0xFE,0x20,0x11,0x20,0x11,0x20,0x21,0x20,0x41,0x20,0x07,0x20,0x00,0x20,0x00,0x00,/*"華",1*/

  42.         0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x30,0x00,0xC0,0x03,0x00,0xFC,0x00,
  43.         0x03,0x00,0x00,0xC0,0x00,0x30,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x00,/*"人",2*/

  44.         0x00,0x00,0x00,0x00,0x7F,0xFF,0x44,0x82,0x44,0x84,0x44,0x88,0x44,0x80,0x44,0x80,
  45.         0x47,0xC0,0x44,0xB0,0x44,0x88,0x44,0x84,0x7C,0x82,0x00,0x8F,0x00,0x00,0x00,0x00,/*"民",3*/

  46.         0x00,0x00,0x00,0x20,0x08,0x21,0x08,0x22,0x08,0x24,0xFF,0xE8,0x08,0x20,0x08,0x20,
  47.         0x08,0x20,0x08,0x20,0xFF,0xE8,0x08,0x24,0x08,0x22,0x08,0x21,0x00,0x20,0x00,0x00,/*"共",4*/

  48.         0x04,0x08,0x24,0x10,0x24,0x60,0x25,0x80,0x7F,0xFF,0xC4,0x80,0x44,0x60,0x04,0x00,
  49.         0x00,0x00,0x1F,0xFC,0x10,0x08,0x10,0x08,0x10,0x08,0x1F,0xFC,0x00,0x00,0x00,0x00,/*"和",5*/

  50.         0x00,0x00,0x7F,0xFF,0x40,0x02,0x48,0x12,0x49,0x12,0x49,0x12,0x49,0x12,0x4F,0xF2,
  51.         0x49,0x12,0x49,0x52,0x49,0x32,0x48,0x12,0x40,0x02,0x7F,0xFF,0x00,0x00,0x00,0x00,/*"國",6*/
  52. };




  53. uchar code TEXT2[]={                   // (16 X 16 , 新宋體 )
  54.         0x20,0x00,0x27,0xFF,0x24,0x00,0x24,0x10,0x26,0x90,0x25,0x90,0x24,0x90,0xFC,0xFE,
  55.         0x24,0x90,0x25,0x90,0x26,0x90,0x24,0x12,0x24,0x01,0x27,0xFE,0x20,0x00,0x00,0x00,/*"南",0*/

  56.         0x20,0x00,0x20,0x02,0x20,0x04,0x27,0xD8,0x24,0x40,0x24,0x42,0xA4,0x41,0x64,0x7E,
  57.         0x24,0x40,0x24,0x40,0x24,0x40,0x27,0xD0,0x20,0x08,0x20,0x06,0x20,0x00,0x00,0x00,/*"京",1*/
  58. };




  59. /*********************************
  60.     延時函數(shù)
  61. 功能: 1ms延時
  62. **********************************/
  63. void delay_ms(uchar cyc)
  64. {
  65.     uchar i, j, k;
  66.     for (k = 1; k <= cyc; k++)
  67.     {
  68.         _nop_();
  69.         _nop_();
  70.         _nop_();
  71.         i = 11;
  72.         j = 190;
  73.         do
  74.         {
  75.             while (--j);
  76.         } while (--i);
  77.     }
  78. }




  79. /*********************************   
  80. 功能: TM1617寫數(shù)據(jù)
  81. **********************************/
  82. void send_8bit(uchar dat)              //發(fā)送8位數(shù)據(jù),從低位開始
  83. {
  84.   uchar i;




  85.   for (i = 0; i < 8; i++)
  86.   {   
  87.         clk = 0;

  88.       if (dat & 0x01)
  89.       {
  90.           dio = 1;
  91.       }
  92.       else         
  93.       {
  94.           dio = 0;
  95.       }

  96.       _nop_();
  97.       _nop_();
  98.       _nop_();
  99.       clk = 1;     
  100.       dat >>= 1;     
  101.   }

  102.   clk = 0;
  103.   dio = 0;
  104. }




  105. /******************發(fā)送控制命令***********************/
  106. void send_command(uchar com)           //發(fā)送命令字節(jié)
  107. {
  108.     stb = 1;                           //stb置高
  109.     NOP;
  110.     stb = 0;                           //stb置低
  111.     send_8bit(com);                    //發(fā)送8bit數(shù)據(jù)
  112. }




  113. /*********************************
  114.     TM1617控制指令
  115. 功能: 驅(qū)動LED顯示一列16個點)
  116. **********************************/
  117. void dispcol(uchar highcol, uchar lowcol)
  118. {   
  119.     send_command(0x00);                //顯示模式設置,設置為8段2位的顯示模式(8 x 2 = 16LED)
  120.     send_command(0x40);                //寫數(shù)據(jù)到顯示寄存器,采用地址自動加一
  121.     send_command(0xc0);                //顯示寄存器的00H單元開始

  122.                                        //給顯示寄存器送數(shù)據(jù)(一列16bit,拆分為4個字節(jié)發(fā)送)
  123.     send_8bit((lowcol  & 0xf0));       //地址0xC0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
  124.     send_8bit((lowcol  & 0x0f));       //地址0xC1
  125.     send_8bit((highcol & 0xf0));       //地址0xC2   
  126.     send_8bit((highcol & 0x0f));       //地址0xC3





  127.     send_command((0x80 | showmode));   //顯示控制參數(shù),開關(guān)顯示用位4,亮度可以通過改變位3~0
  128.     stb = 1;
  129. }




  130. void showtext(uchar code *text, uchar len)//顯示text中的所有字符
  131. {
  132.     uchar i;
  133.     uint  offset;




  134.     offset =  word_index * 32;

  135.     if (offset >= len)
  136.     {
  137.         word_index = 0;
  138.         offset = 0;
  139.     }

  140.     DelayN = DelayTime / (100 * 40);
  141.     for (i = offset; i < offset + 32; i += 2)
  142.     {
  143.         dispcol(text[ i], text[i + 1]);
  144.         delay_ms(DelayN);                  //列顯示之間的延時,可控制字符顯示寬度
  145.     }




  146.     if (cyc_count < 3)
  147.     {
  148.         cyc_count++;
  149.     }
  150.     else
  151.     {
  152.         cyc_count = 0;
  153.         word_index++;
  154.     }
  155. }




  156. void display(unsigned char index)      //根據(jù)ID選擇要顯示的文本內(nèi)容
  157. {
  158.     switch (index)  
  159.     {        
  160.         case 0:   
  161.         {                     
  162.             showtext(TEXT1, sizeof(TEXT1));
  163.         }
  164.         break;

  165.         case 1:   
  166.         {
  167.             showtext(TEXT2, sizeof(TEXT2));
  168.         }
  169.         break;

  170.         //default:
  171.         //{
  172.         //    display_word(TEXT1);
  173.         //}

  174.     }
  175. }




  176. /*********************************  
  177. 功能:讀取TM1617按鍵數(shù)據(jù)到鍵盤緩沖區(qū)
  178. **********************************/
  179. void readkey()
  180. {
  181.     uchar i, j;

  182.     send_command(0x42);                //送讀按鍵命令(42H)
  183.     dio = 1;




  184.     for (i = 0; i < 5; i++)
  185.     {                                  //讀TM1617的5BYTE按鍵數(shù)據(jù)到鍵盤緩沖區(qū)
  186.         for (j = 0; j < 8; j++)
  187.         {
  188.             clk = 0;
  189.             keybuf[ i] = keybuf[ i] >> 1;
  190.             clk = 1;
  191.             if (dio == 1)
  192.             {
  193.                 keybuf[ i] = keybuf[ i] | 0x80;
  194.             }
  195.             NOP;
  196.         }
  197.         NOP;
  198.         NOP;
  199.     }




  200.     clk = 0;
  201.     dio = 0;
  202.     stb = 1;
  203. }




  204. void exint0() interrupt 0              //INT0中斷入口
  205. {               
  206.     EX0 = 0;
  207.     if (direct == 1)                   //INT0口的狀態(tài), INT0=0(下降沿); INT0=1(上升沿)
  208.     {
  209.         if (showflag == 1)
  210.         {
  211.             delay_ms(15);
  212.             if (direct == 1)
  213.             {
  214.                 delay_ms(20);
  215.                 DelayTime=TimeCount;   
  216.                 TimeCount=0;           //延時周期計數(shù)清零         
  217.                 display(contentid);    //根據(jù)contentid給顯示寄存器送相應的顯示數(shù)據(jù)
  218.             }
  219.         }
  220.     }
  221.     else
  222.     {                  
  223.         dispcol(0x00, 0x00);           //反向揮動時消影,立即關(guān)閉顯示
  224.     }
  225.     EX0 = 1;
  226. }




  227. void timer0() interrupt 1        //定時器0中斷子程序
  228. {
  229.     TimeCount++;
  230. }




  231. /*********************************
  232.     主函數(shù)
  233. **********************************/
  234. void main()
  235. {
  236.     dispcol(0x00, 0x00);               //初始化顯示寄存器




  237.     direct = 1;
  238.     IT0    = 0;                        //設置INT0的中斷類型 (1:僅下降沿 0:上升沿和下降沿)
  239.     EX0    = 1;                        //使能INT0中斷
  240.     IP     = 0x02;    //設置中斷優(yōu)先級
  241.     AUXR  |= 0x80;  //定時器時鐘1T模式
  242.     TMOD   = 0x02;    //定時器0方式2,8位重裝載
  243.     TH0    = 0x80;    //設定定時器初值
  244.     TL0    = 0x80;           
  245.     EA     = 1;        //開放中斷
  246.     ET0    = 1;    //開放定時器1中斷
  247.     TF0    = 0;
  248.     TR0    = 1;    //啟動定時器0,開始計時*/




  249.     while(1)                           //循環(huán)
  250.     {
  251.         readkey();                     //讀鍵盤

  252.         if ((Key1 == 1) && (ledlight < 7))
  253.         {
  254.             ledlight++;                //按Key1表示升高LED亮度
  255.             showmode = (showmode & 0xf8) | ledlight;
  256.         }

  257.         if ((Key2 == 1) && (ledlight > 0))
  258.         {
  259.             ledlight--;                //按Key2表示降低LED亮度
  260.             showmode = (showmode & 0xf8) | ledlight;
  261.         }




  262.         if (Key3 == 1)                 //按Key3表示顯示前一幅文本
  263.         {
  264.             if (contentid > 0)
  265.             {
  266.                contentid--;
  267.             }
  268.             else
  269.             {
  270.                contentid = 1;
  271.             }
  272.         }

  273.         if (Key4 == 1)                 //按Key4表示顯示后一幅文本
  274.         {
  275.             if (contentid < 1)
  276.             {
  277.                contentid++;
  278.             }
  279.             else
  280.             {
  281.                 contentid = 0;
  282.             }
  283.         }




  284.         if (Key5 == 1)                 //Key5是控制文本是否顯示的乒乓開關(guān)
  285.         {                    
  286.             if (showflag == 1)
  287.             {        
  288.                 showflag = 0;
  289.                 showmode = ledlight & 0x07;   //立即關(guān)閉顯示
  290.                 dispcol(0x00, 0x00);
  291.             }
  292.             else
  293.             {
  294.                 showflag = 1;
  295.                 showmode = ledlight | 0x08;   //打開顯示
  296.             }
  297.         }        
  298.     }
  299. }
復制代碼




108_1540354_39a135b6acfabe3.jpg
108_1540354_b073779c4003aa1.jpg
108_1540354_b61a72fcd0b2ace.jpg
108_1540354_1c4d816b403defc.jpg
108_1540354_145e0cb03437184.jpg
108_1540354_8bb4204b6089095.jpg
108_1540354_e9a0f8b80cad4f7.jpg
108_1540354_b8f362f96946b8a.jpg
108_1540354_76c2429a9bcfa4b.jpg
108_1540354_d6d650301056814.jpg 108_1540354_e5f9d9ec0ccaa1d.jpg




108_1540354_4229ec07650645f.jpg



TM1617_ V1.2.pdf

639.9 KB, 下載次數(shù): 6, 下載積分: 黑幣 -5

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表