1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > STC15W201S串口蓝牙通信PWM控制RGB彩灯

STC15W201S串口蓝牙通信PWM控制RGB彩灯

时间:2021-08-03 18:29:35

相关推荐

STC15W201S串口蓝牙通信PWM控制RGB彩灯

国庆假期倒腾了五天,准备搞个手机蓝牙无线控制RGB LED的控制器;本来已经用STM32F103C8T6写好程序了,但这个芯片的成本比较高,如果多搞几个的话,还真心的费钱,且这个芯片用在这个功能上,也太大材小用了。于是准备用价格低廉的STC芯片替代,在购买电子元器件的时候,特意找了一款价格便宜的芯片STC15W201S,价格在3元左右一片吧。本以为很容易的在网上就会找到相关的例程的,没有想到,搜了一下,竟然一个相关的例程也没有找到,泪奔啊。。。

刚好最近在学习电子技术,都买了回来,不管怎样,试一下自己开搞吧,努力百度查询基本资料中。。

先介绍一下STC15W201S的芯片的基本信息吧,芯片的工作电压为2.5V至5.5V,保守点,用3.3V吧;芯片内带高精度RC震荡器且不能外接晶震,在一般的应用场合,连外围的晶震电路都省了,这点值得点赞啊。程序存储为1K,RAM为256字节,还带有4K的EEPROM,这个片内EEPROM还没有测试,下回想用的时候,再测试吧,这个感觉也不错,连外存都不用挂,还是一个字,省!片内有二个定时器,定时器0和定时器2,只有一个串口,但是能分时复用,相当于二个串口,但这点我还没有测试。

程序实现的功能如下,蓝牙模块通过串口与STC15W201S的串口相连接,接收与发送数据。输出五路PWM信号,对红绿蓝黄白五种色的LED灯进行调色及亮度控制。另有一条PWM信号控制输出,用于原灯电路与改装LED灯的控制转换。总不能将原灯的东西全部丢掉吧,加上去就好,通电后默认用原灯,通过控制器转换。

程序烧录参数如下图,需要注意,烧录时,需要将12与13脚的电平拉低才能写入。实物图有点乱,有兴趣看电路图吧,

KEIL代码:

USART.H内容

#ifndef __USART_H__

#define __USART_H__

typedef unsigned char u8;

typedef unsigned int WORD;

#define UNLOCK 0x00; //用于标识数据包的接收状态

#define LOCK 0xff;

#define BAUD 9600 //串口波特率 115200

#define NONE_PARITY 0 //无校验

#define ODD_PARITY 1 //奇校验

#define EVEN_PARITY 2 //偶校验

#define MARK_PARITY 3 //标记校验

#define SPACE_PARITY 4 //空白校验

#define PARITYBIT NONE_PARITY //定义校验位

#define DATA_LEN 7 //定义协议数据位长度

sfr P_SW1 = 0xA2; //外设功能切换寄存器1

#define S1_S0 0x40 //P_SW1.6

#define S1_S1 0x80 //P_SW1.7

extern bit busy;

extern unsigned int buf_num;

extern u8 rev_buf[6];

void Usart_Int(void);

void SendData(u8 dat);

void SendString(char *s);

void Uart();

#endif

USART.C 代码

#include <main.h>

#include <usart.h>

unsigned int buf_num;

bit busy;

u8 rev_buf[6];

void Usart_Int(void)

{

buf_num=0;

ACC = P_SW1;

ACC &= ~(S1_S0 | S1_S1); //S1_S0=0 S1_S1=0

P_SW1 = ACC; //(P3.0/RxD, P3.1/TxD)

#if (PARITYBIT == NONE_PARITY)

SCON = 0x50; //8位可变波特率

#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)

SCON = 0xda; //9位可变波特率,校验位初始为1

#elif (PARITYBIT == SPACE_PARITY)

SCON = 0xd2; //9位可变波特率,校验位初始为0

#endif

T2L = (65536 - (FOSC/4/BAUD)); //设置波特率重装值

T2H = (65536 - (FOSC/4/BAUD))>>8;

AUXR = 0x14; //T2为1T模式, 并启动定时器2

AUXR |= 0x01; //选择定时器2为串口1的波特率发生器

ES = 1; //使能串口1中断

EA = 1;

}

/*----------------------------

UART 中断服务程序

-----------------------------*/

void Uart() interrupt 4 using 1

{

if (RI)

{

RI = 0; //清除RI位

rev_buf[buf_num] =SBUF;

buf_num ++ ;

}

if (TI)

{

TI = 0; //清除TI位

busy = 0; //清忙标志

}

}

/*----------------------------

发送串口数据

----------------------------*/

void SendData(u8 dat)

{

while (busy); //等待前面的数据发送完成

ACC = dat; //获取校验位P (PSW.0)

if (P) //根据P来设置校验位

{

#if (PARITYBIT == ODD_PARITY)

TB8 = 0; //设置校验位为0

#elif (PARITYBIT == EVEN_PARITY)

TB8 = 1; //设置校验位为1

#endif

}

else

{

#if (PARITYBIT == ODD_PARITY)

TB8 = 1; //设置校验位为1

#elif (PARITYBIT == EVEN_PARITY)

TB8 = 0; //设置校验位为0

#endif

}

busy = 1;

SBUF = ACC; //写数据到UART数据寄存器

}

/*----------------------------

发送字符串

----------------------------*/

void SendString(char *s)

{

while (*s) //检测字符串结束标志

{

SendData(*s++); //发送当前字符

}

}

PWM.H 代码

#ifndef __PWM_H__

#define __PWM_H__

#define PWM_ON 1

#define PWM_OFF (!PWM_ON)

#define Timer0_Rate 25000 //中断频率

#define Timer0_Reload (65536UL -(FOSC / Timer0_Rate)) //Timer 0 重装值

#define PWM_DUTY_MAX 100 // 0~255 PWM周期, 最大255

extern int Red_Value;

extern int Greed_Value;

extern int Blue_Value;

extern int White_Value;

extern int Yellow_Value;

extern int K1_Value;

void Timer0_Int();

#endif

PWM.C 代码

#include <main.h>

#include <pwm.h>

int Red_Value;

int Greed_Value;

int Blue_Value;

int White_Value;

int Yellow_Value;

int K1_Value;

int PWM_COUNT; //PWM计数

void Timer0_Int() //初始化计数器0

{

AUXR |= (1<<7); // Timer0 set as 1T mode

TMOD &= ~(1<<2); // Timer0 set as Timer

TMOD &= ~0x03; // Timer0 set as 16 bits Auto Reload

TH0 = Timer0_Reload / 256; //Timer0 Load

TL0 = Timer0_Reload % 256;

ET0 = 1; //Timer0 Interrupt Enable

PT0 = 0; //高优先级

TR0 = 1; //Timer0 Run

EA = 1; //打开总中断

PWM_COUNT=0;

}

/********************** Timer0 1ms中断函数 ************************/

void timer0 (void) interrupt 1

{

PWM_COUNT++;

if (PWM_COUNT >= PWM_DUTY_MAX)

{

PWM_COUNT =0 ;

RED=PWM_ON;

GREED=PWM_ON;

BLUE=PWM_ON;

WHITE =PWM_ON;

YELLOW =PWM_ON;

K1=PWM_ON;

}

if (Red_Value <= PWM_COUNT) RED = PWM_OFF;

if (Greed_Value <= PWM_COUNT) GREED = PWM_OFF;

if (Blue_Value <= PWM_COUNT) BLUE = PWM_OFF;

if (White_Value <= PWM_COUNT) WHITE = PWM_OFF;

if (Yellow_Value <= PWM_COUNT) YELLOW = PWM_OFF;

if (K1_Value <= PWM_COUNT) K1 = PWM_OFF;

}

MAIN.H 代码

#ifndef __MAIN_H__

#define __MAIN_H__

#include <reg51.h>

#define FOSC 11059200L //系统频率

sfr P1M1 = 0x91; //IO模式控制寄存器

sfr P1M0 = 0x92; //IO模式控制寄存器

sfr AUXR = 0x8e; //辅助寄存器

sfr T2H = 0xd6; //定时器2高8位

sfr T2L = 0xd7; //定时器2低8位

sbit RED = P1^1; //RED 接在P1.1 16脚

sbit GREED =P1^3; //GREED 接P1.3 2脚

sbit BLUE =P1^5; //BLUE 接P1.5 4脚

sbit WHITE = P1^2; //白色 接 P1.2 1脚

sbit YELLOW =P1^4; //黄色 接 P1.4 3脚

sbit K1 = P1^0; // P1.0 第15脚 增加多一路当开关使用,同时也支持PWM输出

#endif

MAIN.C 代码

#include <reg51.h>

#include <intrins.h>

#include <main.h>

#include <usart.h>

#include <pwm.h>

void delay(unsigned int x);

void Act_Bit(void);

extern bit busy;

extern unsigned int buf_num;

extern u8 rev_buf[6];

extern int Red_Value;

extern int Greed_Value;

extern int Blue_Value;

extern int White_Value;

extern int Yellow_Value;

extern int K1_Value;

//按接收到的数据进行处理数据

void Act_Bit(void)

{

//aa f9 01 红 绿 蓝 dd 取值 0~100

//&& rev_buf[1] == 0xf9

if (rev_buf[0] == 0xaa && rev_buf[6] == 0xdd)

{

if (rev_buf[2] == 0x01) //开灯指令

{

if ( rev_buf[1] == 0xf9) //与STM32协议通用,调速RGB红绿蓝

{

Red_Value= rev_buf[3];

Greed_Value =rev_buf[4];

Blue_Value =rev_buf[5];

}

if ( rev_buf[1] == 0xf8) //增加白色,黄色PWM控制

{

White_Value = rev_buf[3];

Yellow_Value = rev_buf[4];

K1_Value = rev_buf[5];

}

}

//读取各个PWM值

if (rev_buf[2] == 0xff)

{

SendData(0xff);

SendData(Red_Value);

SendData(Greed_Value);

SendData(Blue_Value);

SendData(White_Value);

SendData(Yellow_Value);

SendData(K1_Value);

}

//对于开关K1,增加协议单独控制

if (rev_buf[1] == 0x00 && rev_buf[2] == 0x00 && rev_buf[3] == 0x00 && rev_buf[4] == 0x00 )

{

Red_Value=0x00;

Greed_Value=0x00 ;

Blue_Value =0x00;

White_Value =0x00;

Yellow_Value=0x00;

if ( rev_buf[5] == 0x00)

{

K1_Value =0x00;

}

}

}

}

void main(void)

{

//P1M1 |= 0x02;

P1M0 |=0x3f; //0x3f; 02 配置IO为推挽输出

Usart_Int();

Timer0_Int();

SendString("STC15F2K60S2\r\nUart Test !\r\n");

while(1)

{

if (buf_num >= DATA_LEN)

{

Act_Bit();

buf_num=0;

}

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。