// 智能家居模拟系统-文档
// 2015.12.14 by Huangtao
目前由以下组成:
由 STM32F103系列单片机 + RT-Thread嵌入式实时操作系统 +
串口转WIFI模块 + LED + LCD + L298 + 风扇 + 温度传感器
自定义通信协议:
1、'L' + 控制LED字符(0x11,0x10,0x21...)
2、'F' + 风扇控制符(0xf0,0xf1,0xf2...)
3、'TT',返回温度
手机APP端可以控制LED开关,获取温度,调节风扇转速。
/* application.c 2015.12.4 by Huangtao */ #include <board.h> #include <rtthread.h> #ifdef RT_USING_COMPONENTS_INIT #include <components.h> #endif /* RT_USING_COMPONENTS_INIT */ #ifdef RT_USING_DFS /* dfs filesystem:ELM filesystem init */ #include <dfs_elm.h> /* dfs Filesystem APIs */ #include <dfs_fs.h> #endif #ifdef RT_USING_RTGUI #include <rtgui/rtgui.h> #include <rtgui/rtgui_server.h> #include <rtgui/rtgui_system.h> #include <rtgui/driver.h> #include <rtgui/calibration.h> #endif // 我加入的 #include "led.h" #include "LCD5110.h" #include "ds18b20.h" #include "usart.h" #include "TIM3_PWM.h" // Thread ID static rt_thread_t led_id = RT_NULL; static rt_thread_t fan_id = RT_NULL; static rt_thread_t lcd5110_id = RT_NULL; static rt_thread_t ds18b20_id = RT_NULL; static rt_thread_t uart2_id = RT_NULL; #define CPU_USAGE_CALC_TICK 10 #define CPU_USAGE_LOOP 100 static rt_uint8_t cpu_usage_major = 0; //static cpu_usage_minor= 0; static rt_uint32_t total_count = 0; /* 自定义通信协议: ledControl: 'L'+ 0x10----led1 off 0x11----led1 on 0x20----led2 off 0x21----led2 on ... fanControl: 'F'+ 0xf0----fan off 0xf1----speed 1 0xf2----speed 2 ... */ static short temperature = 0; static char ledControl = 0; static char fanControl = 0; // 访问温度的互斥量 static rt_mutex_t mutexTemperature = RT_NULL; static rt_mutex_t mutexLed = RT_NULL; static rt_mutex_t mutexFan = RT_NULL; // stm32_usart2发送缓冲区 static char uart_tx_buffer[64] = " Open uart2 OK. "; // stm32_usart2接收缓冲区 static char uart_rx_buffer[64]; // USART 接收消息结构 struct rx_msg { rt_device_t dev; rt_size_t size; }; // 用于接收消息的消息队列控制块 static rt_mq_t rx_mq; static struct rt_messagequeue my_rx_mq; // 消息队列中用到的放置消息的内存池 static char msg_pool[1024]; static void cpu_usage_idle_hook() { rt_tick_t tick; rt_uint32_t count; volatile rt_uint32_t loop; if (total_count == 0) { /* get total count */ rt_enter_critical(); tick = rt_tick_get(); while(rt_tick_get() - tick < CPU_USAGE_CALC_TICK) { total_count ++; loop = 0; while (loop < CPU_USAGE_LOOP) loop ++; } rt_exit_critical(); } count = 0; /* get CPU usage */ tick = rt_tick_get(); while (rt_tick_get() - tick < CPU_USAGE_CALC_TICK) { count ++; loop = 0; while (loop < CPU_USAGE_LOOP) loop ++; } /* calculate major and minor */ if (count < total_count) { count = total_count - count; cpu_usage_major = (count * 100) / total_count; //cpu_usage_minor = ((count * 100) % total_count) * 100 / total_count; } else { total_count = count; /* no CPU usage */ cpu_usage_major = 0; //cpu_usage_minor = 0; } } void cpu_usage_init() { /* set idle thread hook */ rt_thread_idle_sethook(cpu_usage_idle_hook); } /* // led ALIGN(RT_ALIGN_SIZE) static rt_uint8_t led_stack[ 512 ]; static struct rt_thread led_thread;*/ static void led_thread_entry(void* parameter) { rt_hw_led_init(); while (1) { rt_mutex_take(mutexLed, RT_WAITING_FOREVER); if(ledControl == 0x11) { // led1 on rt_hw_led_on(0); } else if(ledControl == 0x10) { // led1 off rt_hw_led_off(0); } else if(ledControl == 0x21) { // led2 on rt_hw_led_on(1); } else if(ledControl == 0x20) { // led2 off rt_hw_led_off(1); } rt_mutex_release(mutexLed); // 顺便清屏 //ClearScreen(); rt_thread_delay( 10 ); } } static void fan_thread_entry(void* parameter) { short Compare2Num = 0; TIM3_PWM_Init(900,5); // PWM频率=72000/5/900 while(1) { rt_mutex_take(mutexFan, RT_WAITING_FOREVER); switch(fanControl) { case 0xf0: Compare2Num=0; break; // 关 case 0xf1: Compare2Num=100; break; // 1档 case 0xf2: Compare2Num=150; break; // 2档 case 0xf3: Compare2Num=200; break; // ... case 0xf4: Compare2Num=250; break; case 0xf5: Compare2Num=300; break; case 0xf6: Compare2Num=350; break; case 0xf7: Compare2Num=400; break; case 0xf8: Compare2Num=450; break; case 0xf9: Compare2Num=500; break; case 0xfa: Compare2Num=600; break; case 0xfb: Compare2Num=700; break; case 0xfc: Compare2Num=800; break; case 0xfd: Compare2Num=900; break; // 13档 default: break; } rt_mutex_release(mutexFan); TIM_SetCompare2(TIM3, Compare2Num); rt_thread_delay(10); } } // lcd5110 static void lcd5110_thread_entry(void* parameter) { LcdInit(); while(1) { DispString(15,0,"RT-Thread"); DispString(0,1,"CPU:"); DispNum(30,1,cpu_usage_major); DispChar(45,1,'%'); rt_thread_delay( 5 ); } } // ds18b20 static void ds18b20_thread_entry(void* parameter) { short showTemp; //rt_err_t result; while(DS18B20_Init()); while(1) { DispString(0,3,"Temp: "); rt_mutex_take(mutexTemperature, RT_WAITING_FOREVER); temperature = DS18B20_Get_Temp(); showTemp = temperature; rt_mutex_release(mutexTemperature); if(showTemp<0) { DispChar(40,3,'-'); showTemp=-showTemp; } else DispChar(40,3,' '); DispNum(48,3,((u16)showTemp)/10); //显示正数部分 DispChar(60,3,'.'); DispNum(67,3,((u16)showTemp)%10); //显示小数部分 rt_thread_delay( 5 ); } } // uart2 //=============================================== // 数据到达回调函数 // rt_err_t(*)(rt_device_t dev, rt_size_t size) rt_err_t uart_input(rt_device_t dev, rt_size_t size) { struct rx_msg msg; msg.dev = dev; msg.size = size; if(size >=2) { // 发送消息到消息队列中 rt_mq_send(rx_mq, &msg, sizeof(struct rx_msg)); } return RT_EOK; } static void uart2_thread_entry(void* parameter) { rt_err_t result = RT_EOK; struct rx_msg msg; rt_device_t stm32_uart2; rt_uint32_t rx_length; // 根据注册名查找设备 stm32_uart2 = rt_device_find("uart2"); if (stm32_uart2 != RT_NULL) { // 初始化设备 rt_device_init(stm32_uart2); // 设置回调函数(当设备接收到数据执行) rt_device_set_rx_indicate(stm32_uart2, uart_input); // 打开设备 rt_device_open(stm32_uart2, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM); } rt_device_write(stm32_uart2, 0, &uart_tx_buffer[0], 18); while(1) { // 从消息队列中读取消息, RT_WAITING_FOREVER result = rt_mq_recv(rx_mq, &msg, sizeof(struct rx_msg), RT_WAITING_FOREVER); // 成功收到消息 if(result == RT_EOK) { rx_length = (sizeof(uart_rx_buffer) - 1) > msg.size ? msg.size : sizeof(uart_rx_buffer) - 1; // 读取消息 rx_length = rt_device_read(msg.dev, 0, &uart_rx_buffer[0], rx_length); uart_rx_buffer[rx_length] = '