打印
[STM32F1]

基于STM32芯片的一款智能台灯

[复制链接]
21868|186
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 junpeng324 于 2017-11-12 22:43 编辑

前段时间参加了全国大学生智能互联创新大赛,我们队伍经过半个月的努力做了一款智能台灯,特分享出来供大家学习。优酷演示链接如下 http://v.youku.com/v_show/id_XMjk0OTU2NDA5Mg==.html?spm=a2hzp.8244740.0.0

2.jpg (393.91 KB )

2.jpg

人体感应.rar

1.19 KB

iic.rar

1.54 KB

光照强度模块BH1750.rar

953 Bytes

机智云底层驱动.rar

19.49 KB

旋钮调节.rar

1.17 KB

评分
参与人数 1威望 +5 收起 理由
一路向北lm + 5 赞一个!
来自 2楼
junpeng324|  楼主 | 2017-11-7 22:00 | 只看该作者
智能台灯侧面图

3.jpg (360.83 KB )

3.jpg

使用特权

评论回复
来自 3楼
junpeng324|  楼主 | 2017-11-7 22:00 | 只看该作者
智能台灯整体图

4.jpg (384.07 KB )

4.jpg

使用特权

评论回复
来自 4楼
junpeng324|  楼主 | 2017-11-7 22:02 | 只看该作者
智能台灯俯视图

5.jpg (208.82 KB )

5.jpg

使用特权

评论回复
来自 5楼
junpeng324|  楼主 | 2017-11-7 22:06 | 只看该作者
本帖最后由 junpeng324 于 2017-11-7 22:08 编辑

作品简介
     随着时代的进步人们对灯的要求也越来越多,台灯是普遍的家用照明设备之一,为了结合国家的节能环保计划以及产品人性化的要求,我们团队研发出了一种多功能用途台灯,将智能与节能环保最大化结合。该智能台灯基于多种模块的相互配合,融入了团队智能环保的设计理念,以及人性化的宗旨使“她”可以更加贴心的照顾我们对灯光的需求。智能灯光调节的设计使她拥有最大化保护用户视力的强大功能,通过我们团队特制的手机APP用户可以随心所欲的对她进行远程监控,本智能台灯强大的外设模块使它可以实时获取工作时间、外部环境温湿度、光照强度、可燃气体的数据,并将数据实时显示在手机APP页面端让用户可以实时了解近期工作时间,并掌控外界环境的各种变化。同时语音识别控制和无极调光功能的嵌入更加灵敏化了“她”的可操作性。自动调光模式在不同的时间可以通过获取外界环境来自动调整灯光亮度,有利于节能环保。坐姿纠正功能的实现使得用户能够养成良好的学习工作习惯并保护视力。手速调光的新挑战赋予“她”与众不同的亮点,通过手势扫描的速度来调节灯光亮度,在调节灯光的时候还能给用户体验速度的乐趣,让台灯的使用变得更加便捷、有趣。产品智能化、物联化、人性化的设计将带您进入智能家居的美好生活。

使用特权

评论回复
来自 6楼
junpeng324|  楼主 | 2017-11-7 22:09 | 只看该作者
研究背景
随着现代科学技术的不断发展,生活用品的智能化程度也越来越普及,人们对一些家居物品的人性化、智能化设计要求也越来越高。众所周知台灯作为家庭主要照明工具之一,在现代社会生活中占有重要地位,而且台灯的应用范围非常广泛,适用于各年龄阶段的人群,因此它的市场应用性非常高,具有很好的发展前景。随着青少年近视问题越来越严重,家长越来越重视孩子的视力保护,这使得“无频闪、无眩光”的“护眼台灯”越来越受到家长们的青睐。然而实际上,市面上很多护眼台灯虽然声称“无频闪”,但只是“高频闪”而已。这种更高频的频闪,对眼睛的伤害更大,因为眼睛要非常快速地根据灯光闪动作出反应,长时间使用此种台灯,眼睛更容易疲劳,对视力造成一定伤害。真正无频闪的台灯应该是使用直流电恒流驱动的LED作为发光源,所以本次我们采用的便是 LED灯作为发光源。
如果台灯仅仅具有这些功能,未免太缺乏实用性和创新性。因此,我们通过调查和学习,了解到很多人希望台灯有一些特殊功能,例如:能够通过外界光照自动调节亮度、能够对周边环境检测、能够用手机远程控制台灯、能够让台灯拥有多种工作模式、能够对有害气体的预警、能够让害怕黑夜的孩子晚上安稳入睡等。还有很多生活中我们常常会遇到的问题。一切产品的最终目标都是为人类服务,所以我们团队决定此次比赛我们致力于解决在智能家居类普遍存在的问题,我们也希望通过这次学习能够更好地为人们生活带来便捷,更大程度的实现台灯的人性化、智能化,满足未来智能家居的要求。

使用特权

评论回复
来自 7楼
junpeng324|  楼主 | 2017-11-7 22:10 | 只看该作者
研究目的
     创新来源于生活,一切有价值的创造都将用于提高人们的生活品质。随着现代化社会的不断发展智能物联一体化的创新方向得到了特别的重视,这些方面人们善于开发思想敢于创新,加快了智能化产品的快速发展。台灯作为生活中必不可少的家居用品之一在人们的生活中起着非常重要的作用,尤其对于学生、儿童。但市面上的台灯规格不一种类繁多,为了满足大多数人们的生活要求,我们开始研究了一款符合大众的智能台灯。在一些硬件模块的结合以及一些开发平台的帮助之下让它更具“思想”,能够满足大多数人对于台灯的期望值。
眼睛是人们心灵的窗户,因此,很多人希望台灯能够很好的保护我们的眼睛。所以借助本次大赛的平台我们团队决定做一款多功能的台灯。当然护眼是它的主要功能之一,我们决定采用直流电恒流驱动的LED作为发光源,以减少频闪对人眼的伤害,同时我们采用光照感应模块采集台灯周围环境亮度用来调节灯光自身亮度减少亮度差。我们通过在身边同学的调查得出很多同学希望现代台灯能够等多的拥有科技感时代感,因此在现在智能化,物联化快速发展的今天我们决定用手机APP远程控制台灯,在APP页面上我们做了很多人性化的设计,比如:模式选择功能、远程控制开关、语音开关、亮度调节、温度时间、工作数据显示等一些好玩的功能。这样的设计一是为了满足现代人对于产品智能化的要求,另一个则是物品人性化设计的理念,更好地提高人们的生活质量。手势调节灯光亮度在现代社会中还没有发展成熟,本次我们努力尝试探索以手速快慢等特定条件来调节灯光强弱,使台灯更具科技感。在现实生活中很多小孩子在早期学习中不能养成良好的坐姿,本次比赛中我们试着实现坐姿纠正的功能,用于培养小孩子的正确坐姿养成良好的学习习惯。还有一些人夜晚睡觉害怕黑暗,所以我们此次加入了小夜灯模式,用几个蓝色发光二极管来发出美丽的蓝光,帮助用户安稳入眠。

使用特权

评论回复
来自 8楼
junpeng324|  楼主 | 2017-11-7 22:14 | 只看该作者
模块设计图示:

6.png (427.21 KB )

6.png

使用特权

评论回复
来自 9楼
junpeng324|  楼主 | 2017-11-7 23:21 | 只看该作者
功能分布图:


7.png (396.42 KB )

7.png

使用特权

评论回复
来自 10楼
junpeng324|  楼主 | 2017-11-7 23:23 | 只看该作者
本帖最后由 junpeng324 于 2017-11-7 23:25 编辑

硬件设计之一:
首先考虑到台灯的设计理念要更好地符合智能化、人性化、多功能化的要求,我们使用STM32F401Nucleo作为主控开发板以及Android Studio为软件APP开发平台,同时我们参考研究了很多公司的资料,在这些平台上我们学习了更多的知识,下面介绍一下我们作品的硬件设计流程方案。
1、台灯的外观设计方面,由于外观制作不易成型演示效果不好,所以本次台灯外观选择了在旧台灯上进行改造,使达到废物利用创新节能的作用。该台灯有一个可以弯曲的台柱用于调节光照范围,使得它的实用性更好,同时我们采用了节能护眼的LED灯作为光源,并自己动手进行主灯的焊接工作。
2、设计中使用ST公司的STM32F401Nucleo开发板为主控核心板,并在Android平台下进行手机软件的开发,为了解决硬件与软件的通信,选用了ESP8266wifi模块。ESP8266是上海乐鑫信息科技设计的低功耗wifi芯片,集成完整的TCP/IP协议栈和MCU。而ESP8266模块是深圳安信可公司基于ESP8266芯片研发(增加必要外围电路、串口flash、板载天线等)的串口wifi模块,成本低、使用简便、功能强大。

使用特权

评论回复
来自 11楼
junpeng324|  楼主 | 2017-11-7 23:26 | 只看该作者
硬件电路之二:
    3、在Android studio软件开发平台上编写了名为“智能台灯”的手机APP。实现台灯的远程监控功能,该应用主页面上有多种灯光模式选择功能,同时具有进度条调节灯光亮度、显示当前温湿度、光强度、时间定时开关、语音开关以及工作数据显示等,方便用户的更多生活需求。在后续的实物照片及演示过程中我们会详细介绍。
4、对于无极调光这一方面采用了电容式触摸模块。电容式触摸模块通常广泛适用于遥控器、灯具调光、各类开关以及车载、小家电和家用电器控制界面等应用中。单线触摸,利用电容触摸原理,感应灵敏触手可即。默认是具有开关功能、调光功能、带亮度**渐明渐暗的LED触摸无级调光功能。开灯时慢慢变亮,关灯时慢慢变暗,有效避免了对眼睛的刺激。同时能过通过触摸时间的长短进行光照亮度的调节,总有一种亮度适合您。

使用特权

评论回复
来自 12楼
junpeng324|  楼主 | 2017-11-8 22:39 | 只看该作者
本帖最后由 junpeng324 于 2017-11-8 22:40 编辑

硬件电路之三:
5、HC-SRO4超声波模块。超声波测距模块一般有发射、接收和信号处理三个部分。工作时超声波发射器只需要在触发端给一个至少10微秒的高电平信号,它就会自动发送8个40KHz的方波,自动检测是否有返回的信号。用超声波模块主要用于纠正坐姿需要,我们会通过超声波的测距功能来时刻提醒用户在工作学习时要保持正确的坐姿,一旦用户坐姿偏差太大台灯将会发出报警提醒声,让用户培养良好的坐姿习惯。
6、人体热释电探头。用人体热释电模块能够实时检测到是否有人经过,如果有返回信号则台灯自动开启,能够方便用户第一时间的使用并可以记录入座时间及时给予反馈信息提醒。同时有利于用户的夜间使用,当感应到有人经过它便会自动开灯,方便夜间人们的生活且不影响家人的正常休息。对于害怕黑夜的人来说台灯夜间有一个小夜灯模式,能够让用户安心入睡,保障更好地睡眠质量。我们还运用四个热释电探头做了一个手势控制台灯亮度的功能,通过手速的快慢及方向来改变灯光亮灭。

使用特权

评论回复
来自 13楼
junpeng324|  楼主 | 2017-11-8 22:41 | 只看该作者
硬件电路之四:
7、DHT11温湿度模块。DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,使其成为同类应用场合的最佳选择。所以此次我们选择了这一模块用来实时监测台灯周围的环境变化,用于给用户提供更加健康、舒适的工作学习环境。
8、MQ-2烟雾、甲烷、液化气、可燃气模块。MQ-2气体传感器对液化气、丙烷、氢气的灵敏度高,对天然气和其它可燃蒸汽的检测也很理想。这种传感器可检测多种可燃性气体,是一款适合多种应用的低成本传感器。现在家庭很多在使用天然气、煤气,在为人们生活提供方便的同时,但也存在着一些安全隐患。因此,我们采用该模块对家庭室内环境实时检测,也是为了给用户提供更加安全健康的生活场所。

使用特权

评论回复
来自 14楼
junpeng324|  楼主 | 2017-11-8 22:44 | 只看该作者
硬件电路之五:
9、时钟显示PCF8563模块。PCF8563是低功耗的CMOS实时时钟日历芯片它提供一个可编程时钟输出一个中断输出和掉电检测器所有的地址和数据通过I2C总线接口串行传递最大总线速度为400Kbits/s每次读写数据后内嵌的字地址寄存器会自动产生增量。该模块为我们获取实时时间提供了保障,可以使手机APP页面端实时更新数据提供可靠地时间参考依据。
通过以上模块的协作,我们将各模块收集的数据上传至云端与手机APP之间进行打通连接,让这台台灯拥有了“思想”,它能尽可能多的满足人们的生活需求,提高人们的生活质量,同时适应科技创新、智能化、物联化、未来化的发展方向,为智能家居的发展注入了了新的活力。

使用特权

评论回复
来自 15楼
junpeng324|  楼主 | 2017-11-8 22:51 | 只看该作者
APP软件设计(局部)
/**
    * 发送指令,下发单个数据点的命令可以用这个方法
    * 注意
    * 下发多个数据点命令不能用这个方法多次调用,一次性多次调用这个方**导致模组无**确接收消息,参考方法内注释。
    *
    * @param key   数据点对应的标识名
    * @param value 需要改变的值
    */
   public static void sendCommand(String key, Object value) {
       if (value == null) {
           return;
       }
       int sn = 5;
       ConcurrentHashMap<String, Object> hashMap = newConcurrentHashMap<String, Object>();
       hashMap.put(key, value);
       // 同时下发多个数据点需要一次性在map中放置全部需要控制的keyvalue
        // hashMap.put(key2, value2);
       // hashMap.put(key3, value3);
       mDevice.write(hashMap, sn);
       Log.i("liang", "下发命令:" + hashMap.toString());
}
[size=21.3333px]  

  


使用特权

评论回复
来自 16楼
junpeng324|  楼主 | 2017-11-8 22:53 | 只看该作者
APP软件设计(局部)
/**
*更新界面数据显示
**/
    protected void updateUI() {
        myPowerCheckBox.setChecked(Lamp_Power);
       myAutoCheckBox.setChecked(Lamp_Auto_Control);
        tv_data_Lamp_Size.setText(Lamp_Size +"");
        sb_data_Lamp_Size.setProgress((int)((Lamp_Size - LAMP_SIZE_ADDITION) / LAMP_SIZE_RATIO - LAMP_SIZE_OFFSET));
        tv_data_Today_Humidity.setText("湿度:" + Today_Humidity +"");
        tv_data_Today_Temp.setText(Today_Temp +"°C");
       tv_data_lamp_illumination.setText("光强度:" + Light_Intensity);
       tv_data_have_CombustibleGas.setText((Have_CombustibleGas) ? "有可燃气体" : "无可燃气体");
       tv_data_sitting_posture.setText((Sitting_Posture) ? "坐姿正确" : "坐姿不正确");
        HashMap<String, String>HMSataHashMap = DateTimeUtils.getIntTimeToHMS(Now_Time);
       tv_data_time.setText(HMSataHashMap.get("h") + ":" +HMSataHashMap.get("m"));
        initViewPager();
        HashMap<String, Double>stringDataHashMap = new HashMap<>();
       stringDataHashMap.put("Today_Study", Today_Study);
        stringDataHashMap.put("Last1day_Study",Last1day_Study);
       stringDataHashMap.put("Last2day_Study", Last2day_Study);
       stringDataHashMap.put("Last3day_Study", Last3day_Study);
       stringDataHashMap.put("Last4day_Study", Last4day_Study);
        stringDataHashMap.put("Last5day_Study",Last5day_Study);
       stringDataHashMap.put("Last6day_Study", Last6day_Study);
        //设置温度折线图
       studyTimeContentPager.setData(stringDataHashMap, Today_Date);
        /**
         * 如果灯关了,强制顶部图片最暗
         */
        if (Lamp_Power)setTopLampLight(Lamp_Size);
        else setTopLampLight(-255);
    }

使用特权

评论回复
来自 17楼
junpeng324|  楼主 | 2017-11-8 22:55 | 只看该作者
STM32硬件代码(局部)


1.png (46.89 KB )

1.png

使用特权

评论回复
来自 18楼
junpeng324|  楼主 | 2017-11-9 23:08 | 只看该作者
APP页面:局部图 灯光控制主界面


1.png (123.48 KB )

1.png

使用特权

评论回复
来自 19楼
junpeng324|  楼主 | 2017-11-9 23:14 | 只看该作者
APP时钟设置界面图,可以通过APP来控制台灯上面的数码管时钟实现网络时间的同步与时间调节。

2.png (215.66 KB )

2.png

使用特权

评论回复
来自 20楼
junpeng324|  楼主 | 2017-11-9 23:16 | 只看该作者
设置日期和时间界面图

3.png (248.94 KB )

3.png

使用特权

评论回复
来自 21楼
junpeng324|  楼主 | 2017-11-9 23:18 | 只看该作者
APP智能台灯模式选择界面图

4.png (142.91 KB )

4.png

使用特权

评论回复
来自 22楼
junpeng324|  楼主 | 2017-11-10 10:43 | 只看该作者
创新点
现如今社会LED灯以高节能,长寿命,促环保的优点在社会上面占据着强大的市场,也因此是大家关注的焦点。这几年高亮度的LED光源因科技的迅速发展,制作技术方面突飞猛进,同时造价成本的降低,如今台灯得以使用LED光源作为高亮度,高效率而又省电无碳排放的节能光源。
团队秉持着创新智能、简约实用为主题来设计这款台灯。台灯在现如今的生活比重越来越重,社会大众对台灯的功能要求也越来越高,为适应更加宽广的人群要求,我们在这款设计方面加入了许多新颖的创新理念和设计要求:
1、用手机APP实现对台灯进行远程监控,使用方便并可以实时了解家庭环境的最新情况;
2、自动调光、语音调光、手动调光时刻为了您的方便与快捷作出努力;
3、手势调节光照亮度,通过扫描手速的快慢与方向来改变光亮;
4、对于坐姿的纠正有一定帮助,可以使您培养良好的坐姿习惯,促进身体健康;
5、久坐提醒、定时提醒、小夜灯等为您的健康生活提供便利和保障。

科学技术是第一生产力,创新是科技不断进步的力量源泉。创新要更好地服务于人类的生活,提高人们的生活水平,我们的创新想法是来自于人们生活中的真实需要,我们努力用所学的知识去创造价值,用求知的心态去探索世界,每一次小小的进步都是我们不断前行的动力,我们热爱着生活、我们热爱着科学、我们热爱着无限的创造力。

使用特权

评论回复
来自 23楼
junpeng324|  楼主 | 2017-11-10 10:45 | 只看该作者
实用性
我们的智能台灯,与其他台灯相比智能化设计理念优势较为明显。现如今,智能、节能、环保产品不断出现在大众眼前,科技的快速发展也让越来越多的物品变得智能化、简单化。普通台灯或者说家居产品都将会面临着改革的**,这是一个趋势,也是一个必然现象。现就我们的作品功能分析来说它在现实生活中具有以下实用性:
1、信息化的快速发展让我们的生活变得近在矩尺,一切事情好像都能够通过一个手机来完成,手机成为了我们生活中必不可少的物品。所以,我们给台灯配备了APP连接,通过手机APP页面端我们可以对台灯进行一些特殊的操作,使远在其它地方的您可以随时控制它。
2、在手机APP页面端我们不单单设置有开关功能,还设置了语音调节、进度条调节、多种工作模式选择功能,操作简单易于上手。我们的台灯还可以通过外界光照强度来调整自身亮度,通过不同形式的灯光调节来保护您的眼睛,给你一个舒适的学习工作环境。
3、APP页面端还可以通过台灯实时收集到您的入座时间、周围温湿度、光强度、可燃气体等数据,并将这些数据显示在APP页面端,让您能在千里之外就能对家里的环境了如指掌,随时作出应对准备,还可以查看近一周的工作时间数据,对台灯的使用情况有所了解。
4、在事务缠身想要通过阅读读物放松身心或者睡前阅读一些**又怕沉迷书海不能自拔的时候,您可以通过手机APP页面端对小台灯进行定时关灯,在约定时间结束的时候会通过自动关闭台灯来提醒您该要工作或者休息了,这弥补了我们经常遗忘时间的通病。
5、孩子的学习是我们每个家庭特别关注的问题。学习的同时孩子学习的坐姿也是家长们头疼的难题。孩子们在学习的时候不经意间就会弯腰趴在桌子上面长时间下来对孩子的身体骨骼发育会造成较大的影响,同时近距离学习对眼睛的伤害也会特别的严重。我们的台灯设计上面考虑到这个问题,所以我们添加了坐姿纠正的功能。利用超声波模块通过使用者与台灯的距离远近判断是否存在坐姿偏差,如果您的身体严重倾斜或下趴,台灯将自动熄灭以此来提醒使用者纠正坐姿。
6、我们的产品可以根据手势和无极调光来实现灯光控制。在台灯的上面有4个传感器,当我们的手势在上面快速通过的时候,小台灯的亮度会从最暗直接增加到最亮,如果您的手势缓慢通过的时候我们的小台灯会缓慢变亮,这跟我们台灯上面的实现无极功能的4次指纹按键实现相同的功能------无极调光。第一次指纹按键在上面的时候灯光会由暗缓慢的变到最亮;第二次指纹按键时间在第一次灯变换的过程中时,小台灯直接调到最大亮度;第三次指纹按键会实现小台灯的灯光从最亮缓慢转化到最暗直至灯熄灭;第四次指纹按键时间在第三次灯光变化过程中时,小台灯直接熄灭。这就是我们的无极调光功能的实现过程。
总的来说,我们所有的思想设计都是为了改善我们的生活质量,提高我们的生活水平。每一项功能都尽可能多的为用户提供便利,符合现代化社会人们对商品的要求。

使用特权

评论回复
来自 24楼
junpeng324|  楼主 | 2017-11-10 10:56 | 只看该作者
关于智能台灯程序部分:1.手动模式与自动模式的切换 ,可以通过按键或者APP端来控制自动模式与手动模式的切换。




1.png (76.13 KB )

1.png

使用特权

评论回复
来自 25楼
junpeng324|  楼主 | 2017-11-11 22:20 | 只看该作者
自动模式1:通过获取外界的光线值来实现台灯的自动调节。


1.png (109.87 KB )

1.png

使用特权

评论回复
来自 26楼
junpeng324|  楼主 | 2017-11-11 22:25 | 只看该作者
手动模式:在手动模式下可以通过旋钮,APP和手势控制装置实现台灯的控制。


3.png (104.93 KB )

3.png

使用特权

评论回复
来自 27楼
junpeng324|  楼主 | 2017-11-11 22:28 | 只看该作者
代码部分:模式的切换
void mode()             //通过APP和按键来选择自动和手动模式
{       
       
            shoushi_dat();                       
      shoushi_deal();  //手势控制灯光
                if(mode_flag==1)     //自动模式
                {
      renti_deal();    //人体感应控制灯光
                }
                else                //手动模式下完成app与手势感应控制灯光过程
                {

                   led_deal();      //app控制灯
                         shoushi_dat();                       
       shoushi_deal();  //手势控制灯光       
    }
}

使用特权

评论回复
来自 28楼
junpeng324|  楼主 | 2017-11-11 22:32 | 只看该作者
人体感应部分代码,实现了台灯的自动控制(有乱码)
#include "renti.h"
u8 start_job_flag,day_falg;
extern u16 hour;
extern float lx;
void renti_init()   //手势初始化
{
  GPIO_InitTypeDef GPIO_InitStructure;          //声明一个结构体变量,用来初始化GPIO

        /* 开启GPIO时钟 */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);

/*  配置GPIO的模式和IO口 */
        GPIO_InitStructure.GPIO_Pin=renti|gd;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;         //上拉输入
        GPIO_Init(GPIOD,&GPIO_InitStructure);
}
void renti_deal()  //人体感应
{
        if((hour>=8)&&(hour<=17))    //白天
        {
          day_falg=1;
        }
        if((hour>17)&&(hour<=22))    //工作时间
        {
          day_falg=2;
        }
        if((hour>22)&&(hour<24))    //休息时间
        {
         day_falg=3;
        }
        if((hour>=0)&&(hour<8))     //休息时间
        {
         day_falg=3;
        }
        if((RT==1)|(GD==0))  //人经过或者来学习是灯根据时间光照值来调节
        {

    switch(day_falg)
                 {
                   case 1:   TIM_SetCompare1(TIM5, 0);        break;   //白天关灯
                         case 2:   
                                         //工作时间根据光照值对灯光进行调节
                                  if(lx>2000)
                                                                {
                                                                 TIM_SetCompare1(TIM5, 0);   
                                                                }
                                                                else
                                                                {
                                                                        if((lx>2000))
                                                                        {
                                                                         TIM_SetCompare1(TIM5, 0);
                                                                        }
                                                                        if((lx<=2000)&&(lx>1000))
                                                                        {
                                                                         TIM_SetCompare1(TIM5, 100);
                                                                        }
                                                                        if((lx<=1000)&&(lx>500))
                                                                        {
                                                                         TIM_SetCompare1(TIM5, 500);
                                                                        }
                                                                        if((lx<=500)&&(lx>300))
                                                                        {
                                                                         TIM_SetCompare1(TIM5, 1000);
                                                                        }
                                                                  if((lx<=300)&&(lx>100))
                                                                        {
                                                                         TIM_SetCompare1(TIM5, 1500);
                                                                        }
                                                                        if((lx>0)&&(lx<=100))
                                                                        {
                                                                          TIM_SetCompare1(TIM5, 2000);
                                                                        }
                                                                }   
                                                                break;
                         case 3:    //休息时间也根据光照值对灯光进行调节
                                           
                TIM_SetCompare1(TIM5, 800);
                break;
                   }
  }
        if(GD==0)    //开始学习
        {
          start_job_flag=1;
        }
        if(GD==1)    //结束学习
        {
         start_job_flag=0;
        }
        if((start_job_flag==0)&&(RT==0))  //人离开短暂延时灯灭
        {
          led_off();  //关灯
        }
}


使用特权

评论回复
来自 29楼
junpeng324|  楼主 | 2017-11-11 22:39 | 只看该作者
亮度的测量我们用到了BH1750 基于I2C的模块,下面是I2C的驱动程序
#include "iic.h"

void iic_init(void)
{
        /*****配置GPIO口**************************************/
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOIIC, ENABLE);

        GPIO_InitStructure.GPIO_Pin=IIC_SCL_Pin|IIC_SDA_Pin;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
       
        GPIO_Init(GPIO_IIC, &GPIO_InitStructure);       
       
        /********将IIC的 SCL SDA 上拉释放总线******************/
        SDA_PIN_OUT=1;
        SCL_PIN_OUT=1;
}
/*
函数名:iic_start
功  能:启动iic,启动方式,在SCL高电平期间将SDA由高置低
参  数:无
返回值:无
*/
void iic_start(void)
{
        IIC_SDA_OUT();
        SDA_PIN_OUT=1;
        SCL_PIN_OUT=1;
        delay_us(1);
        SDA_PIN_OUT=0;
        delay_us(1);
        SCL_PIN_OUT=0;
}
/*
函数名:iic_stop
功  能:停止传输数据,实现方式在SCL高电平期间将SDA由低置高
参  数:无
返回值:无
*/
void iic_stop(void)
{
       
  SCL_PIN_OUT=0;
        IIC_SDA_OUT();       
        SDA_PIN_OUT=0;
        delay_us(1);
        SCL_PIN_OUT=1;
        SDA_PIN_OUT=1;
        delay_us(1);
}
/*
函数名:iic_ack
功  能:接收从机应答信号,释放掉总线读取SDA置看是否有负脉冲,
        当一段时间无应答默认接收完毕
参  数:无
返回值:无
*/
u8 iic_wait_ack(void)
{
        u8 i=0;
        IIC_SDA_IN();
    SDA_PIN_OUT=1;delay_us(1);
        SCL_PIN_OUT=1;delay_us(1);
        while(SDA_PIN_IN)
        {
                i++;
                if(i>250)
                {               
            iic_stop();                        //如果i>255则产生非应答信号,iic停止
                        return 1;
                }
               
        }
        SCL_PIN_OUT=0;//时钟输出0
        return 0;
}
/*
函数名:iic_nask
功  能:产生非应答信号
参  数:无
返  回:无
*/
void iic_nack(void)
{
        SCL_PIN_OUT=0;
        IIC_SDA_OUT();
        SDA_PIN_OUT=1;
        delay_us(1);
        SCL_PIN_OUT=1;
        delay_us(1);
        SCL_PIN_OUT=0;
}       
/*
函数名:iic_ask
功  能:产生ask应答
参  数:无
返  回:无
*/
void iic_ack(void)
{
        SCL_PIN_OUT=0;
        IIC_SDA_OUT();
        SDA_PIN_OUT=0;
        delay_us(1);
        SCL_PIN_OUT=1;
        delay_us(1);
        SCL_PIN_OUT=0;
}
/*
函数名:iic_bit_write
功  能:传送一个字节
参  数:u8
返回值:无
*/
void iic_byte_write(u8 buf)
{
    u8 i;
        IIC_SDA_OUT();
        SCL_PIN_OUT=0;
        for(i=1;i<=8;i++)
        {
                SDA_PIN_OUT=(buf>>(8-i))&0x01;
                delay_us(1);
                SCL_PIN_OUT=1;
                delay_us(1);
                SCL_PIN_OUT=0;
                delay_us(1);               
        }
}
/*
函数名:iic_bit_read
功  能:主机读取一个字节
参  数:ask
返回值:
*/
u8 iic_byte_read(unsigned char ask)
{
        unsigned char  i,buf=0;
        IIC_SDA_IN();
        for(i=0;i<8;i++)
        {
           SCL_PIN_OUT=0;
           delay_us(1);
           SCL_PIN_OUT=1;
           buf <<=1;
           if(SDA_PIN_IN)
                   buf++;
            delay_us(1);
        }
        if(!ask)
                iic_nack();
        else
                iic_ack();
        return buf;
}


使用特权

评论回复
来自 30楼
junpeng324|  楼主 | 2017-11-11 22:43 | 只看该作者
BH1750需要的头文件
#ifndef __BH1750__H_
#define __BH1750__H_
#include "stm32f10x.h"
#include "iic/iic.h"
#include "sys/sys.h"
#include "delay/delay.h"
/*************************************************************/

#define BHAddWrite     0x46      //从机地址+最后写方向位
#define BHAddRead      0x47      //从机地址+最后读方向位
#define BHPowDown      0x00      //关闭模块
#define BHPowOn        0x01      //打开模块等待测量指令
#define BHReset        0x07      //重置数据寄存器值在PowerOn模式下有效
#define BHModeH1       0x10      //高分辨率 单位1lx 测量时间120ms
#define BHModeH2       0x11      //高分辨率模式2 单位0.5lx 测量时间120ms
#define BHModeL        0x13      //低分辨率 单位4lx 测量时间16ms
#define BHSigModeH     0x20      //一次高分辨率 测量 测量后模块转到 PowerDown模式
#define BHSigModeH2    0x21      //同上类似
#define BHSigModeL     0x23      // 上类似
/*************************************************************/
void bh_data_send(u8 command);
u16 bh_data_read(void);
void bh1750_init(void);
float read_lx(void);
#endif


使用特权

评论回复
来自 31楼
junpeng324|  楼主 | 2017-11-12 22:35 | 只看该作者
#include <stdio.h>
#include <string.h>
#include "Hal_Usart/hal_uart.h"
#include "gizwits_protocol.h"
#include "public/public.h"


/**@} */
/**@name Gizwits 用户API接口
* @{
*/
extern dataPoint_t currentDataPoint;
/**
* @brief 事件处理接口

* 说明:

* 1.用户可以对WiFi模组状态的变化进行自定义的处理

* 2.用户可以在该函数内添加数据点事件处理逻辑,如调用相关硬件外设的操作接口

* @param[in] info : 事件队列
* @param[in] data : 协议数据
* @param[in] len : 协议数据长度
* @return NULL
* @ref gizwits_protocol.h
*/
int8_t gizwitsEventProcess(eventInfo_t *info, uint8_t *data, uint32_t len)
{
  uint8_t i = 0;
  dataPoint_t *dataPointPtr = (dataPoint_t *)data;
  moduleStatusInfo_t *wifiData = (moduleStatusInfo_t *)data;
  protocolTime_t *ptime = (protocolTime_t *)data;

  if((NULL == info) || (NULL == data))
  {
    return -1;
  }

  for(i=0; i<info->num; i++)
  {
    switch(info->event)
    {
      case EVENT_LAMP_POWER:
        currentDataPoint.valueLamp_Power = dataPointPtr->valueLamp_Power;
        GIZWITS_LOG("Evt: EVENT_LAMP_POWER %d \n", currentDataPoint.valueLamp_Power);
        if(0x01 == currentDataPoint.valueLamp_Power)
        {
          //app    开灯命令
                                        led_app_flag=1;
                                  led_flag=1;
                                       
        }
        else
        {
          //app    关灯命令
                                        led_app_flag=1;
          led_flag=0;                       
        }
        break;
      case EVENT_LAMP_AUTO_CONTROL:
        currentDataPoint.valueLamp_Auto_Control = dataPointPtr->valueLamp_Auto_Control;
        GIZWITS_LOG("Evt: EVENT_LAMP_AUTO_CONTROL %d \n", currentDataPoint.valueLamp_Auto_Control);
        if(0x01 == currentDataPoint.valueLamp_Auto_Control)
        {
          //app模式切换   自动模式
                                        mode_flag=1;
                                }
        else
        {
          //手动模式
                                        mode_flag=0;
                                }
        break;
      case EVENT_POLE_SWITCH:
        currentDataPoint.valuePole_Switch = dataPointPtr->valuePole_Switch;
        GIZWITS_LOG("Evt: EVENT_POLE_SWITCH %d \n", currentDataPoint.valuePole_Switch);
        if(0x01 == currentDataPoint.valuePole_Switch)
        {
          //user handle
        }
        else
        {
          //user handle   
        }
        break;
      case EVENT_HUMAN_BODY_SWITCH:
        currentDataPoint.valueHuman_Body_Switch = dataPointPtr->valueHuman_Body_Switch;
        GIZWITS_LOG("Evt: EVENT_HUMAN_BODY_SWITCH %d \n", currentDataPoint.valueHuman_Body_Switch);
        if(0x01 == currentDataPoint.valueHuman_Body_Switch)
        {
          //user handle
        }
        else
        {
          //user handle   
        }
        break;
      case EVENT_TIMING_SWITCH:
        currentDataPoint.valueTiming_Switch = dataPointPtr->valueTiming_Switch;
        GIZWITS_LOG("Evt: EVENT_TIMING_SWITCH %d \n", currentDataPoint.valueTiming_Switch);
        if(0x01 == currentDataPoint.valueTiming_Switch)
        {
          //user handle
        }
        else
        {
          //user handle   
        }
        break;


      case EVENT_LAMP_SIZE:
        currentDataPoint.valueLamp_Size = dataPointPtr->valueLamp_Size;
        GIZWITS_LOG("Evt:EVENT_LAMP_SIZE %d\n",currentDataPoint.valueLamp_Size);

                          //app 调光标志位
                          led_app_flag=1;

                       
        break;
      case EVENT_TIMING_SIZE:
        currentDataPoint.valueTiming_Size = dataPointPtr->valueTiming_Size;
        GIZWITS_LOG("Evt:EVENT_TIMING_SIZE %4f\n",currentDataPoint.valueTiming_Size);
        //user handle
        break;
      case EVENT_LAMP_MODEL:
        currentDataPoint.valueLamp_Model = dataPointPtr->valueLamp_Model;
        GIZWITS_LOG("Evt:EVENT_LAMP_MODEL %d\n",currentDataPoint.valueLamp_Model);
        //user handle
        break;
      case EVENT_TODAY_DATE:
        currentDataPoint.valueToday_Date = dataPointPtr->valueToday_Date;
        GIZWITS_LOG("Evt:EVENT_TODAY_DATE %d\n",currentDataPoint.valueToday_Date);
        //user handle
        break;
      case EVENT_NOW_TIME:
        currentDataPoint.valueNow_Time = dataPointPtr->valueNow_Time;
        GIZWITS_LOG("Evt:EVENT_NOW_TIME %d\n",currentDataPoint.valueNow_Time);

//                           settime_flag=1;
                        //user handle
        break;


      case WIFI_SOFTAP:
        break;
      case WIFI_AIRLINK:
        break;
      case WIFI_STATION:
        break;
      case WIFI_CON_ROUTER:
        break;
      case WIFI_DISCON_ROUTER:
        break;
      case WIFI_CON_M2M:
        break;
      case WIFI_DISCON_M2M:
        break;
      case WIFI_RSSI:
        GIZWITS_LOG("RSSI %d\n", wifiData->rssi);
        break;
      case TRANSPARENT_DATA:
        GIZWITS_LOG("TRANSPARENT_DATA \n");
        //user handle , Fetch data from [data] , size is [len]
        break;
      case WIFI_NTP:
        GIZWITS_LOG("WIFI_NTP : [%d-%d-%d %02d:%02d:%02d][%d] \n",ptime->year,ptime->month,ptime->day,ptime->hour,ptime->minute,ptime->second,ptime->ntp);
        break;
      default:
        break;
    }
  }

  return 0;
}



/**
* @brief 系统毫秒计时维护函数,毫秒自增,溢出归零

* @param none
* @return none
*/
static uint32_t timerMsCount;
void gizTimerMs(void)
{
    timerMsCount++;
}

/**
* @brief 读取系统时间毫秒计时数

* @param none
* @return 系统时间毫秒数
*/
uint32_t gizGetTimerCount(void)
{
    return timerMsCount;
}


/**
* @brief MCU复位函数

* @param none
* @return none
*/
void mcuRestart(void)
{
    __set_FAULTMASK(1);
    NVIC_SystemReset();
}

/**@} */

/**
* @brief 定时器TIM3中断处理函数

* @param none
* @return none
*/
void TIMER_IRQ_FUN(void)
{
    if (TIM_GetITStatus(TIMER, TIM_IT_Update) != RESET)  
    {
        TIM_ClearITPendingBit(TIMER, TIM_IT_Update  );
        gizTimerMs();
    }
}

/**
* @brief 定时器TIM3定时器初始化

* @param none
* @return none
*/
void timerInit(void)
{
    u16 arr = 7199;
    u16 psc = 9;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(TIMER_RCC, ENABLE); //时钟使能

    //定时器TIM3初始化
    TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重载寄存器周期的值
    TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率的预分频值
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    TIM_TimeBaseInit(TIMER, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位0

    TIM_ITConfig(TIMER, TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

    //中断优先级NVIC设置
    NVIC_InitStructure.NVIC_IRQChannel = TIMER_IRQ;  //TIM3中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //优占优先级0级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //从优先级3级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器
    TIM_Cmd(TIMER, ENABLE);  //使能TIMx
}

/**
* @brief USART2串口中断函数

* 接收功能,用于接收与WiFi模组间的串口协议数据
* @param none
* @return none
*/
void UART_IRQ_FUN(void)
{
    uint8_t value = 0;
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
    {
        USART_ClearITPendingBit(USART2,USART_IT_RXNE);
        value = USART_ReceiveData(USART2);

        gizPutData(&value, 1);
    }
}


/**
* @brief 串口写操作,发送数据到WiFi模组
*
* @param buf      : 数据地址
* @param len       : 数据长度
*
* @return : 正确返回有效数据长度;-1,错误返回
*/
int32_t uartWrite(uint8_t *buf, uint32_t len)
{
    uint32_t i = 0;

    if(NULL == buf)
    {
        return -1;
    }
#ifdef PROTOCOL_DEBUG
    GIZWITS_LOG("MCU2WiFi[%4d:%4d]: ", gizGetTimerCount(), len);
#endif

    for(i=0; i<len; i++)
    {
        USART_SendData(UART, buf);
        while (USART_GetFlagStatus(UART, USART_FLAG_TXE) == RESET);//Loop until the end of transmission
#ifdef PROTOCOL_DEBUG
        GIZWITS_LOG("%02x ", buf);
#endif
        if(i >=2 && buf == 0xFF)
        {
          USART_SendData(UART,0x55);
          while (USART_GetFlagStatus(UART, USART_FLAG_TXE) == RESET);//Loop until the end of transmission
#ifdef PROTOCOL_DEBUG
        GIZWITS_LOG("%02x ", 0x55);
#endif
        }
    }

#ifdef PROTOCOL_DEBUG
    GIZWITS_LOG("\n");
#endif

    return len;
}

/**
* @brief USART串口初始化

* 用于与WiFi模组间的串口通信
* @param none
* @return none
*/
void uartInit(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    UART_GPIO_Cmd(UART_GPIO_CLK, ENABLE);
    UART_CLK_Cmd(UART_CLK, ENABLE);
    UART_AFIO_Cmd(UART_AFIO_CLK, ENABLE);

    GPIO_InitStructure.GPIO_Pin = UART_TxPin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(UART_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = UART_RxPin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(UART_GPIO_PORT, &GPIO_InitStructure);

    USART_InitStructure.USART_BaudRate = UART_BAUDRATE;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(UART, &USART_InitStructure);

    USART_ITConfig(UART,USART_IT_RXNE,ENABLE);
    USART_Cmd(UART, ENABLE);
    USART_ClearFlag(UART, USART_FLAG_TC); /*清空发送完成标志,Transmission Complete flag */

    /*使能串口中断,并设置优先级*/
    NVIC_InitStructure.NVIC_IRQChannel = UART_IRQ;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}


使用特权

评论回复
来自 32楼
junpeng324|  楼主 | 2017-11-12 22:36 | 只看该作者
/**
************************************************************
* @file         gizwits_product.h
* @brief        对应gizwits_product.c的头文件(包含产品软硬件版本定义)
* @author       Gizwits
* @date         2016-09-05
* @version      V0.1.2
* @CopyRight    Gizwits
*
* @NOTE         机智云.只为智能硬件而生
*               Gizwits Smart Cloud  for Smart Products
*               链接|增值ֵ|开放|中立|安全|自有|自由|生态
*               www.gizwits.com
*
***********************************************************/
#ifndef _GIZWITS_PRODUCT_H
#define _GIZWITS_PRODUCT_H

#include <stdint.h>
#include <stm32f10x.h>


/**
* @name 日志打印宏定义
* @{
*/
#define GIZWITS_LOG printf                          ///<运行日志打印
//#define PROTOCOL_DEBUG                              ///<协议数据打印

#ifndef ICACHE_FLASH_ATTR
#define ICACHE_FLASH_ATTR
#endif

/**@} */

#define typedef_t __packed typedef

/**
* MCU软件版本号
*/
#define SOFTWARE_VERSION "03010101"
/**
* MCU硬件版本号
*/
#define HARDWARE_VERSION "03010100"

#ifndef SOFTWARE_VERSION
    #error "no define SOFTWARE_VERSION"
#endif

#ifndef HARDWARE_VERSION
    #error "no define HARDWARE_VERSION"
#endif

/**@name TIM3相关宏定义
* @{
*/
#define TIMER                                         TIM3
#define TIMER_IRQ                                 TIM3_IRQn
#define TIMER_RCC                                 RCC_APB1Periph_TIM3
#define TIMER_IRQ_FUN                         TIM3_IRQHandler
/**@} */

/**@name USART相关宏定义
* @{
*/
#define UART_BAUDRATE                         9600
#define UART_PORT                             2
#define UART                                  USART2
#define UART_IRQ                              USART2_IRQn
#define UART_IRQ_FUN                          USART2_IRQHandler

#if (UART_PORT == 1)
#define UART_GPIO_Cmd          RCC_APB2PeriphClockCmd
#define UART_GPIO_CLK          RCC_APB2Periph_GPIOA

#define UART_AFIO_Cmd          RCC_APB2PeriphClockCmd
#define UART_AFIO_CLK          RCC_APB2Periph_AFIO

#define UART_CLK_Cmd           RCC_APB2PeriphClockCmd
#define UART_CLK               RCC_APB2Periph_USART1

#define UART_GPIO_PORT         GPIOA
#define UART_RxPin             GPIO_Pin_10
#define UART_TxPin             GPIO_Pin_9
#endif

#if (UART_PORT == 2)
#define UART_GPIO_Cmd          RCC_APB2PeriphClockCmd
#define UART_GPIO_CLK          RCC_APB2Periph_GPIOA

#define UART_AFIO_Cmd          RCC_APB2PeriphClockCmd
#define UART_AFIO_CLK          RCC_APB2Periph_AFIO

#define UART_CLK_Cmd           RCC_APB1PeriphClockCmd
#define UART_CLK               RCC_APB1Periph_USART2

#define UART_GPIO_PORT         GPIOA
#define UART_RxPin             GPIO_Pin_3
#define UART_TxPin             GPIO_Pin_2
#endif


#if (UART_PORT == 3)

#define UART_GPIO_Cmd          RCC_APB2PeriphClockCmd
#define UART_GPIO_CLK          RCC_APB2Periph_GPIOC

#define UART_AFIO_Cmd          RCC_APB2PeriphClockCmd
#define UART_AFIO_CLK          RCC_APB2Periph_AFIO

#define UART_CLK_Cmd           RCC_APB1PeriphClockCmd
#define UART_CLK               RCC_APB1Periph_USART3

#define UART_GPIO_PORT         GPIOC
#define UART_RxPin             GPIO_Pin_11
#define UART_TxPin             GPIO_Pin_10

#endif
/**@} */

/**@name 设备状态数据上报间隔时间宏定义
* @{
*/
#define REPORT_TIME_MAX 6000 //6S
/**@} */

void timerInit(void);
void uartInit(void);
void mcuRestart(void);
int32_t uartWrite(uint8_t *buf, uint32_t len);

/**@name Gizwits 用户API接口
* @{
*/
//int8_t gizwitsEventProcess(eventInfo_t *info, uint8_t *data, uint32_t len);
/**@} */

#endif


使用特权

评论回复
来自 33楼
junpeng324|  楼主 | 2017-11-12 22:38 | 只看该作者
旋钮调节
#include "ADC.h"
u8 i; u32 ad,dianya;
void adc_init()  //ADC初始化
{
  GPIO_InitTypeDef GPIO_InitStructure;
        ADC_InitTypeDef ADC_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_ADC1,ENABLE);
       
        //ADC管脚初始化配置
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;      //ADC123 通道1 PA1
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;         //模拟输入
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
       
        //ADC初始化
        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;     //ADC1与ADC2工作在独立模式
        ADC_InitStructure.ADC_ScanConvMode = DISABLE;          //单次单通道模式
        ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;    //单次模式
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //软件触发启动规则通道模数转换
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  //右对齐
        ADC_InitStructure.ADC_NbrOfChannel = 1;
        ADC_Init(ADC1, &ADC_InitStructure);
       
        ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);
        //指定ADC的规则组通道,设置转化顺序和采样时间
       
        ADC_Cmd(ADC1,ENABLE);       

        ADC_ResetCalibration(ADC1);//重置指定ADC的校准寄存器
        while(ADC_GetResetCalibrationStatus(ADC1));//获取ADC重置校验位的状态
       
        ADC_StartCalibration(ADC1);//开始指定ADC的校准状态
        while(ADC_GetCalibrationStatus(ADC1));//获取ADC的校准状态

        ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能或失能ADC的软件转换启动功能
}
void xuanniu_dat()  //旋钮数据处理
{
          for(i=0;i<50;i++)             
                {
                        ADC_SoftwareStartConvCmd(ADC1, ENABLE);
                        while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
                        ad=ad+ADC_GetConversionValue(ADC1);                 
                }
                ad=ad/50;
}
void xuanniu_deal()  //旋钮处理
{
   if(dianya!=ad)
                {
                        led_adc_flag=1;
                        dianya=ad;
                        tiaoguang(dianya/2);
                }

}




使用特权

评论回复
来自 34楼
junpeng324|  楼主 | 2017-11-12 22:42 | 只看该作者
旋钮调节部分我们使用了电位器调节,来改变灯的亮度,通过ADC检测电位器变化的电压以此来改变PWM的值。

使用特权

评论回复
来自 35楼
junpeng324|  楼主 | 2017-11-13 22:14 | 只看该作者
#include "pwm.h"
void pwm_init()
{
        GPIO_InitTypeDef GPIO_InitStructure;   //声明一个结构体变量,用来初始化GPIO
  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//声明一个结构体变量,用来初始化定时器
  TIM_OCInitTypeDef TIM_OCInitStructure;//根据TIM_OCInitStruct中指定的参数初始化外设TIMx


        /* 开启时钟 */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);


        /*  配置GPIO的模式和IO口 */
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
        GPIO_Init(GPIOA,&GPIO_InitStructure);


        //TIM3定时器初始化
        TIM_TimeBaseInitStructure.TIM_Period = 7200;           //不分频,PWM 频率=72000/900=8Khz//设置自动重装载寄存器周期的值
        TIM_TimeBaseInitStructure.TIM_Prescaler = 0;//设置用来作为TIMx时钟频率预分频值,100Khz计数频率
        TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;//设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;        //TIM向上计数模式
        TIM_TimeBaseInit(TIM5, & TIM_TimeBaseInitStructure);




        //PWM初始化          //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
        TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
        TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//PWM输出使能
        TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;


        TIM_OC1Init(TIM5,&TIM_OCInitStructure);
        //注意此处初始化时TIM_OC2Init而不是TIM_OCInit,否则会出错。因为固件库的版本不一样。


        TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Enable);//使能或者失能TIMx在CCR2上的预装载寄存器
       
        TIM_Cmd(TIM5,ENABLE);//使能或者失能TIMx外设
        TIM_SetCompare1(TIM5, 0);
}
void led_on()         //开灯
{
TIM_SetCompare1(TIM5, 2000);
currentDataPoint.valueLamp_Size=200;
}
void led_off()       //关灯
{
TIM_SetCompare1(TIM5, 0);
currentDataPoint.valueLamp_Size=0;
}
void tiaoguang(u16 zkb)      //调光
{
TIM_SetCompare1(TIM5, zkb);
currentDataPoint.valueLamp_Size=zkb/10;
  if(zkb==0)
        {
         currentDataPoint.valueLamp_Power=0;
        }
        else
        {
          currentDataPoint.valueLamp_Power=1;
        }
}


使用特权

评论回复
36
junpeng324|  楼主 | 2017-11-7 12:08 | 只看该作者
#include "public.h"          //公共函数头文件




void all_init()      //初始化
{
        pwm_init();             //pwm初始化
        shoushi_init();      //手势初始化
}

int main()
{       
        all_init();  
        while(1)
        {
                shoushi_dat();      //手势数据采集
                shoushi_deal();     //手势处理函数
        }       
}


使用特权

评论回复
37
mmuuss586| | 2017-11-7 12:36 | 只看该作者

资料太少了

使用特权

评论回复
38
一路向北lm| | 2017-11-7 21:50 | 只看该作者
资料再分享点啊,期待中......

使用特权

评论回复
39
junpeng324|  楼主 | 2017-11-7 21:51 | 只看该作者

打算慢慢更新哈。

使用特权

评论回复
40
junpeng324|  楼主 | 2017-11-7 21:51 | 只看该作者
一路向北lm 发表于 2017-11-7 21:50
资料再分享点啊,期待中......

等待我整理下,不要着急。

使用特权

评论回复
41
aizaixiyuanqian| | 2017-11-7 22:37 | 只看该作者
不错的作品,坐等更新。

使用特权

评论回复
42
一路向北lm| | 2017-11-8 08:19 | 只看该作者
可以加推荐了。

使用特权

评论回复
43
ipman| | 2017-11-8 10:55 | 只看该作者
感觉概念可以,可惜消费者还没有到达这个高度,需要通过手机APP了解台灯

使用特权

评论回复
44
junpeng324|  楼主 | 2017-11-8 22:38 | 只看该作者
ipman 发表于 2017-11-8 10:55
感觉概念可以,可惜消费者还没有到达这个高度,需要通过手机APP了解台灯 ...

小米的台灯不就是吗?很有用啊。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

37

主题

1130

帖子

8

粉丝