stm32之ws2812彩灯
使用stm32F103c8t4, 连接5v,G,A7 引脚
ws2812.c
#include "ws2812.h"
#include "usart.h"
#include "delay.h"
uint8_t pixelBuffer[PIXEL_NUM][24] ;
void ws281x_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //PORTA时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //SPI1时钟使能
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输
/* PA7 SPI1_MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PA7复用推挽输出 SPI
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //串行同步时钟的空闲状态为低电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步时钟的第2个跳变沿(上升或下降)数据被采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //定义波特率预分频的值:波特率预分频值为16
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
SPI_Cmd(SPI1, ENABLE); //使能SPI外设
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
DMA_DeInit(DMA1_Channel3); //将DMA的通道1寄存器重设为缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(SPI1 -> DR); //cpar; //DMA外设ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pixelBuffer; //cmar; //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,从内存读取发送到外设
DMA_InitStructure.DMA_BufferSize = PIXEL_NUM * 24; //cndtr; //DMA通道的DMA缓存的大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
DMA_Init(DMA1_Channel3, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
ws281x_closeAll(); //关闭全部的灯
delay_ms(100); //关闭全部的灯需要一定的时间
}
void ws281x_closeAll(void)
{
uint16_t i;
uint8_t j;
for(i = 0; i < PIXEL_NUM; ++i)
{
for(j = 0; j < 24; ++j)
{
pixelBuffer[i][j] = WS_LOW;
}
}
ws281x_show();
}
uint32_t ws281x_color(uint8_t red, uint8_t green, uint8_t blue)
{
return green << 16 | red << 8 | blue;
}
void ws281x_setPixelColor(uint16_t n ,uint32_t GRBcolor)
{
uint8_t i;
if(n < PIXEL_NUM)
{
for(i = 0; i < 24; ++i)
{
pixelBuffer[n][i] = (((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW);
}
}
}
void ws281x_setPixelRGB(uint16_t n ,uint8_t red, uint8_t green, uint8_t blue)
{
uint8_t i;
if(n < PIXEL_NUM)
{
for(i = 0; i < 24; ++i)
{
pixelBuffer[n][i] = (((ws281x_color(red,green,blue) << i) & 0X800000) ? WS_HIGH : WS_LOW);
}
}
}
void ws281x_show(void)
{
DMA_Cmd(DMA1_Channel3, DISABLE ); //关闭USART1 TX DMA1 所指示的通道
DMA_ClearFlag(DMA1_FLAG_TC3);
DMA_SetCurrDataCounter(DMA1_Channel3,24 * PIXEL_NUM );//DMA通道的DMA缓存的大小
DMA_Cmd(DMA1_Channel3, ENABLE); //使能USART1 TX DMA1 所指示的通道
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t ws281x_wheel(uint8_t wheelPos) {
wheelPos = 255 - wheelPos;
if(wheelPos < 85) {
return ws281x_color(255 - wheelPos * 3, 0, wheelPos * 3);
}
if(wheelPos < 170) {
wheelPos -= 85;
return ws281x_color(0, wheelPos * 3, 255 - wheelPos * 3);
}
wheelPos -= 170;
return ws281x_color(wheelPos * 3, 255 - wheelPos * 3, 0);
}
// Fill the dots one after the other with a color
void ws281x_colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<PIXEL_NUM; i++) {
ws281x_setPixelColor(i, c);
ws281x_show();
delay_ms(wait);
}
}
void ws281x_rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i<PIXEL_NUM; i++) {
ws281x_setPixelColor(i, ws281x_wheel((i+j) & 255));
}
ws281x_show();
delay_ms(wait);
}
}
// Slightly different, this makes the rainbow equally distributed throughout
void ws281x_rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< PIXEL_NUM; i++) {
ws281x_setPixelColor(i,ws281x_wheel(((i * 256 / PIXEL_NUM) + j) & 255));
}
ws281x_show();
delay_ms(wait);
}
}
//Theatre-style crawling lights.
void ws281x_theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<10; j++) { //do 10 cycles of chasing
for (int q=0; q < 3; q++) {
for (uint16_t i=0; i < PIXEL_NUM; i=i+3) {
ws281x_setPixelColor(i+q, c); //turn every third pixel on
}
ws281x_show();
delay_ms(wait);
for (uint16_t i=0; i < PIXEL_NUM; i=i+3) {
ws281x_setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
//Theatre-style crawling lights with rainbow effect
void ws281x_theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (uint16_t i=0; i < PIXEL_NUM; i=i+3) {
ws281x_setPixelColor(i+q, ws281x_wheel( (i+j) % 255)); //turn every third pixel on
}
ws281x_show();
delay_ms(wait);
for (uint16_t i=0; i < PIXEL_NUM; i=i+3) {
ws281x_setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
ws2812.h
#ifndef __WS2812_H
#define __WS2812_H
#include "stm32f10x.h"
#define PIXEL_NUM 60
//硬件spi模拟ws2811时序(用spi的8位数据模拟ws281x的一位数据)
//要将系统时钟设置为56M,分频数设置为8,则SPI的通信频率为7M,传输一位数据的时间约为143纳秒(ns)
//3*143 = 429ns 5*143 = 715ns 符合WS281X芯片的通信时序。
// _____
// | |___| 11111000 high level
// ___
// | |_____| 11100000 low level
#define WS_HIGH 0XF8
#define WS_LOW 0XE0
void ws281x_init(void);
void ws281x_closeAll(void);
void ws281x_rainbowCycle(uint8_t wait);
uint32_t ws281x_color(uint8_t red, uint8_t green, uint8_t blue);
void ws281x_setPixelColor(uint16_t n ,uint32_t GRBcolor);
void ws281x_show(void);
void ws281x_theaterChase(uint32_t c, uint8_t wait);
void ws281x_colorWipe(uint32_t c, uint8_t wait);
void ws281x_rainbow(uint8_t wait);
void ws281x_theaterChaseRainbow(uint8_t wait);
#endif /* __WS2812_H */
main.c
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "ws2812.h"
#include <stdio.h>
#include <stdlib.h>
int8_t i;
void Delay(u32 count)
{
u32 i = 0;
for(; i < count; i++);
}
int main(void)
{
uart_init(115200);
delay_init();
ws281x_init();
while(1)
{
int randomNumber = rand() % 255;
ws281x_colorWipe(ws281x_color(255, 0, 0), randomNumber); // Red
ws281x_colorWipe(ws281x_color(0, 255, 0), 50); // Green
ws281x_colorWipe(ws281x_color(200, 255, 0), 50); //黄色
ws281x_colorWipe(ws281x_color(100, 255, 50), 50); //冰蓝
ws281x_colorWipe(ws281x_color(155, 255, 0), 50); //嫩绿色
/*
for(i = 0; i < PIXEL_NUM; ++i)
{
ws281x_setPixelColor(i, ws281x_color(255, 250, 0));
ws281x_show();
delay_ms(5);
}
*/
}
}
C:\Users\yys53\OneDrive\python\bestscript>tree D:\stm32\qq-hh-My_Project_stm32\ws2812 /F
卷 软件 的文件夹 PATH 列表
卷序列号为 9DCD-7651
D:\STM32\QQ-HH-MY_PROJECT_STM32\WS2812
│ keilkilll.bat
│
├─CORE
│ core_cm3.c
│ core_cm3.h
│ startup_stm32f10x_hd.s
│
├─HARDWARE
│ ├─KEY
│ │ key.c
│ │ key.h
│ │
│ ├─LED
│ │ led.c
│ │ led.h
│ │
│ └─ws2812
│ ws2812.c
│ ws2812.h
│
├─OBJ
│ core_cm3.crf
│ core_cm3.d
│ core_cm3.o
│ delay.crf
│ delay.d
│ delay.o
│ key.crf
│ key.d
│ key.o
│ led.crf
│ led.d
│ led.o
│ main.crf
│ main.d
│ main.o
│ misc.crf
│ misc.d
│ misc.o
│ startup_stm32f10x_hd.d
│ startup_stm32f10x_hd.o
│ stm32f10x_dma.crf
│ stm32f10x_dma.d
│ stm32f10x_dma.o
│ stm32f10x_gpio.crf
│ stm32f10x_gpio.d
│ stm32f10x_gpio.o
│ stm32f10x_it.crf
│ stm32f10x_it.d
│ stm32f10x_it.o
│ stm32f10x_rcc.crf
│ stm32f10x_rcc.d
│ stm32f10x_rcc.o
│ stm32f10x_spi.crf
│ stm32f10x_spi.d
│ stm32f10x_spi.o
│ stm32f10x_usart.crf
│ stm32f10x_usart.d
│ stm32f10x_usart.o
│ sys.crf
│ sys.d
│ sys.o
│ system_stm32f10x.crf
│ system_stm32f10x.d
│ system_stm32f10x.o
│ USART.axf
│ USART.build_log.htm
│ usart.crf
│ usart.d
│ USART.hex
│ USART.htm
│ USART.lnp
│ usart.o
│ USART.sct
│ USART_USART.dep
│ ws2812.crf
│ ws2812.d
│ ws2812.o
│
├─STM32F10x_FWLib
│ ├─inc
│ │ misc.h
│ │ stm32f10x_adc.h
│ │ stm32f10x_bkp.h
│ │ stm32f10x_can.h
│ │ stm32f10x_cec.h
│ │ stm32f10x_crc.h
│ │ stm32f10x_dac.h
│ │ stm32f10x_dbgmcu.h
│ │ stm32f10x_dma.h
│ │ stm32f10x_exti.h
│ │ stm32f10x_flash.h
│ │ stm32f10x_fsmc.h
│ │ stm32f10x_gpio.h
│ │ stm32f10x_i2c.h
│ │ stm32f10x_iwdg.h
│ │ stm32f10x_pwr.h
│ │ stm32f10x_rcc.h
│ │ stm32f10x_rtc.h
│ │ stm32f10x_sdio.h
│ │ stm32f10x_spi.h
│ │ stm32f10x_tim.h
│ │ stm32f10x_usart.h
│ │ stm32f10x_wwdg.h
│ │
│ └─src
│ misc.c
│ stm32f10x_adc.c
│ stm32f10x_bkp.c
│ stm32f10x_can.c
│ stm32f10x_cec.c
│ stm32f10x_crc.c
│ stm32f10x_dac.c
│ stm32f10x_dbgmcu.c
│ stm32f10x_dma.c
│ stm32f10x_exti.c
│ stm32f10x_flash.c
│ stm32f10x_fsmc.c
│ stm32f10x_gpio.c
│ stm32f10x_i2c.c
│ stm32f10x_iwdg.c
│ stm32f10x_pwr.c
│ stm32f10x_rcc.c
│ stm32f10x_rtc.c
│ stm32f10x_sdio.c
│ stm32f10x_spi.c
│ stm32f10x_tim.c
│ stm32f10x_usart.c
│ stm32f10x_wwdg.c
│
├─SYSTEM
│ ├─delay
│ │ delay.c
│ │ delay.h
│ │
│ ├─sys
│ │ sys.c
│ │ sys.h
│ │
│ └─usart
│ usart.c
│ usart.h
│
└─USER
│ JLinkSettings.ini
│ main.c
│ startup_stm32f10x_hd.lst
│ stm32f10x.h
│ stm32f10x_conf.h
│ stm32f10x_it.c
│ stm32f10x_it.h
│ system_stm32f10x.c
│ system_stm32f10x.h
│ USART.map
│ USART.uvguix.qiu
│ USART.uvguix.yys53
│ USART.uvoptx
│ USART.uvprojx
│
└─DebugConfig
USART_STM32F103C8.dbgconf
USART_STM32F103C8_1.0.0.dbgconf
USART_STM32F103ZE_1.0.0.dbgconf
本文作者: 永生
本文链接: https://www.yys.zone/detail/?id=286
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
评论列表 (0 条评论)