找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6144|回复: 0
打印 上一主题 下一主题
收起左侧

STM8单片机+WS2812 LED灯带的应用程序 原理图PCB文件

  [复制链接]
跳转到指定楼层
楼主
本工程实现了用WS2812 LED灯带显示音乐的幅度变化;非常酷炫!
单片机使用了STM8S003F3P6,通过读取声音传感器模块MAX4466的输出脚电平的ADC值,让WS2812灯带
随着音乐的节奏动起来,实现了一个简单的音乐节奏灯.
压缩包中是工程文件,PCB原理图是用在自己其他工程上的,由于WS2812只是单线控制,MAX4466也是只有一个端口读取数据,因此原理图
没有专门进行修改;只是在相应的引脚上进行了操作;
本工程对初次使用WS2812的朋友有参考作用。

Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)


单片机源程序如下:
  1. /**************************************************************/
  2. //Discription:E3 LIPO Charger for 2--3Bytes Battery
  3. //DETAIL:No Button,No Buzzer,Just LED,No Main Charge Port ,Just Balance Port
  4. //MCU:stm8s103F3
  5. //FOSC:8Mhz Internal RC oscillates
  6. //Date:2012.10.8 by HCC
  7. #include"stm8s103F.h"
  8. #include"userdef.h"
  9. #include"string.h"
  10. void SysInit(void);
  11. void EEPROM_Read(BYTE *PData,BYTE Len,BYTE *PAdress);
  12. void EEPROM_Write(BYTE *PData,BYTE Len,BYTE *PAdress);
  13. void Load_Config_Data(void);
  14. void Save_Config_Data(void);
  15. WORD  AdcAvr(WORD *p);
  16. void SysAdc(void);
  17. void Timer(void);
  18. void BatByteCheck(void);
  19. void CheckBatVX(void);
  20. void BatCharge(void);
  21. void Error_proc(void);
  22. void LED_Set(BYTE data);
  23. void Get_vCell_Data(void);
  24. void Set_Led_Data(void);
  25. void Set_Led_By_TM1628(u8 mode);
  26. void Set_WS2812_Led(u8);
  27. u16 Get_Adc_Value(u8 chn,u8 count);
  28. BYTE Zero_Cur_Timer=0;
  29. BYTE CheckDC_Time=0;
  30. BYTE DC_Low=0;
  31. u8 bScale_Error=0;
  32. u8 uart_tick=0;
  33. u16 Balance_Time;
  34. #define TRICKLE_TIME 30*60
  35. #define VBUF_LEN 8
  36. u8 key_data=0,key_old=0,key_time=0,key_buf=0,key_buf_old=0,bkey_down=0;
  37. u8 pass_word=0,key_inter_time=0;
  38. u16 key_press_time=0;
  39. //u16 Min_Cell=0,Max_Cell=0,Standy_Pwm_Time=0,Chg_Time=0;
  40. //u16 IR_Set_Value1,IR_Set_Value2;
  41. //u16 IR_Echo_Value1,IR_Echo_Value2;
  42. //u16 Adc_PM;
  43. //u8 Print_Status,Echo_OK;
  44. //u16 Link_Count;
  45. //u8 Power_Down_Enable;
  46. //@near u8 DB[20];
  47. @near u16 AdcBuf[100];
  48. u16 DV=0,DV_Max=0;
  49. u8 Hold_Time=0,Fall_Time=0,Fall_Time2=0;
  50. #define MAX_LINK_COUNT 100
  51. #define KEY_OFF 0
  52. #define KEY_F 2
  53. #define KEY_B 4
  54. #define KEY_L 8
  55. #define DIR_F PC5=0
  56. #define DIR_B PC5=1
  57. #define PULSE_H PC6=1
  58. #define PULSE_L PC6=0
  59. #define ENDV 4240
  60. #define SOFT_TX_H PD1=1
  61. #define SOFT_TX_L PD1=0
  62. #define OUT_L {PC6=1;PC6=1;PC6=0;PC6=0;PC6=0;PC6=0;PC6=0;PC6=0;PC6=0;}
  63. #define OUT_H {PC6=1;PC6=1;PC6=1;PC6=1;PC6=1;PC6=1;PC6=1;PC6=0;PC6=0;}
  64. @far @interrupt void TIM2_UPD_IRQHandler (void)  //2ms
  65. {
  66.           TIM2_SR1=0x00;
  67.           TimeBase++;
  68.           T2ms = 1;
  69.           return;
  70. }
  71. void delay_us(u16 t)
  72. {
  73.           while(t--)
  74.           {
  75.                 Nop();Nop();Nop();Nop();Nop();Nop();
  76.           }
  77. }
  78. void delay_ms(u16 t)
  79. {
  80.     u16 k;
  81.         while(t--)
  82.         {
  83.                 k=1050;
  84.                 while(k--)
  85.                 {
  86.                         Nop();Nop();Nop();Nop();Nop();Nop();
  87.                 }
  88.         }
  89. }
  90. void SysInit(void)
  91. {
  92.                 u8 i;
  93.                 CFG_GCR |=0x01; //disable SWIM
  94.                 RST_SR |=0x1f;//clr reset flag
  95.                   CLK_ICKR=0X09;  //ENALBE HSI 16MHZ  &  beep
  96.                   CLK_ECKR=0X00;
  97.                   CLK_CKDIVR=0x00; //HSIDIV/1  CPUDIV/1  :16MHZ
  98.                   while(!(CLK_ICKR & 0x02))  ;  //HSIRDY=1
  99.                
  100.                 CLK_PCKENR1  |=0XA0;  //TIM1 & TIM2 ENABLE
  101.                 CLK_PCKENR2  |=0X08;  //ADC
  102.                
  103.                 PA_DDR=0x00;//xxxx 000x   
  104.                 PA_CR1=0x0E;//0000 1110 pull high
  105.                 PA_CR2=0x00;
  106.                 PA_ODR=0x00;
  107.                
  108.                 PB_DDR=0x30;//xx11 xxxx
  109.             PB_CR1=0x30;//0011 0000//PB4,PB5--LED1,LED2
  110.                 PB_CR2=0x00;
  111.                 PB_ODR=0x30;//
  112.                
  113.                 PC_DDR=0xF8;//1111 1XXX//dir2,pulse2,dir,pulse,PM
  114.                 PC_ODR=0x70;//0111 0000//PM=0,OTHERS=1
  115.                 PC_CR1=0xF8;//1111 1000
  116.                 PC_CR2=0x00;
  117.                                 
  118.                 PD_DDR=0x30;//x011 000x
  119.                 PD_ODR=0x7E;//0111 1110
  120.                 PD_CR1=0x32;//0011 0010
  121.                 PD_CR2=0x00;
  122.                 /*
  123.                 PE_DDR=0x20;//LEDR1OFF
  124.                 PE_ODR=0x20;
  125.                 PE_CR1=0x20;
  126.                 PE_CR2=0;
  127.                
  128.                 PF_DDR=0;
  129.                 PF_ODR=0x10;
  130.                 PF_CR1=0x10;//PF4 pull high
  131.                 PF_CR2=0;*/
  132.                                 
  133.                 ADC_CSR=ADC_CH_CUR;//ch0
  134.                 ADC_CR1=0X71;//Ffre=Fmaster/18
  135.             ADC_CR2|=0X08;//RIGH ALIGN
  136.             ADC_TDRL=0X58;//0101 1000,AN3,AN4,AN6
  137.             ADC_CR1|=0X01;//ENABLE ADON
  138.                 //uart1 BRR1--11~4 BRR2--15~12+3~0
  139.                 UART1_CR1=0x00;//设置M字长,8位数据位
  140.                 UART1_CR2=0x00;//使发送禁用TEN=0
  141.                 UART1_CR3=0x00;//1位停止位?
  142.                 //UART1_BRR2=0x00;//100KHZ
  143.                 //UART1_BRR1=0x0A;//BUARD_RATE=16000000/0XA0
  144.                 UART1_BRR2=0x0b;//115200
  145.                 UART1_BRR1=0x08;//BUARD_RATE=16000000/0X8B
  146.                 UART1_CR2=0x08;//TEN=1,REN=0
  147.                 UART1_DR=0;//要发送的数
  148.                 while((UART1_SR&0x40)==0);//发送是否完成
  149.                 //
  150.                 /*
  151.                 TIM1_ARRH=0x01;
  152.                 TIM1_ARRL=0x90;//16M/400=40K
  153.                 TIM1_CCR1H=0x00;
  154.                 TIM1_CCR1L=0x00;
  155.                 TIM1_CR1=0x81;
  156.                 TIM1_CCMR1=0x68;
  157.                 TIM1_CCER1=0x01;
  158.                 TIM1_BKR=0x80;
  159.                 TIM1_EGR=0x01;
  160.                 */
  161.                
  162.                 TIM2_IER=0x00;
  163.                 TIM2_EGR=0x01;
  164.                 TIM2_PSCR=0x04;
  165.                 TIM2_ARRH=0x07;//2ms
  166.                 TIM2_ARRL=0xD0;
  167.                 TIM2_CNTRH=0x07;
  168.                 TIM2_CNTRH=0xD0;
  169.                 TIM2_CR1=0x01;
  170.                 TIM2_IER=0x01;
  171.                 Sei();
  172.                 //LED1GON;LED2GON;LED3GON;LED1RON;LED2RON;LED3RON;
  173.                 DV = 0;
  174.                 for(i=0;i<30;i++)
  175.                 {
  176.                         DV = i;
  177.                         Set_Led_Data();
  178.                         //Set_Led_By_TM1628(1);
  179.                         Set_WS2812_Led(1);
  180.                         PB4 = 0;
  181.                         PB5 = 0;
  182.                         delay_ms(50);
  183.                         //delay_us(50000);
  184.                         PB4 = 1;
  185.                         PB5 = 1;
  186.                         delay_ms(50);
  187.                         //delay_us(50000);
  188.                 }
  189.                 /*               
  190.                 T_Sec = 0;
  191.                 T10ms = 0;
  192.                 LED_Set(3);
  193.                 while(T_Sec==0)
  194.                 {                                                                                       
  195.                         Timer();                        
  196.                 }
  197.                 //LED1GOFF;LED2GOFF;LED3GOFF;LED1ROFF;LED2ROFF;LED3ROFF;
  198.                 LED_Set(0);
  199.                 LED_Time = 0;
  200.                 Pwm_SW = 0;
  201.                 */
  202. }
  203. void  Timer(void)
  204. {
  205.         Fall_Time2++;
  206.         if(TimeBase>=5)     //10ms
  207.         {
  208.                         TimeBase=0;
  209.                         //Pwm_SW++;        
  210.                         //T10ms++;
  211.                         //CheckByteTime++;
  212.                         //ErrorTimer++;
  213.                         //CheckDC_Time++;
  214.                         //LED_Time++;
  215.                         //Standy_Pwm_Time++;
  216.                         //uart_tick++;
  217.                 if(Hold_Time>0)
  218.                   Hold_Time--;
  219.                 Fall_Time++;
  220.                 /*
  221.                   if(T10ms>=100)
  222.                   {
  223.             T10ms = 0;
  224.             if(Balance_Time<50000)
  225.                     Balance_Time++;
  226.             T_Sec++;
  227.             PreChargeTime++;
  228.             PwmWorkTime++;
  229.             Charge_Total_Time++;
  230.                                                 Zero_Cur_Timer++;
  231.                                                 //Chg_Time++;
  232.                 }        
  233.                 */               
  234.         }
  235. }
  236. void EEPROM_Read(BYTE *pdata,BYTE len,BYTE *eepaddr)
  237. {               
  238.         //设置编程时间,FIX =1:编程时间固定为标准编程时间tprog
  239.     FLASH_CR1 &= (BYTE)(~0x01);
  240.     FLASH_CR1 |= 0x01;
  241.         //MASS密钥,解除EEPROM的保护
  242.         do
  243.         {
  244.         FLASH_DUKR = 0xAE;
  245.         FLASH_DUKR = 0x56;
  246.         }while((FLASH_IAPSR & 0x08) == 0);
  247.         //EOP=1,EEPROM编程结束
  248.            for(;len>0;len--)
  249.            {
  250.                 *pdata++=*eepaddr++;
  251.                while((FLASH_IAPSR & 0x04) != 0x00);
  252.            }
  253. }
  254. /////////////////////////////////////////
  255. //定义EEPROM字节写 函数
  256. void EEPROM_Write(BYTE *pdata,BYTE len,BYTE *eepaddr)
  257. {
  258.         //设置编程时间,FIX =1:编程时间固定为标准编程时间tprog
  259.     FLASH_CR1 &= (BYTE)(~0x01);
  260.     FLASH_CR1 |= 0x01;
  261.         //MASS密钥,解除EEPROM的保护
  262.     do
  263.         {
  264.         FLASH_DUKR = 0xAE;
  265.         FLASH_DUKR = 0x56;
  266.         }while((FLASH_IAPSR & 0x08) == 0);
  267.         //EOP=1,EEPROM编程结束
  268.     for(;len>0;len--)
  269.     {
  270.             *eepaddr++=*pdata++;
  271.         while((FLASH_IAPSR & 0x04) != 0x00);
  272.     }
  273. }
  274. ///////////////////////////////////////////////////
  275. void Load_Config_Data(void)
  276. {
  277.         u8 i,sum;
  278.         EEPROM_Read(eep,5,(BYTE *)0x4008);
  279.         sum = 0;
  280.         for(i=0;i<4;i++)
  281.                 sum += eep[i];
  282.                 /*
  283.         if(eep[0]==0x58 && sum==eep[4])
  284.         {
  285.                 Link_Count = eep[1]*256+eep[2];
  286.                 Power_Down_Enable = eep[3];
  287.         }
  288.         else
  289.         {
  290.             Link_Count = MAX_LINK_COUNT;
  291.                 Power_Down_Enable = 0xaa;
  292.         }
  293.         */
  294. }
  295. /////////////////////////////////////////////////////////////
  296. void Save_Config_Data(void)
  297. {        
  298.         u8 i,sum;
  299.         eep[0] = 0x58;
  300.         eep[1] = 0;//Link_Count/256;
  301.         eep[2] = 0;//Link_Count%256;
  302.         eep[3] = 0;//Power_Down_Enable;
  303.         sum = 0;
  304.         for(i=0;i<4;i++)
  305.                 sum += eep[i];
  306.         eep[4] = sum;
  307.         EEPROM_Write(eep,5,(BYTE *)0x4008);  //lopo//340         
  308.         //if(PD_IDR & 2)  
  309. }
  310. //
  311. u16 Get_Adc_Value(u8 chn,u8 count)
  312. {
  313.         u8 i;
  314.         u32 sum=0;
  315.         u16 adc_value=0,max=0,min=0xffff;
  316.         for(i=0;i<count;i++)
  317.         {
  318.                   ADC_CSR=chn;
  319.                 ADC_CR1|=0x01;
  320.                 while((ADC_CSR&0x80)==0);
  321.                 adc_value = ADC_DRL;//ADC_DRH*256+ADC_DRL;
  322.                 adc_value += ADC_DRH*256;
  323.                 sum+=adc_value;                        
  324.                 //if(adc_value>max)
  325.                         //max = adc_value;
  326.                 //if(adc_value<min)
  327.                         //min = adc_value;        
  328.         }
  329.         adc_value = sum*5/count;
  330.         return adc_value;        
  331. }
  332. /////////////////////////////////////////////////////////////
  333. void convert_to_decimal(unsigned int source,unsigned char *result,unsigned char num)
  334. {
  335.                 result[num] = ' ';
  336.                 while(num--)
  337.                 {
  338.                         result[num] = source%10+0x30;
  339.                         source /=10;
  340.                 }
  341.                
  342. }
  343. /*
  344. void uart_send_byte_soft(u8 dat)
  345. {
  346.                 u8 i;
  347.                 Cli();
  348.                 for(i=0;i<10;i++)
  349.                 {
  350.                         if(i==0)
  351.                                 SOFT_TX_L;
  352.                         else if(i==9)
  353.                                 SOFT_TX_H;
  354.                         else
  355.                         {
  356.                                 if(dat&1)
  357.                                         SOFT_TX_H;
  358.                                 else
  359.                                         SOFT_TX_L;
  360.                                 dat>>=1;
  361.                         }
  362.                         delay_us(28);
  363.                 }
  364.                 Sei();
  365. }
  366. u8 str_buf[7];
  367. void uart_send_string(u8*str)
  368. {
  369.                 while(*str)
  370.                 {
  371.                         uart_send_byte_soft(*str++);
  372.                 }
  373. }
  374. void uart_out_tick(void)
  375. {
  376.         str_buf[4] = ' ';
  377.         str_buf[5] = 0;
  378.         if(uart_tick>=4)
  379.         {
  380.                 if(uart_tick>=5)
  381.                 {
  382.                         uart_tick = 4;
  383.                         PD_DDR |= 2;
  384.                         delay_us(20);
  385.                         uart_send_string("V1:");
  386.                         convert_to_decimal(Aver_vCell[0],str_buf,4);
  387.                         uart_send_string(str_buf);
  388.                         uart_send_string("V2:");
  389.                         convert_to_decimal(Aver_vCell[1],str_buf,4);
  390.                         uart_send_string(str_buf);
  391.                         uart_send_string("V3:");
  392.                         convert_to_decimal(Aver_vCell[2],str_buf,4);
  393.                         uart_send_string(str_buf);        
  394.                         uart_send_string("PWM:");
  395.                         convert_to_decimal(PwmBuf,str_buf,4);
  396.                         uart_send_string(str_buf);        
  397.                         uart_send_string("C:");
  398.                         convert_to_decimal(BatCur,str_buf,4);
  399.                         uart_send_string(str_buf);                        
  400.                         uart_send_string("F:");
  401.                         convert_to_decimal(BatChargeFullTime,str_buf,4);
  402.                         uart_send_string(str_buf);        
  403.                         uart_send_string("\r\n=======================\r\n");
  404.                         PD_DDR &= ~2;        
  405.                 }
  406.         }
  407. }
  408. */
  409. //u8 Tx[16];
  410. u8 str_buf[8];
  411. void Uart2_Send(u8* dat,u8 len)
  412. {
  413.         u8 i;
  414.         for(i=0;i<len;i++)
  415.         {
  416.                 UART1_DR=dat[i];//要发送的数
  417.                 while(1)
  418.                 {
  419.                   if((UART1_SR&0x40)>0)
  420.                           break;
  421.                 }
  422.         }
  423. }
  424. void Uart_Out_Data(void)
  425. {
  426.         static u8 i=0;
  427.         static u16 dv_max=0;
  428.         //Uart2_Send("DV=",3);
  429.         convert_to_decimal(DV,str_buf,4);
  430.         Uart2_Send(str_buf,5);
  431.         if(dv_max<DV)
  432.           dv_max = DV;
  433.         if(++i>=10)
  434.         {
  435.           i = 0;
  436.           convert_to_decimal(dv_max,str_buf,4);
  437.           str_buf[6] = '\r';
  438.           str_buf[7] = '\n';
  439.           Uart2_Send(str_buf,8);
  440.           dv_max = 0;         
  441.         }
  442.         /*
  443.         for(i=0;i<10;i++)
  444.         {
  445.                 convert_to_decimal(AdcBuf[i],str_buf,4);
  446.                 Uart2_Send(str_buf,5);         
  447.         }
  448.         str_buf[0] = '\r';
  449.         str_buf[1] = '\n';
  450.         Uart2_Send(str_buf,2);
  451. ……………………

  452. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei附件下载:
WS2812.7z (312.94 KB, 下载次数: 82)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏7 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表