完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
|
|
相关推荐
1个回答
|
|
|
想做一个能够远程检测温湿度的东西,这样家里放一个,外面放一个,早上一起来就能看到实时的温湿度,岂不美滋滋。
最初想法是单独买温湿度的传感器,像DHT11那样,然后在买一个无线模块像NRF24L01,然后再配个微控制器啥的,后来在淘宝搜着搜着就发现了WHT20这款神器,他本身就有无线功能,而且他的传感器是SHT20,精度更高。然后这样我就只要配个接收的微控制器,选来选去,觉得51用腻了,STM32有点大材小用了,Arduino Emmmm......不想用,就用了STM8S这么一个从来没用过的的微控制器。 先说下WHT20和他配套的接收器WSR。 一、WHT20 这是他官方介绍.(我只是不想打这么多字) 上面就有他的引脚,它可以通过串口在线设置,也可以通过WSR进行设置,他的VCC只能接3.3V左右的电压,实际测试,接5V虽然不会坏,但是发的都是乱码。 1.通过串口设置 通过串口设置时候,要把他的SET脚拉低,然后通过串口给他发送指令。(十六进制发送) CC是开始标志;Time就是他的采集周期,可以设置1-65536s(占两个字节);NETID是他的网络号,只有WHT20和WSR的网络号相同时候才能通信,范围0-65535(两个字节);功率是设置他的发射功率(一个字节);波特率就是串口波特率(一个字节);Chose设置1时,他无线发射的同时也会通过串口发送,0就只无线发射(一个字节);Channel就是通信频道,有128个频道(一个字节);SUM是前面所有字节加起来,取低八位(一个字节),这校验和正确的时候,传感器才会返回值,不正确也能设置成功,不过不会返回....不知道算不算它的一个BUG;FF结束标志。 功率的对应表。 波特率对应表。 2.无线设置 短暂拉低KEY脚后拉高,此时就可以等待WSR的设置指令,此时传感器参数会恢复到默认状态NETID=0000,power=12dBm,channel=0x64.然后WSR就发射设置指令,按照如下格式。 只有指定的传感器ID才能接受设置参数,FFFFFF的话,会设置所有处于设置状态的传感器。 传感器设置成功后悔将参数保存到EEPROM中,然后发射返回值。 二、WSR CS是片选,接低电平工作。SET是设置,拉低可通过串口对他进行设置。 1.串口设置自身参数。 拉低SET脚后,串口发送0XAA+0X5A+模块ID+NETID+0X00+POWER+0X00+波特率+0X00+Channel+0X00 +0X00+0X12+0X00+SUM 参数意义同WHT20。 2.设置传感器参数 WSR的SET拉低,通过串口发送AA5E指令,就可以设置处于设置状态的WHT20了 参数意义同WHT20,设置成功后就会返回AA5F指令 再就是他们之间的通讯协议了 这款传感器还是不错的,功耗真的挺低的,实测,12dBm的功率,采集周期7S,我用的锂电池,平均电流大概在1.6mA左右,也就是一个2000mah的锂电池,能用大概40多天。 STM8S 这个单片机不能用keil开发,只能用IAR和官方的STVD,网上的程序也是挺少的,开发它我也废了一番功夫。 我要用它的串口然后再用它驱动12864,我用的那一款引脚很少,所以12864我就用了SPI驱动方式。 说到底只是款单片机,看下时钟,看下各种片内外设寄存器就能用了呗。这个淘宝买的系统板,4块钱一个,真是便宜啊。。 官方的资料也是少之又少,他这板子用的是内部RC振荡电路提供时钟源,官方介绍说他因为出产,环境啥的不同,导致有差异。。。。就直接说不太准就行了呗.......,而且他是啥三级流水线,这个三级流水线意思就是呢...取指令,指令解码,指令执行交给了三个人去做,这样效率会快很多,但是 这也就造成一个问题,一条汇编指令,他的周期我不知道是多少了.... 要想延时准还得用汇编........ volatile u8 fac_us=0; void delay_init(u8 clk) { if(clk>16)fac_us=(16-4)/4;//24Mhz时,stm8大概19个周期为1us else if(clk>4)fac_us=(clk-4)/4; else fac_us=1; } void delay_us(u16 nus) { __asm( "PUSH A n" //压栈 1T "DELAY_XUS: n" "LD A,fac_us n" //倍延加载到累加器A 1T "DELAY_US_1: n" "NOP n" //1T "DEC A n" //1T "JRNE DELAY_US_1 n" //!=0 跳转(2T)到DELAY_US_1执行, =0 不跳转(1T). "NOP n" //1T "DECW X n" //1T "JRNE DELAY_XUS n" //!=0 跳转(2T)到DELAY_XUS 执行, =0 不跳转(1T). "POP A n" //出栈 1T ); } STM8S 通过SPI驱动LCD12864 void SPI_12864_Init(void) { SPI_Init(SPI_FIRSTBIT_MSB, SPI_BAUDRATEPRESCALER_2, SPI_MODE_MASTER, SPI_CLOCKPOLARITY_HIGH, SPI_CLOCKPHASE_2EDGE, SPI_DATADIRECTION_2LINES_FULLDUPLEX, SPI_NSS_SOFT, 0x00); SPI_Cmd(ENABLE); GPIO_Init(GPIOC,GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_FAST );//定义LED的管脚的模式 GPIO_WriteHigh(GPIOC, GPIO_PIN_4); } void LCD_wr(u8 lcd_com,u8 lcd_data) //写入LCD数据或命令 { u8 lcd_data_m***,lcd_data_l***; lcd_data_m***=0xf0&lcd_data; lcd_data_l***=(0x0f&lcd_data)<<4; if(lcd_com==0) //写命令 { while (SPI_GetFlagStatus( SPI_FLAG_TXE) == RESET); //等待 SPI 发送缓冲空 SPI_SendData(0xf8); // SPI 发送数据--命令指令-- } if(lcd_com==1) //写数据 { while (SPI_GetFlagStatus( SPI_FLAG_TXE) == RESET); //等待 SPI1 发送缓冲空 SPI_SendData(0xfa); //SPI1 发送数据--数据指令-- } delay_ms(1); while(SPI_GetFlagStatus( SPI_FLAG_TXE) == RESET); //等待 SPI1 接收数据完毕 SPI_SendData(lcd_data_m***); //SPI1 发送高4位数据 delay_ms(1); while(SPI_GetFlagStatus( SPI_FLAG_TXE) == RESET); //Wait for SPI1 Tx buffer empty SPI_SendData(lcd_data_l***); // SPI1 发送低4位数据 delay_ms(1); } void initlcd(void) //LCD初始化 { LCD_wr(0,0x30); //30---基本指令动作 delay_ms (4); LCD_wr(0,0x01); //清屏,地址指针指向00H delay_ms (3); LCD_wr(0,0x06); //光标的移动方向 delay_ms (1); LCD_wr(0,0x0c); //开显示,关游标 delay_ms (1); } //LCD显示字符串 //X Y起始坐标 //*ptr 字符串地址 dat 字符串长度 //返回值 无 void LCD_showstring(u8 X,u8 Y,u8 *ptr,u8 dat) { u8 i; switch(X) //判断第几行 { case 0:Y|=0x80;break; case 1:Y|=0x90;break; case 2:Y|=0x88;break; case 3:Y|=0x98;break; default:break; } LCD_wr(0,Y); //发送起始地址 for (i=0;i LCD_wr(1,*ptr++); } } //LCD显示数字(包括负数) //X,Y 数字显示起始地址 void LCD_shownum(u8 X,u8 Y,char num) { switch(X) //判断第几行 { case 0:Y|=0x80;break; case 1:Y|=0x90;break; case 2:Y|=0x88;break; case 3:Y|=0x98;break; default:break; } LCD_wr(0,Y); if(num>=128) //大于128代表负数 { LCD_wr(1,0x2D); //显示‘-’ num=num&0x7f; //最高位置零 LCD_wr(1,num/10+0x30);//取十位 LCD_wr(1,num%10+0x30);//取个位 } else if(num<128) { LCD_wr(1,(num)/10+0x30); LCD_wr(1,(num)%10+0x30); } } 串口相关程序 void Uart_Init(void) { UART1_DeInit(); UART1_Init((u32)9600, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO , UART1_SYNCMODE_CLOCK_DISABLE , UART1_MODE_TXRX_ENABLE); UART1_ITConfig(UART1_IT_RXNE_OR,ENABLE ); UART1_Cmd(ENABLE ); } void UART1_SendByte(u8 data) { UART1_SendData8((unsigned char)data); /* Loop until the end of transmission */ while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET); } void UART1_SendString(u8* Data,u16 len) { u16 i=0; for(;i } u8 UART1_ReceiveByte(void) { u8 USART1_RX_BUF; while (UART1_GetFlagStatus(UART1_FLAG_RXNE) == RESET); USART1_RX_BUF=UART1_ReceiveData8(); return USART1_RX_BUF; } void CLR_BUF() //清空串口接收缓存 { point=0; memset( RxBuffer,0,20); } #pragma vector=20 __interrupt void UART1_RX_IRQHandler(void) { u8 Res; static u8 start; //LCD_display(0,0,"hello1",8); if(UART1_GetITStatus(UART1_IT_RXNE )!= RESET) /*接收中断(接收到的数据必须是0x0d 0x0a结尾)*/ { Res =UART1_ReceiveData8();/*(USART1->DR);读取接收到的数据,当读完数据后自动取消RXNE的中断标志位*/ if(Res==0xAA) {start=1;} //判断数据是否开始 if(Res==0x5B) {cmd_responce=1;} //判断是否是命令 if(Res==0xFF) {start=0;usart_flag=1;} //判断是否结束 if(start) RxBuffer[point++]=Res; //读取命令OR数据 } } WSR相关函数 void wsr_Init(void) { GPIO_Init(GPIOA,GPIO_PIN_1, GPIO_MODE_OUT_PP_HIGH_FAST );//SET脚接A1 GPIO_Init(GPIOA,GPIO_PIN_2, GPIO_MODE_OUT_PP_HIGH_FAST );//CS脚接A2 GPIO_WriteLow(GPIOA, GPIO_PIN_2); GPIO_WriteHigh(GPIOA, GPIO_PIN_1); } //WSR设置函数 //NETID:网络号 power:功率 channel:频道 baud:波特率 //返回参数:0:设置不成功 // 1:设置成功 u8 wsr_set(u8 NETID,u8 power,u8 channel,u8 baud) { u8 i; u8 cmd[18]={0xAA,0X5A,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X04,0X00,0X64,0X00,0X00,0X00,0X12,0X00,0X00};//命令数组 cmd[5]=NETID; cmd[7]=power; cmd[9]=baud; cmd[11]=channel; for(i=0;i<17;i++) cmd[17]=cmd[17]+cmd; //添加校验位 GPIO_WriteLow(GPIOA, GPIO_PIN_1); //SET L delay_ms(1); UART1_SendString(cmd,18); //发送命令 //delay_ms(1); while(!cmd_responce); //等待命令回复 cmd_responce=0; GPIO_WriteHigh(GPIOA, GPIO_PIN_1); //SET H delay_ms(3); if(RxBuffer[5]==NETID&&RxBuffer[7]==power&&RxBuffer[9]==baud&&RxBuffer[11]==channel) //判断是否设置成功 { CLR_BUF(); return 1; } CLR_BUF(); return 0; } |
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
4200 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
3261 浏览 1 评论
2791 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
2224 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
15129 浏览 2 评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
3164浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
1939浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
2106浏览 3评论
2019浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
2216浏览 3评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-13 00:48 , Processed in 0.607213 second(s), Total 74, Slave 57 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
419