新塘单片机MS51FB9AE驱动WS2812
最近开了个专栏,专门用来学习ESP32S3的,当然,代码也适用于ESP32板子,改下引脚号就可以的。感兴趣的可以看看。
https://blog.csdn.net/weixin_38476200/article/details/129828874
这个模块可以和所有单片机进行通讯,既可以用iic也可以用串口进行通讯。最多可以控制255个彩灯。测试过好几个厂家的彩灯,均能正常显示。资料已归档。感兴趣可以私聊。下面仅做下笔记,提示我自己,防止我忘记。
一、原理图
使用MS51FB9AE驱动ws2812,最多可支持255个彩灯。
这里设计的初衷是将这款单片机做成模块,让用户可以通过串口或者IIC协议控制WS2812彩灯。省却用户自己编写驱动的烦恼。毕竟ws2812对于一些基础比较薄弱的新手来说,驱动起来还是比较麻烦的。
代码使用新唐isp下载烧录器进行下载,P3为下载接口。
Q1主要为防止P1处电源反接!
二、代码讲解
main.c代码
#include "MS51.h"
void main()
{
MODIFY_HIRC();//24Mhz
Led_Init();
Enable_WDT_Reset_Config();
Timer0_Init();
Ws2812b_Init(RGB_Group,RGB_GPIO);
get_I2C_Address_From_Flash();
get_UART0_Baudrate_From_Flash();
//get_Leds_Count_From_Flash();
while(1)
{
if(IIC_Flag==1) //IIC接收到数据
{
process_Cmd(data_received);
IIC_Flag=0;
}
if(receiveFlag==1) //串口接收到数据
{
receiveFlag=0;
clr_IE_ES;
processUartCmd(uart_buffer);
set_IE_ES;
}
}
}
user.h文件
#ifndef _USER_H_
#define _USER_H_
#include "MS51.h"
#define REG_LEDS_COUNT 0x00 //设置LED个数
#define REG_LED_SPECIFIED_DATA 0x01 //设置指定ID的LED的颜色数据
#define REG_LED_SPECIFIED 0x02 //设置指定ID的LED的颜色数据,并立即显示
#define REG_LED_ALL_DATA 0x03 //设置所有LED的颜色数据
#define REG_LED_ALL 0x04 //设置所有LED的颜色数据,并立即显示
#define REG_TRANS_DATA_TO_LED 0x05 //使已经传输的颜色数据生效
#define REG_LEDS_COUNT_READ 0xfa //获取LED的个数
#define REG_I2C_ADDR_UART_BD_READ 0xfb //获取IIC/串口波特率
#define REG_UART_BAUDRATE 0xfc //设置串口波特率
#define REG_I2C_ADDRESS 0xfd //设置IIC地址
#define REG_BRAND 0xfe //获取商标
#define REG_VERSION 0xff //获取版本
#define UART_ACK (0x06)
#define FIRMWARE_BRAND ("linzhentao")
#define FIRMWARE_VERSION ("20210401-V02.03")
extern unsigned char SLAVE_ADDRESS; //IIC地址
extern unsigned long xdata BAUDRATE[13]; //串口波特率数据
extern unsigned char UART_BAUDRATE_INDEX; //串口波特率选择索引号
extern unsigned char _LedsCount; //临时彩灯数目存储变量
extern char I2C_Cmd_In_Processed; //IIC-看门狗喂狗操作变量
extern char Uart_Cmd_In_Processed; //Uart-看门狗喂狗操作变量
void process_Cmd(unsigned char *rxData); //IIC接收到数据时触发执行函数
void processUartCmd(unsigned char *rxData); //Uart接收到数据时触发执行函数
void setAllLedsColorData(unsigned char r,unsigned char g,unsigned char b); //设置所有彩灯颜色数据
void setAllLedsColor(unsigned char r,unsigned char g,unsigned char b); //设置所有彩灯颜色数据并立即显示
void set_Leds_Count_To_Flash(unsigned char count); //向Flash中写入彩灯的数目
void set_I2C_New_Address(unsigned char address); //设置IIC地址函数
void get_Leds_Count_From_Flash(void); //从Flash中获取彩灯的数目
void get_I2C_Address_From_Flash(void); //从Flash中获取IIC的地址
void get_UART0_Baudrate_From_Flash(void); //从Flash中获取串口波特率数据
led.h文件
#ifndef _LED_H
#define _LED_H
#define LED P05 //定义指示灯引脚
#define LED_MODE P05_PUSHPULL_MODE //设置指示灯引脚模式为强推挽模式
void Led_Init(void); //指示灯初始化函数
#endif
flash_data.h文件
#ifndef _FLASH_DATA_H
#define _FLASH_DATA_H
#include "MS51.h"
#define DATA_SIZE 128 //APROM-Flash空间大小
#define I2C_ADDRESS_IN_FALSH 0x3C01 //IIC地址在Flash中的地址
#define UART_BAUDRATE_IN_FALSH 0x3C02 //串口波特率在Flash中的地址(3个字节)
#define LEDS_COUNT_IN_FALSH 0x3C03 //彩灯的数目在Flash中的地址
unsigned char FLASH_ReadByte(unsigned int addr); //往特定地址读一个字节的数据
void FLASH_ProgramByte(unsigned int addr,unsigned char value);//往特定地址写一个字节
#endif
my_IIC.h文件
#ifndef _MY_IIC_H
#define _MY_IIC_H
#include "MS51.h"
#define EEPROM_SLA 0x40 //设置从机地址
#ifdef HIRC_16MHz
#define I2C_CLOCK 9//设置I2C时钟为400K(16000000/4/(I2C_CLOCK+1))
#else
#define I2C_CLOCK 14//设置I2C时钟为400K(24000000/4/(I2C_CLOCK+1))
#endif
#define IIC_Buffer_Size 16
extern bit IIC_Flag; //IIC接收到数据标志位
extern unsigned char xdata data_received[IIC_Buffer_Size]; //临时接收IIC数据空间
extern unsigned char xdata data_send[IIC_Buffer_Size]; //临时发送IIC数据空间
extern unsigned char data_rece_num; //接收数据计数
extern unsigned char data_send_num; //发送数据计数
extern unsigned char iic_end_send_flag; //发送停止数据计数
void Init_I2C(unsigned char address); //IIC初始化
void my_I2C_SendData(unsigned char *Data,char number); //IIC发送数据函数
#endif
my_uart.h文件
#ifndef _MY_UART_H
#define _MY_UART_H
#include "MS51.h"
#define Uart_Buffer_Size 9
#define UART_CMD_MAXED_LENGHT 8
#define UART_CMD_START_BYTE 0xcc //串口数据起始命令
#define UART_CMD_END_BYTE 0xdd //串口数据结束命令
#define UART0_Timer1 0
#define UART0_Timer3 1
#define UART1_Timer3 2
#define UART0 0
#define UART1 1
extern bit receiveFlag; //串口接收标志位,如果标志位置位,说明使用了串口中断接收到数据
extern unsigned char xdata uart_buffer[Uart_Buffer_Size]; //临时存储串口数据空间
void UART_Open(unsigned long u32SysClock, unsigned char u8UARTPort,unsigned long u32Baudrate);
void UART_Init(unsigned long baudRate); //串口初始化函数
void UART0_SendData8( char dat); //串口发送一个字节
void UART0_Send_Strings(char *dat,unsigned int num);//串口发送一串字符串
#endif
WS2812.h文件
#ifndef _WS2812_H
#define _WS2812_H
#include "MS51.h"
#define MAX_LEDS 255 //定义led最大个数
#define WS2812_NUMBERS 8 //定义默认led个数
#define RGB_Group 0 //定义RGB灯控制引脚在第几组
#define RGB_GPIO 4 //定义RGB灯控制引脚在第几组
#define RGB_PIN P04 //定义RGB灯引脚
#define RGB_PIN_H() RGB_PIN = 1 //设置引脚输出高电平
#define RGB_PIN_L() RGB_PIN = 0 //设置引脚输出低电平
#define RED 0xff0000 //红色
#define GREEN 0x00ff00 //绿色
#define BLUE 0x0000ff //蓝色
#define BLACK 0x000000 //熄灭
#define WHITE 0xffffff //白色
void Ws2812b_Init(int Px,int Pxx);//彩灯控制引脚模式设置
void setLedCount(unsigned char count);//设置彩灯数目
unsigned char getLedCount();//获取彩灯数目
void rgb_SetColor( unsigned char LedId, unsigned long color);//设置指定ID的彩灯颜色
void rgb_SetRGB(unsigned char LedId, unsigned long red, unsigned long green, unsigned long blue); //设置指定ID的彩灯颜色
void rgb_SendArray();//发送所有彩灯的颜色数据
#endif
ws2812可以参考我的另一篇文章了解开发的过程。
最近有点穷,如果各位路过的大佬觉得对您有帮助,跪求各位大佬赏口饭吃,点个关注。
如果您对于这个模块感兴趣,您可以联系本人或者留言。欢迎一起探讨进步。资料不挂积分了,挂积分亏的太多。模块资料包括PCB工程,模块代码。