Spieed micarray开发介绍

一、产品概述

SK9822是一种**两线制三通道传输(RGB)**驱动智能控制电路和发光 电路于一体的LED光源控制。产品包含信号解码模块、 数据缓冲器、内置恒流电路和RC振荡器;CMOS,低电压,低功耗 消耗;256级灰度PWM调节和32级亮度调节;采用双路 输出,数据与CLK信号同步,串联各晶圆输出动作 同步。

应用领域:

  • 全彩LED串灯、LED全彩模组、LED超硬超软灯、LED护栏管、LED外观/场景照明
  • LED点光源、LED像素屏、LED异形屏、各种电子产品、电器设备等。
    顶级SMD内部集成高品质外部控制线串联级联恒流IC;5 v应用;默认开电灯;

●控制电路与RGB芯片中的SMD 5050元器件,形成完全控制像素、混色的均匀性和一致性;

●采用双线同步控制

●三路RGB输出控制,8Bit(256)色;5Bit(32) 调节亮度;

三路恒流驱动,特定信号自检测功能

●最高频率30MHZ串行数据输入

●双路数据传输,内置支持不间断

二、基于STM32的SK9822灯珠控制

cpp 复制代码
#include "gpio.h"
#include "head.h"
#include <string.h>

// GPIO定义(PA0=CLK,PA1=DATA,和硬件连接对应)
#define SK9822_CLK_PIN    GPIO_PIN_0
#define SK9822_DATA_PIN   GPIO_PIN_1
#define SK9822_GPIO_PORT  GPIOA

// 电平操作宏定义
#define CLK_WBit(x)  HAL_GPIO_WritePin(SK9822_GPIO_PORT, SK9822_CLK_PIN, (GPIO_PinState)x)
#define DATA_WBit(x) HAL_GPIO_WritePin(SK9822_GPIO_PORT, SK9822_DATA_PIN, (GPIO_PinState)x)

//精准CPU周期延时(STM32F405 168MHz1周期=5.95ns满足SK9822时序要求)
void SK9822_DelayCycles(uint32_t cycles) {
  __IO uint32_t cnt = cycles;
  while (cnt--) {
    __NOP(); // 空操作,纯消耗CPU周期,无额外开销
  }
}

void SK9822_SendBit(uint8_t bit) {
  // 把当前位的 0/1 输出到 DATA 引脚
  bit ? DATA_WBit(1) : DATA_WBit(0);
  
  // 等数据稳定(20个CPU周期,约119ns)
  SK9822_DelayCycles(20);
  
  // 拉 CLK 引脚到高电平,SK9822 会在这个时候"采样"DATA 引脚上的位
  CLK_WBit(1);
  SK9822_DelayCycles(20);
  
  // 拉 CLK 引脚到低电平,准备发送下一位
  CLK_WBit(0);
  SK9822_DelayCycles(20);
}

void SK9822_SendByte(uint8_t byte) {
  for (uint8_t i = 0; i < 8; i++) {
    // 步骤1:取当前字节的"最高位"(比如第一次循环,byte=0xFF,最高位是1)
    uint8_t bit = (byte >> 7) & 0x01;
    
    // 步骤2:把这一位发送出去(调用 SK9822_SendBit)
    SK9822_SendBit(bit);
    
    // 步骤3:字节左移1位,把"下一位"变成最高位(比如 0xFF << 1 → 0xFE,下一位还是1)
    byte <<= 1;
  }
}


void SK9822_SendLedFrame(uint8_t red, uint8_t green, uint8_t blue) {

	//uint8_t max_bright = 0x1F;
	uint8_t max_bright = 0x08;
	
	uint8_t byte1 = (0x07 << 5) | max_bright;

	uint8_t byte2 = ((blue & 0x0F) << 4) | ((blue >> 4) & 0x0F);

	uint8_t byte3 = ((green & 0x0F) << 4) | ((green >> 4) & 0x0F);

	uint8_t byte4 = ((red & 0x0F) << 4) | ((red >> 4) & 0x0F);
	
	uint8_t frame[4] = {byte1,byte2,byte3,byte4};

	// 发送这4字节(32位)
	for(uint8_t i = 0; i < 4; i++) 
	{
		SK9822_SendByte(frame[i]);
	}
}
#if 0
void spieed_test()
{
	for (uint8_t i = 0; i < 4; i++) {
		SK9822_SendByte(0x00);
	}
	
	for (uint8_t i = 0; i < 32; i++) {
		uint8_t red = 0xFF;
		uint8_t green = 0x00;
		uint8_t blue = 0x00;
		SK9822_SendLedFrame(red, green, blue);
	}
	
	for (uint8_t i = 0; i < 4; i++) {
		SK9822_SendByte(0xFF);
	}
}
#endif
// 核心更新函数
void SK9822_UpdateLeds(uint8_t led_num, uint8_t rgb_data[][3]) {
  __disable_irq(); // 禁用中断,避免时序错乱

  // 起始帧:4字节0x00
  for (uint8_t i = 0; i < 4; i++) {
    SK9822_SendByte(0x00);
  }

  // 发送每颗灯的数据(只给目标灯赋值,其他全0)
  for (uint8_t i = 0; i < led_num; i++) {
    uint8_t red = rgb_data[i][0];
    uint8_t green = rgb_data[i][1];
    uint8_t blue = rgb_data[i][2];
    SK9822_SendLedFrame(red, green, blue);
  }

  // 结束帧:4字节0xFF
  for (uint8_t i = 0; i < 4; i++) {
    SK9822_SendByte(0xFF);
  }

  SK9822_DelayCycles(50);
  __enable_irq(); // 恢复中断
}

void SK9822_SingleLedOn(uint8_t led_index, uint8_t red, uint8_t green, uint8_t blue) {
  uint8_t rgb[TOTAL_LED][3] = {0}; 
  

  rgb[led_index][0] = red;
  rgb[led_index][1] = green;
  rgb[led_index][2] = blue;
  
  SK9822_UpdateLeds(TOTAL_LED, rgb); 
}

void spieed_test()
{
	SK9822_SingleLedOn(LED_ROW1_U11,0x00,0x00,0x00);
}

三、基于STM32的麦克风数据的提取

cpp 复制代码
#include "gpio.h"
#include "head.h"
#include <math.h>
#include <stdlib.h>

#define MIC_SCK_W(x)  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13,(GPIO_PinState)x);
#define MIC_SDW_W(x)  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12,(GPIO_PinState)x);

#define SPIEED_MIC_D0() HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0);
#define SPIEED_MIC_D1() HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_1);
#define SPIEED_MIC_D2() HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_2);
#define SPIEED_MIC_D3() HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_3);

extern void SK9822_DelayCycles(uint32_t cycles);
extern void SK9822_SingleLedOn(uint8_t led_index, uint8_t red, uint8_t green, uint8_t blue);

void Sipeed_MIC_Init(void)
{
  MIC_SCK_W(1);
  MIC_SDW_W(1);
}

uint32_t Sipeed_read_left(uint8_t mic)
{
  uint8_t i = 0;
  uint32_t data = 0;
  int ret = 0;
  SK9822_DelayCycles(325);
	
  MIC_SDW_W(0);
	
  for(i = 1; i <= 32; i++)
  {
    MIC_SCK_W(1);
    
    if (i >= 2 && i <= 25)
    {
      if (mic == 0)
      {
        ret = SPIEED_MIC_D0();
        data |= ret << (33-i);
      }
      else if (mic == 1)
      {
        ret = SPIEED_MIC_D1();
        data |= ret << (33-i);
      }
      else if (mic == 2)
      {
        ret = SPIEED_MIC_D2();
        data |= ret << (33-i);
      }
    }
    MIC_SCK_W(0);
    
  }
  return data;
}

uint32_t Sipeed_read_right(uint8_t mic)
{
  uint8_t i = 0;
  uint32_t data = 0;
  int ret = 0;
  SK9822_DelayCycles(325);
	
  MIC_SDW_W(1);
  for(i = 1; i <= 32; i++)
  {
    MIC_SCK_W(1);
    
    if (i >= 2 && i <= 25)
    {
      if (mic == 0)
      {
        ret = SPIEED_MIC_D0();
        data |= ret << (33-i);
      }
      else if (mic == 1)
      {
        ret = SPIEED_MIC_D1();
        data |= ret << (33-i);
      }
      else if (mic == 2)
      {
        ret = SPIEED_MIC_D2();
        data |= ret << (33-i);
      }
	  else if (mic == 3)
      {
        ret = SPIEED_MIC_D3();
        data |= ret << (33-i);
      }
    }
    MIC_SCK_W(0);
    
  }
  return data;
}

void qqqqqqqqq_test()
{
	uint32_t data = 0;
	uint32_t data2 = 0;
	
	data = Sipeed_read_left(0);
	data2 = Sipeed_read_right(0);
	printf("mic0:%u\r\n",data);
	printf("mic1:%u\r\n",data2);
	
	data = Sipeed_read_left(1);
	data2 = Sipeed_read_right(1);
	printf("mic2:%u\r\n",data);
	printf("mic3:%u\r\n",data2);
	
	data = Sipeed_read_left(2);
	data2 = Sipeed_read_right(2);
	printf("mic4:%u\r\n",data);
	printf("mic5:%u\r\n",data2);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 简化的数据采集函数 - 直接使用平均值
int Mic_GetAverages(int avg_buf[]) {
  uint32_t temp_buf[10] = {0};
  uint32_t sum = 0;
  
  // 左声道麦克风 0,1,2
  for (int mic_idx = 0; mic_idx < 3; mic_idx++) {
    sum = 0;
    for (int j = 0; j < 10; j++) {
      temp_buf[j] = Sipeed_read_left(mic_idx);
      sum += temp_buf[j];
    }
    // 直接使用平均值
    avg_buf[mic_idx] = (int)(sum / 10000);
  }
  
  // 右声道麦克风 0,1,2
  for (int mic_idx = 0; mic_idx < 3; mic_idx++) {
    sum = 0;
    for (int j = 0; j < 10; j++) {
      temp_buf[j] = Sipeed_read_right(mic_idx);
      sum += temp_buf[j];
    }
    // 直接使用平均值
    avg_buf[mic_idx + 3] = (int)(sum / 10000);
  }
  
  return 0;
}

// 声源定位函数
int Spieed_MIC_Sample()
{
  int first_averages[6] = {0};
  int max_value = 0;       
  int max_idx = 0;          
  
  // 1. 采集数据:获取6个采样点的平均值(存入first_averages)
  Mic_GetAverages(first_averages);
  
  // 2. 调试输出:打印每个采样点的平均值
  for (int i = 0; i < 6; i++) {
    printf("Mic%d----first_averages=%d\r\n", i + 1, first_averages[i]); 
  }
  
  // 3. 找出 first_averages 中的最大值及对应索引
  max_value = first_averages[0]; 
  max_idx = 0;                  
  for (int i = 1; i < 6; i++) {  
    if (first_averages[i] > max_value) {
      max_value = first_averages[i]; 
      max_idx = i;             
    }
  }
  
  // 4. 打印最大值结果
  printf("Max value: %d, at Mic%d\n", max_value, max_idx + 1); 
  return max_idx; 
}

// 主控制函数
void Thr_MIC_Con_LED()
{
  while(1) {
    int ret = Spieed_MIC_Sample();

    SK9822_SingleLedOn(ret * 2, 0x00, 0x00, 0xFF);
    printf("Stable detection: Mic%d\n", ret);

    HAL_Delay(500); // 缩短延迟提高响应速度
  }
}

打印段可以提取出来数据,但是数据并不准确和灵敏,简单的对sipeed mic的了解,后续有继续跟进的话会及时更新代码的

相关推荐
哄娃睡觉2 小时前
STM32 VBAT外围电路接法详解--备用电源(纽扣电池)
stm32
小李做物联网2 小时前
26.3基于stm32单片机毕业设计物联网软硬件智能遮阳棚设计
stm32·单片机·嵌入式硬件·物联网
易水寒陈2 小时前
使用1个定时器作为多个串口的超时计数器
stm32·单片机
芯联智造3 小时前
【stm32简单外设篇】- 水银开关
c语言·stm32·单片机·嵌入式硬件
Geek__19923 小时前
STM32F103开发板上移植Agile Modbus库的详细指南
stm32·嵌入式硬件·敏捷流程
hazy1k3 小时前
MSPM0L1306 从零到入门:第二章 GPIO 从入门到精通 —— 点亮你的第一颗LED
stm32·单片机·嵌入式硬件·esp32·ti·mspm0
d111111111d3 小时前
STM32外设学习--PWR电源控制
笔记·stm32·单片机·嵌入式硬件·学习
小柯博客4 小时前
从零开始打造 OpenSTLinux 6.6 Yocto 系统 - STM32MP2(基于STM32CubeMX)(三)
stm32·嵌入式硬件·开源·嵌入式·yocto·st·stm32mp2
阿容1234565 小时前
stm32两轮平衡车-01
stm32·单片机·嵌入式硬件