经过了这个暑假大约4个星期的培训,我第一次感觉到世界的伟大与自己的渺小。有很多自己不知道的与要学习的,每一个方向都是一门学问。这4个星期我从对软件硬件一无所知,到跟着学长学姐学习做一套完整的物联网小系统,虽说对每个方面的接触都不深,也没有系统的学习,但是还是大体有一些体会与感悟,希望借这篇博客梳理一下自己所学及遇到的问题。
首先一个物联网小系统的话,必定是要由硬件与软件构成的。针对于我们此次做的这个,它主要的功能是获取室内的温度,并通过一个界面显示出来。
硬件部分:设计一个开发板,让它实现从室内读取温度的功能。并通过一段程序,使接收到的温度转换为特定格式,发送给服务器
软件部分:通过对HTML,JS,CSS样式表以及VUE的学习,做出一个网页,写一段程序接收服务器发出的json格式的数据并显示在网页上
硬件部分
如果要自己设计一个开发板的话,Altium Designer是必不可少的。因此我们第一个学习的软件也是它,开发板绘制完成后,我们就会使用Keil向32单片机中编程,以获取温度。此时温度可以在串口调试助手中显示。
- Altium Designer
- 首先是学习常规的画原理图和PCB的一些方法
- 学习开发板的设计以及每个部分的画法
- 通过查找资料,找到合适的芯片,并明白使用方法
- 设计电路板,并完成PCB的绘制
- Keil
- 学习一些简单的实验例程,如:流水灯,数码管,按键控制
关于流水灯51以及32实现方法的一些不同(易混淆):
实现左移8位
51:
for(i=0;i<8;i++)
{
P2=~(0x01<<i);
delay(50000);
}
32:
for(i=0;i<8;i++)
{
GPIO_ResetBits(GPIOC,0x01<<i);
delay_ms(500);
GPIO_SetBits(GPIOC,0x01<<i);
delay_ms(500);
}
这两段代码虽然看起来相似,但实现原理却完全不同。
51的代码是通过直接给P2口赋高低电平来控制灯的亮暗,而32则是通过两个函数
GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
这两个函数的第二个参数是IO口的引脚,所以第二段代码的移位其实是选择某一个灯,并通过函数的功能去点亮和熄灭它。第一段代码的移位则是直接移动高低电平。第一次学习的话,我想在这里应该很容易犯错。
并且在32中如果使能了一个灯的话,这个灯会直接被点亮,所以我们如果想要它一开始就是熄灭状态的话,就必须在你的.c文件中预先将所有灯设置为不点亮状态。
- 学习串口与中断的知识
u8 temp;
u8 USART_RX_BUF[50];//串口数据缓冲区
u8 USART_FLAG;//接收完成标志位
void USART1_IRQHandler(void) //串口1的中断服务函数
{
static u8 num;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//判断接收中断是否发生
{
temp=USART_ReceiveData(USART1);//读取接收到的数据
USART_RX_BUF[num++]=temp;
if(temp=='&')
{
USART_FLAG=1;
num=0;
}
USART_SendData(USART1, (uint8_t) temp);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) //等待发送完成
{} //USART_FLAG_TC:发送完成标志位
}
}
这段代码里涉及到两个非常容易混淆的函数
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
第一个函数USART_GetITStatus()是获取中断发生的动作
由返回值SET或RESET判断,所以if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
这段代码便是判断接收中断是否发生。
第二个函数FlagStatus USART_GetFlagStatus()是用于检测串口中断标志位的状态,同样返回SET或RESET
所以while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
这段代码便是没有发送完成就继续循环,即“等待发送完成的意思”。
除了这两个函数,当时这段程序还有困扰我的一点(可能很简单,但我当时真的想了好久),就是串口接收到的数据都是一个字节一个字节被赋给数组中的每一个元素的,最后接收到“停止符”的时候,代表数据接收完成,然后num置0.
- 理解TM275的工作原理,写出得到温度的程序
在进行这一步的时候,我觉得我收获最大的是如何通过查看文档去写出你自己的程序。
这是我的温度芯片读取到寄存器的一个图,以下这段代码是实现读取
u16 TMP275_Read_Registers(u8 pointer)
{
u16 temp;
IIC_Start();
IIC_Send_Byte(0x90);
IIC_Wait_Ack();
IIC_Send_Byte(pointer); //设置指向寄存器,指向将要操作的寄存器
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(0x91); //发送器件地址
IIC_Wait_Ack();
temp=IIC_Read_Byte(1); //读取数据到寄存器
temp<<=8; //temp左移八位
temp=IIC_Read_Byte(1); //读取数据到寄存器
return temp;
}
这一段代码基本上全部是按照图中进行,我们可以看到,代码中发送了两次器件地址,前面的位是用于配置温度芯片,最后一位则是看图是读还是写。在上图R/W的位置,很明确地标出了最后一位是1还是0,这也是我出错的一个点。
- 最后学习服务器数据发送格式,编写转换格式的程序
最后开发板焊接完成之后,便可以开始调试程序,上传至服务器了。
焊接过程中,我也遇到了一些问题。当我完成了板子的焊接以后,Keil总会提醒我关于下载器的配置导致无法下载的问题,我也上网搜了许多解决方案,但大都是重新配置下载器那一块。但幸好一个同学经验比较丰富,说是可能是复位电路的问题,于是我们重新焊接了复位电路,才完成了程序的下载。
软件部分
软件的学习方面,我们主要学习了前端。培训的内容大概分成了4个大的部分:HTML,CSS,JavaScript,Vue.js
- 首先,我们讲了HTML中的一些基本的标签和布局
- 然后学习了为我们要得到的界面添加样式的一些方法
在这中间我印象比较深的是添加图片时,相对路径与绝对路径的区别。
绝对路径就是指这张图片在你的电脑所处的具体位置,而相对路径则是这张图片相对你的程序所处的位置。类似于这样src="../img/6.jpg"
我们的界面做出来后不可能只在自己的电脑上才能看,当我们把文件打包发给别人时,使用相对路径就可以保证在别人的电脑上也可以打开,所以最好使用相对路径。
- 学习了JS的一些基础知识(如:函数,语句,循环等)和 JS HTML DOM (文档对象模型)的一些相关知识
这一阶段的话,比较吸引眼球的是我们可以自己制作那些坑过别人的点不完的弹窗,而且只需要几行代码即可以实现,比如:
var str = ["你个傻瓜", "你个大傻瓜", "不信?", "哼", "相信了吧"];
var i = 0;
for (i in str)
{
alert(str[i]);
}
JS HTML DOM的知识也感觉比较有意思,它能够创建动态的 HTML 内容。
- 最后我们学习了一些简单的Vue.js的内容,由服务器获取温度并在网页上显示出来也是由这一步来实现
这一部分的内容我印象最深的大概有两个板块:第一个板块是关于Vue.js Ajax(axios);第二个是如何利用一些已有的UI框架去美化你的界面
首先Vue.js Ajax(axios)是什么(借用一下学长的ppt)
所以我认为其中有两个部分比较重要,一个是创建请求,一个是接收响应。我们学习写程序时,在这两个部分出的错误也是最多的。
创建请求:一共有8种方法,其中最常用的有GET和POST两种
GET:常用于向服务器查询某些信息
POST:通常用于向服务器发送应该被保存的数据
现在比如我们随便找一个api接口;
天气获取接口:
https://www.apiopen.top/weatherApi?city=成都
那么?后的便是它的参数,GET传递参数有两种方式
1.直接在 URL 上添加参数
.get("https://www.apiopen.top/weatherApi?city=成都")
2.通过 params 设置参数
.get("https://www.apiopen.top/weatherApi", {
params: {
city:"成都"
}
})
接收响应:首先axios请求的响应是有它自己的响应结构的
我们想要得到的数据都被存放在由服务器提供的响应data里,所以我们写程序的时候需要一点一点的向里“挖掘”。
比如现在我的天气返回示例是这样的:
我现在要获取15日的高温就应该写成
.then(response => {
console.log(response)
this.content=response.data.data.forecast[0].high
})
因为由服务器提供的响应data里包含了所有的这些响应数据,所以我们要一层层的向下“调用”,所以会有两个data。
同理,当我们把我们板子上获取的温度上传至服务器,再通过服务器的接口获取温度,这样便可以实现在网页上显示温度的功能。
现在再来说一下UI的板块。一个好的UI可以为我们的页面增色不少,现在也有许多成品的UI模块,我们不需要自己去设计,只需要安装插件就可以直接使用,非常方便。但对于我们自己来说,它给我们的代码并不一定能够匹配我们所有的想法,所以我们还需要自己多动手多动脑去思考,如何去修改并完善它。
这样,就实现了我们所要做的物联网获取温度的小系统。