AVR单片机Atxmega128A3U点亮SK6812RGBW灯带显示程序1、灯带数据格式和数位循序 file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml7376/wps1.jpg file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml7376/wps2.jpg file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml7376/wps3.jpg 2、LED码定义和时序file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml7376/wps4.jpg 数据传输时间 (1)协议采用单极性归零码,每个码元必须有低电平,本协议的每个码元起始为高电平,高电平时间宽度决定是“0”码还是“1”码; (2)书写程序时,码元周期最低要求为1.2us; (3)“0”码和“1”码的高电平时间按照上表的规定范围,“0”码和“1”码的低电平时间要求小于20us。 file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml7376/wps5.jpg 3、文件ledstrap.h灯带输入信号引脚为PORTF.2 #ifndef _LEDSTRAP_H_ #define _LEDSTRAP_H_ //灯带输出引脚控制 #define LED_DO_HIGH (PORTF.OUTSET=0b00000100) //灯带数据引脚输出高电平 PF2 #define LED_DO_LOW (PORTF.OUTCLR=0b00000100) //灯带数据引脚输出低电平 #define _nop_() #asm("NOP") #define COLOR_NUM 9 //显示9种颜色 #define LIGHT_NUM 20 //可以亮20个灯。 typedef struct color { unsigned char red; unsigned char green; unsigned char blue; unsigned char white; } COLOR; //32位RGBW颜色结构 void ledstrap_reset(); //灯带复位 //发送数据顺序: g7g6g5g4g3g2g1g0r7r6r5r4r3r2r1r0b7b6b5b4b3b2b1b0 void send_data(unsigned char r, unsigned char g, unsigned char b,unsigned char w); #endif 4、文件ledstrap.c#include "xmega128a3u.h" #include "general.h" #include "ledstrap.h" //”0”码输出函数 void code0() { LED_DO_HIGH; _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); LED_DO_LOW; _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); } //“1”码输出函数 void code1() { LED_DO_HIGH; _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); LED_DO_LOW; _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); } #define CODE0 code0(); #define CODE1 code1(); //>80μs void ledstrap_reset() { unsigned int i; LED_DO_LOW;//Din = 0; for(i=0;i<80;i++) { _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_(); } } //发送数据顺序: //g7g6g5g4g3g2g1g0r7r6r5r4r3r2r1r0b7b6b5b4b3b2b1b0w7w6w5w4w3w2w1w0 void send_data(unsigned char r,unsigned char g,unsigned char b,unsigned char w) { unsigned char a; for(a=0;a<8;a++) { if(g&0x80) CODE1 else CODE0 g<<=1; } for(a=8;a<16;a++) { if(r&0x80) CODE1 else CODE0 r<<=1; } for(a=16;a<24;a++) { if(b&0x80) CODE1 else CODE0 b<<=1; } for(a=24;a<32;a++) { if(w&0x80) CODE1 else CODE0 w<<=1; } } 5、演示函数AVR开发工具是:CodeVision3.12,初始化部分利用向导工具实现。 注意:本程序系统时钟是32MHz, Atxmega128A3U的PORTF的引脚2设置成输出,主程序如下: #include "delay.h" #include "ledstrap.h" // 定义几组颜色 COLOR rainbow[] = { {0xFF, 0x00, 0x00,0x00}, // red {0x00, 0xFF, 0x00,0x00}, //green {0x00, 0x00, 0xFF,0x00}, //blue {10,108,169,0}, //青蓝色 {0xFF, 0xFF, 0x00,0x00}, // yellow {0xFF, 0x00, 0xFF,0x00}, // violet {0, 0, 0xFF,0x7F}, // indigo {0x8B, 0, 0xFF,0x00}, // oringe {0, 0, 0,0}, // off }; //下面是系统时钟初始化程序,采用外部16M晶振,通过锁相环2倍频输出32MHz时钟 // System Clocks initialization void system_clocks_init(void) { unsigned char n,s; // Optimize for speed #pragma optsize- // Save interrupts enabled/disabled state s=SREG; // Disable interrupts #asm("cli") // External 16000.000 kHz oscillator initialization // Crystal oscillator increased drive current: Off // External Clock Source - Startup Time: 0.4-16 MHz Quartz Crystal - 16k CLK OSC.XOSCCTRL=OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc; // Enable the external oscillator/clock source OSC.CTRL|=OSC_XOSCEN_bm; // Wait for the external oscillator to stabilize while ((OSC.STATUS & OSC_XOSCRDY_bm)==0); // PLL initialization // PLL clock source: External Osc. or Clock // PLL multiplication factor: 2 // PLL output/2: Off // PLL frequency: 32.000000 MHz // Set the PLL clock source and multiplication factor n=(OSC.PLLCTRL & (~(OSC_PLLSRC_gm | OSC_PLLDIV_bm | OSC_PLLFAC_gm))) | OSC_PLLSRC_XOSC_gc | (0<<OSC_PLLDIV_bp) | 2; CCP=CCP_IOREG_gc; OSC.PLLCTRL=n; // Enable the PLL OSC.CTRL|=OSC_PLLEN_bm; // System Clock prescaler A division factor: 1 // System Clock prescalers B & C division factors: B:1, C:1 // ClkPer4: 32000.000 kHz // ClkPer2: 32000.000 kHz // ClkPer: 32000.000 kHz // ClkCPU: 32000.000 kHz n=(CLK.PSCTRL & (~(CLK_PSADIV_gm | CLK_PSBCDIV1_bm | CLK_PSBCDIV0_bm))) | CLK_PSADIV_1_gc | CLK_PSBCDIV_1_1_gc; CCP=CCP_IOREG_gc; CLK.PSCTRL=n; // Wait for the PLL to stabilize while ((OSC.STATUS & OSC_PLLRDY_bm)==0); // Select the system clock source: Phase Locked Loop n=(CLK.CTRL & (~CLK_SCLKSEL_gm)) | CLK_SCLKSEL_PLL_gc; CCP=CCP_IOREG_gc; CLK.CTRL=n; // Disable the unused oscillators: 2 MHz, 32 MHz, internal 32 kHz OSC.CTRL&= ~(OSC_RC2MEN_bm | OSC_RC32MEN_bm | OSC_RC32KEN_bm); // Lock the CLK.CTRL and CLK.PSCTRL registers n=CLK.LOCK | CLK_LOCK_bm; CCP=CCP_IOREG_gc; CLK.LOCK=n; // ClkPer output disabled PORTCFG.CLKEVOUT&= ~(PORTCFG_CLKOUTSEL_gm | PORTCFG_CLKOUT_gm); // PLL fault detection: Off // External clock source failure detection: On n=(OSC.XOSCFAIL & (~(OSC_PLLFDEN_bm | OSC_XOSCFDEN_bm))) | OSC_XOSCFDEN_bm; CCP=CCP_IOREG_gc; OSC.XOSCFAIL=n; // Restore interrupts enabled/disabled state SREG=s; // Restore optimization for size if needed #pragma optsize_default } // Oscillator failure non-maskable interrupt interrupt [OSC_OSCF_vect] void oscillator_failure_isr(void) { if (OSC.XOSCFAIL & OSC_XOSCFDIF_bm) { // External clock source failure detected // Clear the failure detection interrupt flag OSC.XOSCFAIL|=OSC_XOSCFDIF_bm; // Write your code here } } // 下面是初始化端口,只列出PORTF的初始化部分 void ports_init(void) { // PORTF initialization // OUT register PORTF.OUT=0xff; // Pin0: Input // Pin1: Input // Pin2: Output // Pin3: Input // Pin4: Input // Pin5: Input // Pin6: Input // Pin7: Input PORTF.DIR=0x04; // Pin0 Output/Pull configuration: Totempole/PULLUP // Pin0 Input/Sense configuration: Sense both edges // Pin0 Inverted: Off // Pin0 Slew Rate Limitation: Off PORTF.PIN0CTRL=PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc|PORT_OPC_PULLUP_gc; // Pin1 Output/Pull configuration: Totempole/PULLUP // Pin1 Input/Sense configuration: Sense both edges // Pin1 Inverted: Off // Pin1 Slew Rate Limitation: Off PORTF.PIN1CTRL=PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc|PORT_OPC_PULLUP_gc; // Pin2 Output/Pull configuration: Totempole/PULLUP // Pin2 Input/Sense configuration: Sense both edges // Pin2 Inverted: Off // Pin2 Slew Rate Limitation: Off PORTF.PIN2CTRL=PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc|PORT_OPC_PULLUP_gc; // Pin3 Output/Pull configuration: Totempole/PULLUP // Pin3 Input/Sense configuration: Sense both edges // Pin3 Inverted: Off // Pin3 Slew Rate Limitation: Off PORTF.PIN3CTRL=PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc|PORT_OPC_PULLUP_gc; // Pin4 Output/Pull configuration: Totempole/PULLUP // Pin4 Input/Sense configuration: Sense both edges // Pin4 Inverted: Off // Pin4 Slew Rate Limitation: Off PORTF.PIN4CTRL=PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc|PORT_OPC_PULLUP_gc; // Pin5 Output/Pull configuration: Totempole/PULLUP // Pin5 Input/Sense configuration: Sense both edges // Pin5 Inverted: Off // Pin5 Slew Rate Limitation: Off PORTF.PIN5CTRL=PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc|PORT_OPC_PULLUP_gc; // Pin6 Output/Pull configuration: Totempole/PULLUP // Pin6 Input/Sense configuration: Sense both edges // Pin6 Inverted: Off // Pin6 Slew Rate Limitation: Off PORTF.PIN6CTRL=PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc|PORT_OPC_PULLUP_gc; // Pin7 Output/Pull configuration: Totempole/PULLUP // Pin7 Input/Sense configuration: Sense both edges // Pin7 Inverted: Off // Pin7 Slew Rate Limitation: Off PORTF.PIN7CTRL=PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc|PORT_OPC_PULLUP_gc; // Interrupt 0 level: Disabled // Interrupt 1 level: Disabled PORTF.INTCTRL=(PORTF.INTCTRL & (~(PORT_INT1LVL_gm | PORT_INT0LVL_gm))) | PORT_INT1LVL_OFF_gc | PORT_INT0LVL_OFF_gc; // Pin0 Pin Change interrupt 0: Off // Pin1 Pin Change interrupt 0: Off // Pin2 Pin Change interrupt 0: Off // Pin3 Pin Change interrupt 0: Off // Pin4 Pin Change interrupt 0: Off // Pin5 Pin Change interrupt 0: Off // Pin6 Pin Change interrupt 0: Off // Pin7 Pin Change interrupt 0: Off PORTF.INT0MASK=0x00; // Pin0 Pin Change interrupt 1: Off // Pin1 Pin Change interrupt 1: Off // Pin2 Pin Change interrupt 1: Off // Pin3 Pin Change interrupt 1: Off // Pin4 Pin Change interrupt 1: Off // Pin5 Pin Change interrupt 1: Off // Pin6 Pin Change interrupt 1: Off // Pin7 Pin Change interrupt 1: Off PORTF.INT1MASK=0x00; } //主程序函数 void main(){ unsigned char n; int i,j,k; #pragma optsize- // Make sure the interrupts are disabled #asm("cli") // Low level interrupt: On // Round-robin scheduling for low level interrupt: On // Medium level interrupt: On // High level interrupt: On // The interrupt vectors will be placed at the start of the Application FLASH section n=(PMIC.CTRL & (~(PMIC_RREN_bm | PMIC_IVSEL_bm | PMIC_HILVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm))) | PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm|PMIC_RREN_bm; CCP=CCP_IOREG_gc; PMIC.CTRL=n; // Set the default priority for round-robin scheduling PMIC.INTPRI=0x00; // Restore optimization for size if needed #pragma optsize_default //初始化PORT和System_Clock system_clocks_init(); ports_init(); //测试灯带:20个灯珠同种颜色循环100次 K=0; while (k++<100){ for(i = 0;i<COLOR_NUM ; i++) { // 1. lighten all the lights for(j = 0; j < LIGHT_NUM; j++) send_data(rainbow.red, rainbow.green, rainbow.blue,rainbow.white); delay_ms(500); ledstrap_reset(); } } }
|