本工程实现了用WS2812 LED灯带显示音乐的幅度变化;非常酷炫!
单片机使用了STM8S003F3P6,通过读取声音传感器模块MAX4466的输出脚电平的ADC值,让WS2812灯带
随着音乐的节奏动起来,实现了一个简单的音乐节奏灯.
压缩包中是工程文件,PCB原理图是用在自己其他工程上的,由于WS2812只是单线控制,MAX4466也是只有一个端口读取数据,因此原理图
没有专门进行修改;只是在相应的引脚上进行了操作;
本工程对初次使用WS2812的朋友有参考作用。
Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)
单片机源程序如下:
- /**************************************************************/
- //Discription:E3 LIPO Charger for 2--3Bytes Battery
- //DETAIL:No Button,No Buzzer,Just LED,No Main Charge Port ,Just Balance Port
- //MCU:stm8s103F3
- //FOSC:8Mhz Internal RC oscillates
- //Date:2012.10.8 by HCC
- #include"stm8s103F.h"
- #include"userdef.h"
- #include"string.h"
- void SysInit(void);
- void EEPROM_Read(BYTE *PData,BYTE Len,BYTE *PAdress);
- void EEPROM_Write(BYTE *PData,BYTE Len,BYTE *PAdress);
- void Load_Config_Data(void);
- void Save_Config_Data(void);
- WORD AdcAvr(WORD *p);
- void SysAdc(void);
- void Timer(void);
- void BatByteCheck(void);
- void CheckBatVX(void);
- void BatCharge(void);
- void Error_proc(void);
- void LED_Set(BYTE data);
- void Get_vCell_Data(void);
- void Set_Led_Data(void);
- void Set_Led_By_TM1628(u8 mode);
- void Set_WS2812_Led(u8);
- u16 Get_Adc_Value(u8 chn,u8 count);
- BYTE Zero_Cur_Timer=0;
- BYTE CheckDC_Time=0;
- BYTE DC_Low=0;
- u8 bScale_Error=0;
- u8 uart_tick=0;
- u16 Balance_Time;
- #define TRICKLE_TIME 30*60
- #define VBUF_LEN 8
- u8 key_data=0,key_old=0,key_time=0,key_buf=0,key_buf_old=0,bkey_down=0;
- u8 pass_word=0,key_inter_time=0;
- u16 key_press_time=0;
- //u16 Min_Cell=0,Max_Cell=0,Standy_Pwm_Time=0,Chg_Time=0;
- //u16 IR_Set_Value1,IR_Set_Value2;
- //u16 IR_Echo_Value1,IR_Echo_Value2;
- //u16 Adc_PM;
- //u8 Print_Status,Echo_OK;
- //u16 Link_Count;
- //u8 Power_Down_Enable;
- //@near u8 DB[20];
- @near u16 AdcBuf[100];
- u16 DV=0,DV_Max=0;
- u8 Hold_Time=0,Fall_Time=0,Fall_Time2=0;
- #define MAX_LINK_COUNT 100
- #define KEY_OFF 0
- #define KEY_F 2
- #define KEY_B 4
- #define KEY_L 8
- #define DIR_F PC5=0
- #define DIR_B PC5=1
- #define PULSE_H PC6=1
- #define PULSE_L PC6=0
- #define ENDV 4240
- #define SOFT_TX_H PD1=1
- #define SOFT_TX_L PD1=0
- #define OUT_L {PC6=1;PC6=1;PC6=0;PC6=0;PC6=0;PC6=0;PC6=0;PC6=0;PC6=0;}
- #define OUT_H {PC6=1;PC6=1;PC6=1;PC6=1;PC6=1;PC6=1;PC6=1;PC6=0;PC6=0;}
- @far @interrupt void TIM2_UPD_IRQHandler (void) //2ms
- {
- TIM2_SR1=0x00;
- TimeBase++;
- T2ms = 1;
- return;
- }
- void delay_us(u16 t)
- {
- while(t--)
- {
- Nop();Nop();Nop();Nop();Nop();Nop();
- }
- }
- void delay_ms(u16 t)
- {
- u16 k;
- while(t--)
- {
- k=1050;
- while(k--)
- {
- Nop();Nop();Nop();Nop();Nop();Nop();
- }
- }
- }
- void SysInit(void)
- {
- u8 i;
- CFG_GCR |=0x01; //disable SWIM
- RST_SR |=0x1f;//clr reset flag
- CLK_ICKR=0X09; //ENALBE HSI 16MHZ & beep
- CLK_ECKR=0X00;
- CLK_CKDIVR=0x00; //HSIDIV/1 CPUDIV/1 :16MHZ
- while(!(CLK_ICKR & 0x02)) ; //HSIRDY=1
-
- CLK_PCKENR1 |=0XA0; //TIM1 & TIM2 ENABLE
- CLK_PCKENR2 |=0X08; //ADC
-
- PA_DDR=0x00;//xxxx 000x
- PA_CR1=0x0E;//0000 1110 pull high
- PA_CR2=0x00;
- PA_ODR=0x00;
-
- PB_DDR=0x30;//xx11 xxxx
- PB_CR1=0x30;//0011 0000//PB4,PB5--LED1,LED2
- PB_CR2=0x00;
- PB_ODR=0x30;//
-
- PC_DDR=0xF8;//1111 1XXX//dir2,pulse2,dir,pulse,PM
- PC_ODR=0x70;//0111 0000//PM=0,OTHERS=1
- PC_CR1=0xF8;//1111 1000
- PC_CR2=0x00;
-
- PD_DDR=0x30;//x011 000x
- PD_ODR=0x7E;//0111 1110
- PD_CR1=0x32;//0011 0010
- PD_CR2=0x00;
- /*
- PE_DDR=0x20;//LEDR1OFF
- PE_ODR=0x20;
- PE_CR1=0x20;
- PE_CR2=0;
-
- PF_DDR=0;
- PF_ODR=0x10;
- PF_CR1=0x10;//PF4 pull high
- PF_CR2=0;*/
-
- ADC_CSR=ADC_CH_CUR;//ch0
- ADC_CR1=0X71;//Ffre=Fmaster/18
- ADC_CR2|=0X08;//RIGH ALIGN
- ADC_TDRL=0X58;//0101 1000,AN3,AN4,AN6
- ADC_CR1|=0X01;//ENABLE ADON
- //uart1 BRR1--11~4 BRR2--15~12+3~0
- UART1_CR1=0x00;//设置M字长,8位数据位
- UART1_CR2=0x00;//使发送禁用TEN=0
- UART1_CR3=0x00;//1位停止位?
- //UART1_BRR2=0x00;//100KHZ
- //UART1_BRR1=0x0A;//BUARD_RATE=16000000/0XA0
- UART1_BRR2=0x0b;//115200
- UART1_BRR1=0x08;//BUARD_RATE=16000000/0X8B
- UART1_CR2=0x08;//TEN=1,REN=0
- UART1_DR=0;//要发送的数
- while((UART1_SR&0x40)==0);//发送是否完成
- //
- /*
- TIM1_ARRH=0x01;
- TIM1_ARRL=0x90;//16M/400=40K
- TIM1_CCR1H=0x00;
- TIM1_CCR1L=0x00;
- TIM1_CR1=0x81;
- TIM1_CCMR1=0x68;
- TIM1_CCER1=0x01;
- TIM1_BKR=0x80;
- TIM1_EGR=0x01;
- */
-
- TIM2_IER=0x00;
- TIM2_EGR=0x01;
- TIM2_PSCR=0x04;
- TIM2_ARRH=0x07;//2ms
- TIM2_ARRL=0xD0;
- TIM2_CNTRH=0x07;
- TIM2_CNTRH=0xD0;
- TIM2_CR1=0x01;
- TIM2_IER=0x01;
- Sei();
- //LED1GON;LED2GON;LED3GON;LED1RON;LED2RON;LED3RON;
- DV = 0;
- for(i=0;i<30;i++)
- {
- DV = i;
- Set_Led_Data();
- //Set_Led_By_TM1628(1);
- Set_WS2812_Led(1);
- PB4 = 0;
- PB5 = 0;
- delay_ms(50);
- //delay_us(50000);
- PB4 = 1;
- PB5 = 1;
- delay_ms(50);
- //delay_us(50000);
- }
- /*
- T_Sec = 0;
- T10ms = 0;
- LED_Set(3);
- while(T_Sec==0)
- {
- Timer();
- }
- //LED1GOFF;LED2GOFF;LED3GOFF;LED1ROFF;LED2ROFF;LED3ROFF;
- LED_Set(0);
- LED_Time = 0;
- Pwm_SW = 0;
- */
- }
- void Timer(void)
- {
- Fall_Time2++;
- if(TimeBase>=5) //10ms
- {
- TimeBase=0;
- //Pwm_SW++;
- //T10ms++;
- //CheckByteTime++;
- //ErrorTimer++;
- //CheckDC_Time++;
- //LED_Time++;
- //Standy_Pwm_Time++;
- //uart_tick++;
- if(Hold_Time>0)
- Hold_Time--;
- Fall_Time++;
- /*
- if(T10ms>=100)
- {
- T10ms = 0;
- if(Balance_Time<50000)
- Balance_Time++;
- T_Sec++;
- PreChargeTime++;
- PwmWorkTime++;
- Charge_Total_Time++;
- Zero_Cur_Timer++;
- //Chg_Time++;
- }
- */
- }
- }
- void EEPROM_Read(BYTE *pdata,BYTE len,BYTE *eepaddr)
- {
- //设置编程时间,FIX =1:编程时间固定为标准编程时间tprog
- FLASH_CR1 &= (BYTE)(~0x01);
- FLASH_CR1 |= 0x01;
- //MASS密钥,解除EEPROM的保护
- do
- {
- FLASH_DUKR = 0xAE;
- FLASH_DUKR = 0x56;
- }while((FLASH_IAPSR & 0x08) == 0);
- //EOP=1,EEPROM编程结束
- for(;len>0;len--)
- {
- *pdata++=*eepaddr++;
- while((FLASH_IAPSR & 0x04) != 0x00);
- }
- }
- /////////////////////////////////////////
- //定义EEPROM字节写 函数
- void EEPROM_Write(BYTE *pdata,BYTE len,BYTE *eepaddr)
- {
- //设置编程时间,FIX =1:编程时间固定为标准编程时间tprog
- FLASH_CR1 &= (BYTE)(~0x01);
- FLASH_CR1 |= 0x01;
- //MASS密钥,解除EEPROM的保护
- do
- {
- FLASH_DUKR = 0xAE;
- FLASH_DUKR = 0x56;
- }while((FLASH_IAPSR & 0x08) == 0);
- //EOP=1,EEPROM编程结束
- for(;len>0;len--)
- {
- *eepaddr++=*pdata++;
- while((FLASH_IAPSR & 0x04) != 0x00);
- }
- }
- ///////////////////////////////////////////////////
- void Load_Config_Data(void)
- {
- u8 i,sum;
- EEPROM_Read(eep,5,(BYTE *)0x4008);
- sum = 0;
- for(i=0;i<4;i++)
- sum += eep[i];
- /*
- if(eep[0]==0x58 && sum==eep[4])
- {
- Link_Count = eep[1]*256+eep[2];
- Power_Down_Enable = eep[3];
- }
- else
- {
- Link_Count = MAX_LINK_COUNT;
- Power_Down_Enable = 0xaa;
- }
- */
- }
- /////////////////////////////////////////////////////////////
- void Save_Config_Data(void)
- {
- u8 i,sum;
- eep[0] = 0x58;
- eep[1] = 0;//Link_Count/256;
- eep[2] = 0;//Link_Count%256;
- eep[3] = 0;//Power_Down_Enable;
- sum = 0;
- for(i=0;i<4;i++)
- sum += eep[i];
- eep[4] = sum;
- EEPROM_Write(eep,5,(BYTE *)0x4008); //lopo//340
- //if(PD_IDR & 2)
- }
- //
- u16 Get_Adc_Value(u8 chn,u8 count)
- {
- u8 i;
- u32 sum=0;
- u16 adc_value=0,max=0,min=0xffff;
- for(i=0;i<count;i++)
- {
- ADC_CSR=chn;
- ADC_CR1|=0x01;
- while((ADC_CSR&0x80)==0);
- adc_value = ADC_DRL;//ADC_DRH*256+ADC_DRL;
- adc_value += ADC_DRH*256;
- sum+=adc_value;
- //if(adc_value>max)
- //max = adc_value;
- //if(adc_value<min)
- //min = adc_value;
- }
- adc_value = sum*5/count;
- return adc_value;
- }
- /////////////////////////////////////////////////////////////
- void convert_to_decimal(unsigned int source,unsigned char *result,unsigned char num)
- {
- result[num] = ' ';
- while(num--)
- {
- result[num] = source%10+0x30;
- source /=10;
- }
-
- }
- /*
- void uart_send_byte_soft(u8 dat)
- {
- u8 i;
- Cli();
- for(i=0;i<10;i++)
- {
- if(i==0)
- SOFT_TX_L;
- else if(i==9)
- SOFT_TX_H;
- else
- {
- if(dat&1)
- SOFT_TX_H;
- else
- SOFT_TX_L;
- dat>>=1;
- }
- delay_us(28);
- }
- Sei();
- }
- u8 str_buf[7];
- void uart_send_string(u8*str)
- {
- while(*str)
- {
- uart_send_byte_soft(*str++);
- }
- }
- void uart_out_tick(void)
- {
- str_buf[4] = ' ';
- str_buf[5] = 0;
- if(uart_tick>=4)
- {
- if(uart_tick>=5)
- {
- uart_tick = 4;
- PD_DDR |= 2;
- delay_us(20);
- uart_send_string("V1:");
- convert_to_decimal(Aver_vCell[0],str_buf,4);
- uart_send_string(str_buf);
- uart_send_string("V2:");
- convert_to_decimal(Aver_vCell[1],str_buf,4);
- uart_send_string(str_buf);
- uart_send_string("V3:");
- convert_to_decimal(Aver_vCell[2],str_buf,4);
- uart_send_string(str_buf);
- uart_send_string("PWM:");
- convert_to_decimal(PwmBuf,str_buf,4);
- uart_send_string(str_buf);
- uart_send_string("C:");
- convert_to_decimal(BatCur,str_buf,4);
- uart_send_string(str_buf);
- uart_send_string("F:");
- convert_to_decimal(BatChargeFullTime,str_buf,4);
- uart_send_string(str_buf);
- uart_send_string("\r\n=======================\r\n");
- PD_DDR &= ~2;
- }
- }
- }
- */
- //u8 Tx[16];
- u8 str_buf[8];
- void Uart2_Send(u8* dat,u8 len)
- {
- u8 i;
- for(i=0;i<len;i++)
- {
- UART1_DR=dat[i];//要发送的数
- while(1)
- {
- if((UART1_SR&0x40)>0)
- break;
- }
- }
- }
- void Uart_Out_Data(void)
- {
- static u8 i=0;
- static u16 dv_max=0;
- //Uart2_Send("DV=",3);
- convert_to_decimal(DV,str_buf,4);
- Uart2_Send(str_buf,5);
- if(dv_max<DV)
- dv_max = DV;
- if(++i>=10)
- {
- i = 0;
- convert_to_decimal(dv_max,str_buf,4);
- str_buf[6] = '\r';
- str_buf[7] = '\n';
- Uart2_Send(str_buf,8);
- dv_max = 0;
- }
- /*
- for(i=0;i<10;i++)
- {
- convert_to_decimal(AdcBuf[i],str_buf,4);
- Uart2_Send(str_buf,5);
- }
- str_buf[0] = '\r';
- str_buf[1] = '\n';
- Uart2_Send(str_buf,2);
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei附件下载:
WS2812.7z
(312.94 KB, 下载次数: 82)
|