功能如下
1、两种模式,手动模式和自动模式
2、手动模式下,可以通过按键控制窗帘开启关闭
2、自动模式下,根据光照值,控制窗帘开启关闭
3、光照阈值可以通过按键修改
4、模式也可以通过按键切换
5、所有数据通过蓝牙传递到手机app
6、可以通过蓝牙下发指令进行远程的控制
A 设置
B 增加
C 减少
演示视频:基于STC8单片机的智能窗帘_哔哩哔哩_bilibili
电路原理图
PCB
所有代码如下:
#define OLEDJ_IIC_SCL P1_4
#define OLEDJ_IIC_SCL_MODE {P1M1&=~0x10;P1M0&=~0x10;}//P1_4双向IO口
#define OLEDJ_IIC_SDA P1_5
#define OLEDJ_IIC_SDA_MODE {P1M1&=~0x20;P1M0&=~0x20;}//P1_5双向IO口
#define OLED_B_zhiow_font16
#define OLED_B_ZHITI8
#define OLED_B_num1
#include <intrins.h>
#include <STC8HX.h>
uint32 sys_clk = 24000000;//设置PWM、定时器、串口、EEPROM频率参数
#include "lib/UART.h"
#include "mylib/OLED_jy.h"
#include "lib/ADC.h"
#include "lib/wmath.h"
#include "lib/delay.h"
#include <stdlib.h>
#include <stdio.h>
uint16 ticks = 0;
int8 flag = 0;
uint16 TCNT = 0;
int8 light = 0;
int8 light_MAX = 54;
int8 light_MIN = 22;
int8 wendu_max = 35;
int8 wendu_min = 22;
uint8 set2 = 0;
char RES = 0;
uint8 pwmnum = 0;
void set_timer0(uint16 x);
uint16 servo_write(uint16 vlaue);
char *numtostr(int num)
{
static char my_dest[10];
_itoa(num, my_dest, 10);
return my_dest;
}
char *String(char *dest, const char *src)
{
static char my_dest[50];
strcpy(my_dest, dest);
strcat(my_dest, src);
return my_dest;
}
void UART_R(void) interrupt 4 using 1{
if(UART1_GET_RX_FLAG){
UART1_CLEAR_RX_FLAG;
RES = SBUF;
if(RES == 'A'){
set2 = set2 + 1;
if(set2 > 1){
set2 = 0;
}
}
if(RES == 'B'){
if(set2 == 1){
ticks = servo_write(180);
pwmnum = 1;
}
else{
light_MAX = light_MAX + 1;
}
}
if(RES == 'C'){
if(set2 == 1){
pwmnum = 0;
ticks = servo_write(0);
}
else{
light_MAX = light_MAX - 1;
}
}
}
}
void Timer0Init(void) //100微秒@24.000MHz
{
AUXR &= 0x7f; //定时器时钟12T模式
TMOD &= 0xf0; //设置定时器模式
TL0 = 0x38; //设定定时初值
TH0 = 0xff; //设定定时初值
}
/*描述该功能...
*/
void set_timer0(uint16 x){
TF0 = 0;
TH0 = (((65535 - x * 2)&0xff00)>>8);
TL0 = ((65535 - x * 2)&0x00ff);
}
/*描述该功能...
*/
uint16 servo_write(uint16 vlaue){
if(vlaue < 0){
vlaue = 0;
}
if(vlaue > 180){
vlaue = 180;
}
vlaue = map(vlaue,0,180,500,2500);
return vlaue;
}
void T_IRQ0(void) interrupt 1 using 1{
flag = !flag;
if(flag == 0){
set_timer0(ticks);
P3_2 = 0;
}
if(flag == 1){
set_timer0(20000 - ticks);
P3_2 = 1;
}
}
void putchar(char c)
{
if (c == '\n')
{
uart_putchar(UART_1, 0x0d);
uart_putchar(UART_1, 0x0a);
} else {
uart_putchar(UART_1, (uint8)c);
}
}
void setup()
{
P3M1&=~0x04;P3M0|=0x04;//推挽输出
Timer0Init();
EA = 1; // 控制总中断
ET0 = 1; // 控制定时器中断
TR0 = 1;// 定时器0开始计时
uart_init(UART_1, UART1_RX_P16, UART1_TX_P17, 9600, TIM_1);//初始化串口
EA = 1;
ES = 1;
ticks = servo_write(180);
OLEDJ_Init();//OLED初始化
OLEDJ_Display_On();//OLED开启显示
adc_init(ADC_P10, ADC_SYSclk_DIV_2, ADC_8BIT);//ADC初始化,三个参数ADC引脚,时钟分频双数2-32,输出值位数12BIT最大分率-12位的ADC输出12位,10位的输出10位
P3M1=0x00;P3M0=0x00;//双向IO口
}
void loop()
{
light = 100 - adc_read(ADC_P10) * 2;
if(light < 0){
light = 0;
}
delay(100);
OLEDJ_show_font16("智能电动窗帘系统",0,0);
OLEDJ_show_font16("光照",0,2);
OLEDJ_ShowString(40,3,(String(numtostr(light), " ")),8);
OLEDJ_show_font16("上限",0,4);
OLEDJ_ShowNum(40,5,light_MAX,8);
if(set2 == 1){
OLEDJ_show_font16("手动模式",0,6);
if(pwmnum == 0){
printf_small("智能电动窗帘系统\r\n光照%d 上限%d \r\n手动模式 关闭\r\n", ((int16)(light)), ((int16)(light_MAX)));
OLEDJ_show_font16("关闭",70,6);
}
else{
printf_small("智能电动窗帘系统\r\n光照%d 上限%d \r\n手动模式 开启\r\n", ((int16)(light)), ((int16)(light_MAX)));
OLEDJ_show_font16("开启",70,6);
}
}
if(set2 == 0){
OLEDJ_show_font16("自动模式",0,6);
if(light > light_MAX){
ticks = servo_write(180);
pwmnum = 1;
OLEDJ_show_font16("开启",70,6);
printf_small("智能电动窗帘系统\r\n光照%d 上限%d \r\n自动模式 开启\r\n", ((int16)(light)), ((int16)(light_MAX)));
}
if(light <= light_MAX){
ticks = servo_write(0);
pwmnum = 0;
OLEDJ_show_font16("关闭",70,6);
printf_small("智能电动窗帘系统\r\n光照%d 上限%d \r\n自动模式 关闭\r\n", ((int16)(light)), ((int16)(light_MAX)));
}
}
if(P3_7 == 0){
set2 = set2 + 1;
if(set2 > 1){
set2 = 0;
}
}
if(P3_6 == 0){
if(set2 == 1){
ticks = servo_write(180);
pwmnum = 1;
}
else{
light_MAX = light_MAX + 1;
}
}
if(P3_5 == 0){
if(set2 == 1){
pwmnum = 0;
ticks = servo_write(0);
}
else{
light_MAX = light_MAX - 1;
}
}
}
void main(void)
{
setup();
while(1){
loop();
}
}