学习 学习
因为后面需要用到OLED屏幕显示,这里就开始了整合之路,没有新东西。就像变形金刚里的大力神一样进行组合变形。只是这里遇到一个问题,还是搞不明白,在程序烧录进去后功能没问题。重新上电后需要重启才开始运行。很费解。工程文件在这里 UART_OLED.rar
串口1的调试
该MCU共有2个串口,即串口0和串口1.这两个串口在结构上是不同的,因此在使用方法上也是不同。首先在结构上,串口0需要定时器来为其产生波特率,而串口1则内部有自己的定时器可以直接自己产生波特率。串口0内部没有FIFO,而串口1拥有发送和接收FIFO,可以提高使用效率。除此之外,串口1在发送和接收数据时数据格式除了正常串口的起始位,奇偶校验位,停止位等外,还可以配置extra bit。如果配置了extra bit则可以不用FIFO。不过为了方便使用,这里调试还是采用FIFO,不配置extra bit。
关于FIFO
发送和接收FIFO都可以触发中断,对于发送FIFO,寄存器TXTH充当FIFO数据的最低标准,,并且当FIFO中的字节数小于或等于TXTH值时,将设置TXRQ标志。例如,如果TXTH字段配置为1,则在传输FIFO中剩余0或1个字节发送时,TXRQ将被设置。并且寄存器UART1FCT当发送结束后,会自动变成0,该寄存器用来指示发送FIFO中有多少个字节的数据
对于接收FIFO,RXTH充当FIFO数据的高水位线,并且RXRQ标志将在FIFO中的字节数大于RXTH值时设置。例如,如果RXTH字段配置为0,则RXRQ将在接收FIFO中至少有一个字节时设置。同样,当数据读取后,UART1FCT用来指示接收FIFO中有多少个数据的值会自动变成0.
串口初始化
查看官方例程,对于UART1的BSP驱动包含很多函数,而在本工程中用到串口1仅仅用作发送功能,因此这里只使用串口的发送功能,发送依旧采用中断发送,如果不采用中断,如果一次性发送多个数据,接收端只能收到开始和结束的数据。
串口的IO口初始化
该MCU的片内外设对于IO的映射比较灵活,当需要将片内外设映射到外部IO口时,需要根据片内外设的优先级映射到从0.0开始的IO。其中UART0如果使用,则固定映射到0.4和0.5,其他外设则按照如图1所示进行映射。如果想将某一外设移动其按照优先级本应该映射到的IO口,则只需要将其本应该映射到的IO口skip就可以。例如,如果只使用UART1的功能,则其应该映射到0.4和0.5,如果想映射到0.6和0.7,则只需要将P1SKIP寄存器的第4位和第5位设置成skip即可。
IO口初始化代码如下:
void uart1_io_set(void) { //将串口1映射到0.6,0.7 P0MDOUT = P0MDOUT_B0__OPEN_DRAIN | P0MDOUT_B1__OPEN_DRAIN | P0MDOUT_B2__OPEN_DRAIN | P0MDOUT_B3__OPEN_DRAIN | P0MDOUT_B4__PUSH_PULL | P0MDOUT_B5__OPEN_DRAIN | P0MDOUT_B6__PUSH_PULL | P0MDOUT_B7__OPEN_DRAIN; //0.6.0.7设置为数字模式 P0MDIN = P0MDIN_B0__ANALOG | P0MDIN_B1__ANALOG | P0MDIN_B2__ANALOG | P0MDIN_B3__ANALOG | P0MDIN_B4__DIGITAL | P0MDIN_B5__DIGITAL | P0MDIN_B6__DIGITAL | P0MDIN_B7__DIGITAL; //将P0.4 P0.5跳过 P0SKIP = P0SKIP_B0__SKIPPED | P0SKIP_B1__SKIPPED | P0SKIP_B2__SKIPPED | P0SKIP_B3__SKIPPED | P0SKIP_B4__SKIPPED | P0SKIP_B5__SKIPPED | P0SKIP_B6__NOT_SKIPPED | P0SKIP_B7__NOT_SKIPPED; }
对于波特率,以及中断的配置
这里将波特率设置为115200,注意前提是系统时钟为内部时钟(24.5MHZ)的8分频,这里需要配置串口1内部自己的定时器的装载值。为了发送数据方便,这里对FIOF的设置阈值均为0.具体程序如下。
void uart1_param_init(void) { SFRPAGE = 0x20; //使能内部定时器 SBCON1 = SBCON1_BREN__ENABLED | SBCON1_BPS__DIV_BY_1; //设置FIFO阈值为0 UART1FCN0 = UART1FCN0_RXTH__ZERO | UART1FCN0_TXTH__ZERO | UART1FCN0_RFRQE__ENABLED | UART1FCN0_TFRQE__DISABLED; //设置内部定时器装载值 SBRLH1 = (0xFF << SBRLH1_BRH__SHIFT); SBRLL1 = (0xF3 << SBRLL1_BRL__SHIFT); //使能接收 SCON1 |= SCON1_REN__RECEIVE_ENABLED; UART1PCF=UART1PCF_RXSEL__CROSSBAR; SMOD1=SMOD1|SMOD1_SDL__8_BITS|SMOD1_SBL__SHORT|SMOD1_PE__PARITY_DISABLED | SMOD1_XBE__DISABLED|SMOD1_SPT__ODD_PARITY|SMOD1_MCE__MULTI_DISABLED; UART1FCN1 &= ~(UART1FCN1_RIE__BMASK | UART1FCN1_TIE__BMASK); //接收空闲中断为16个时钟周期 UART1FCN1 |= UART1FCN1_RXTO__TIMEOUT_16; } //对发送FIFO进行设置 void UART1_initTxFifo(void) { SFRPAGE = 0x20; UART1FCN0 &= ~(UART1FCN0_TFRQE__BMASK | UART1FCN0_TFLSH__BMASK | UART1FCN0_TXTH__FMASK | UART1FCN0_TFRQE__BMASK); //禁止发送中断 UART1FCN0 |= (UART1FCN0_TXTH__ZERO | UART1FCN0_TFRQE__DISABLED); UART1FCN1 &= ~(UART1FCN1_TFRQ__BMASK | UART1FCN1_TXHOLD__BMASK | UART1FCN1_TXNF__BMASK | UART1FCN1_TIE__BMASK); UART1FCN1 |= (UART1FCN1_TFRQ__SET | UART1FCN1_TXHOLD__CONTINUE | UART1FCN1_TIE__DISABLED); }
发送数据代码,利用UART1_wrteBuffer函数来使能发送中断
void UART1_writeBuffer(uint8_t buffer, uint8_t length) { // Initialize internal data txBuffer = buffer; txRemaining = length; // Enable tx fifo interrupts to kick off transfer UART1FCN0 |= UART1FCN0_TFRQE__ENABLED; } SI_INTERRUPT(UART1_ISR, UART1_IRQn) { if ((UART1FCN1 & UART1FCN1_TFRQ__BMASK) && (UART1FCN0 & UART1FCN0_TFRQE__ENABLED)) { // Write bytes as long as the tx fifo is not full and there // is room in the tx buffer while (txRemaining && (UART1FCN1 & UART1FCN1_TXNF__NOT_FULL)) { SBUF1 = txBuffer; --txRemaining; } } }
源工程文件点击这里UART1_SEND.rar
因为系统需要OLED屏幕作为显示,所以这里先将OLED屏幕显示点亮来作为第二个任务。点灯的程序参考shihengrui的帖子成功点亮,再此对其表示感谢。
OLED屏幕选择的是0.96英寸的OLED屏幕,采用的通信方式是IIC,这里依旧选择软件模拟的方式来进行点亮显示。
话不多说,直接上代码,只不过在进行存字库字符的时候,由于该板子的内存比较小,这里将字库的数组前都加上“data”关键字,以将数据放到data段,否则会报错。还有一个问题需要注意,采用Simplicity Studio编译器进行编译程序,需要添加licence,否则会提示超出版本程序大小限制
OLED头文件
#ifndef INC_OLED_H_ #define INC_OLED_H_ #include <SI_EFM8BB52_Register_Enums.h> #define OLED_CMD 0 //写命令 #define OLED_DATA 1 //写数据 #define OLED_MODE 0 //定义端口 SI_SBIT(OLED_SCL,SFR_P1,5); SI_SBIT(OLED_SDA,SFR_P1,6); #define OLED_SCLK_Clr() OLED_SCL=0 #define OLED_SCLK_Set() OLED_SCL=1 #define OLED_SDIN_Clr() OLED_SDA=0 #define OLED_SDIN_Set() OLED_SDA=1 #define SIZE 16 #define XLevelL 0x02 #define XLevelH 0x10 #define Max_Column 128 #define Max_Row 64 #define Brightness 0xFF #define X_WIDTH 128 #define Y_WIDTH 64 #define u8 uint8_t #define u32 uint32_t #define u16 uint16_t //OLED控制用函数 void OLED_WR_Byte(unsigned dat,unsigned cmd); void OLED_Display_On(void); void OLED_Display_Off(void); void OLED_Init(void); void OLED_Clear(void); void OLED_DrawPoint(u8 x,u8 y,u8 t); void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot); void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size); void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size); void OLED_ShowString(u8 x,u8 y, u8 *p,u8 Char_Size); void OLED_Set_Pos(unsigned char x, unsigned char y); void OLED_ShowCHinese(u8 x,u8 y,u8 no); void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]); void Delay_50ms(unsigned int Del_50ms); void Delay_1ms(unsigned int Del_1ms); void fill_picture(unsigned char fill_Data); void Picture(); void IIC_Start(); void IIC_Stop(); void Write_IIC_Command(unsigned char IIC_Command); void Write_IIC_Data(unsigned char IIC_Data); void Write_IIC_Byte(unsigned char IIC_Byte); void IIC_Wait_Ack(); #endif /* INC_OLED_H_ */
OLED源文件
/* * oled.c * * Created on: 2021年12月20日 * Author: liubinbin */ #include "oled.h" #include "oledfont.h" #include <device.h> /** * @name:IIC_Start() * @msg: I2C发送起始信号 * @param {*} * @return {*} */ void IIC_Start() { OLED_SCLK_Set() ; NOP();NOP();NOP(); //等待延时 OLED_SDIN_Set(); NOP();NOP();NOP(); //等待延时 OLED_SDIN_Clr(); NOP();NOP();NOP(); //等待延时 OLED_SCLK_Clr(); NOP();NOP();NOP(); //等待延时 } /** * @name: void IIC_Stop() * @msg: IIC停止信号 * @param {*} * @return {*} */ void IIC_Stop() { OLED_SCLK_Set() ; NOP();NOP();NOP(); //等待延时 OLED_SDIN_Clr(); NOP();NOP();NOP(); //等待延时 OLED_SDIN_Set(); NOP();NOP();NOP(); //等待延时 } /** * @name:void IIC_Wait_Ack() * @msg: 等待应答 * @param {*} * @return {*} */ void IIC_Wait_Ack() { OLED_SCLK_Set() ; NOP();NOP();NOP(); OLED_SCLK_Clr(); NOP();NOP();NOP(); } /** * @name: Write_IIC_Byte(unsigned char IIC_Byte) * @msg: IIC写一个字节数据 * @param {unsigned char} IIC_Byte * @return {*} */ void Write_IIC_Byte(unsigned char IIC_Byte) { unsigned char i; unsigned char m,da; da=IIC_Byte; NOP();NOP();NOP(); OLED_SCLK_Clr(); NOP();NOP();NOP(); for(i=0;i<8;i++) { m=da; OLED_SCLK_Clr(); m=m&0x80; if(m==0x80) {OLED_SDIN_Set();} else OLED_SDIN_Clr(); NOP();NOP();NOP(); da=da<<1; OLED_SCLK_Set(); NOP();NOP();NOP(); OLED_SCLK_Clr(); NOP();NOP();NOP(); } } /** * @name:Write_IIC_Command(unsigned char IIC_Command) * @msg: IIC写一个命令 * @param {unsigned char} IIC_Command * @return {*} */ void Write_IIC_Command(unsigned char IIC_Command) { IIC_Start(); Write_IIC_Byte(0x78); IIC_Wait_Ack(); Write_IIC_Byte(0x00); IIC_Wait_Ack(); Write_IIC_Byte(IIC_Command); IIC_Wait_Ack(); IIC_Stop(); } /** * @name: Write_IIC_Data(unsigned char IIC_Data) * @msg: IIC写一个数据 * @param {unsigned char} IIC_Data * @return {*} */ void Write_IIC_Data(unsigned char IIC_Data) { IIC_Start(); Write_IIC_Byte(0x78); //D/C#=0; R/W#=0 IIC_Wait_Ack(); Write_IIC_Byte(0x40); //write data IIC_Wait_Ack(); Write_IIC_Byte(IIC_Data); IIC_Wait_Ack(); IIC_Stop(); } /** * @name: OLED_WR_Byte(unsigned dat,unsigned cmd) * @msg: OLED写一个字节 * @param {unsigned} dat 写数据 * @param {unsigned} cmd 写命令 * @return {*} */ void OLED_WR_Byte(unsigned dat,unsigned cmd) { if(cmd) { Write_IIC_Data(dat); } else { Write_IIC_Command(dat); } } /** * @name:fill_picture(unsigned char fill_Data) * @msg: 填充图片 * @param {unsigned char} fill_Data * @return {*} */ void fill_picture(unsigned char fill_Data) { unsigned char m,n; for(m=0;m<8;m++) { OLED_WR_Byte(0xb0+m,0); //page0-page1 OLED_WR_Byte(0x00,0); //low column start address OLED_WR_Byte(0x10,0); //high column start address for(n=0;n<128;n++) { OLED_WR_Byte(fill_Data,1); } } } /** * @name:OLED_Set_Pos(unsigned char x, unsigned char y) * @msg: 设置坐标 * @param {unsigned char} x 横坐标 * @param {unsigned char} y 纵坐标 * @return {*} */ void OLED_Set_Pos(unsigned char x, unsigned char y) { OLED_WR_Byte(0xb0+y,OLED_CMD); OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD); OLED_WR_Byte((x&0x0f),OLED_CMD); } /** * @name: OLED_Display_On(void) * @msg: 开启OLED屏幕显示 * @param {*} * @return {*} */ void OLED_Display_On(void) { OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令 OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON } /** * @name: OLED_Display_Off(void) * @msg: 关闭OLED显示 * @param {*} * @return {*} */ void OLED_Display_Off(void) { OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令 OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF } /** * @name: OLED_Clear(void) * @msg: 清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样 * @param {*} * @return {*} */ void OLED_Clear(void) { u8 i,n; for(i=0;i<8;i++) { OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7) OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址 OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址 for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); //更新显示 } } /** * @name:OLED_On(void) * @msg: 打开OLED显示 * @param {*} * @return {*} */ void OLED_On(void) { u8 i,n; for(i=0;i<8;i++) { OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7) OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址 OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址 for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA); //更新显示 } } /** * @name:OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size) * @msg: 显示字符 * @param {u8} x 起始横坐标0-128 * @param {u8} y 起始纵坐标0-6 * @param {u8} chr 显示字符 * @param {u8} Char_Size 大小12/16 * @return {*} */ void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size) { unsigned char c=0,i=0; c=chr-' ';//得到偏移后的值 if(x>Max_Column-1){x=0;y=y+2;} if(Char_Size ==16) { OLED_Set_Pos(x,y); for(i=0;i<8;i++) OLED_WR_Byte(F8X16[c*16+i],OLED_DATA); OLED_Set_Pos(x,y+1); for(i=0;i<8;i++) OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA); } else { OLED_Set_Pos(x,y); for(i=0;i<6;i++) OLED_WR_Byte(F6x8[c][i],OLED_DATA); } } /** * @name: oled_pow(u8 m,u8 n) * @msg: m的n次方 * @param {u8} m * @param {u8} n * @return {*} */ u32 oled_pow(u8 m,u8 n) { u32 result=1; while(n--)result*=m; return result; } /** * @name: OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2) * @msg: 显示数字 * @param {u8} x 起始横坐标0-128 * @param {u8} y 起始纵坐标0-6 * @param {u32} num 数字值 * @param {u8} len 位数 * @param {u8} size2 大小12/16 * @return {*} */ void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2) { u8 t,temp; u8 enshow=0; for(t=0;t<len;t++) { temp=(num/oled_pow(10,len-t-1))%10; if(enshow==0&&t<(len-1)) { if(temp==0) { OLED_ShowChar(x+(size2/2)*t,y,' ',size2); continue; }else enshow=1; } OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2); } } /** * @name: OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size) * @msg: 显示字符串 * @param {u8} x起始横坐标0-128 * @param {u8} y起始纵坐标0-6 * @param {u8} *chr 字符串指针 * @param {u8} Char_Size 大小12/16 * @return {*} */ void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size) { unsigned char j=0; while (chr[j]!='\0') { OLED_ShowChar(x,y,chr[j],Char_Size); x+=8; if(x>120){x=0;y+=2;} j++; } } /** * @name: OLED_Init(void) * @msg: 初始化OLED屏幕 * @param {*} * @return {*} */ void OLED_Init(void) { uint8_t SFRPAGE_save = SFRPAGE; //init oled io P1MDIN = P1MDIN|P1MDIN_B5__DIGITAL|P1MDIN_B6__DIGITAL; P1MDOUT = P1MDOUT|P1MDOUT_B5__PUSH_PULL|P1MDOUT_B6__PUSH_PULL; XBR2 = XBR2|XBR2_XBARE__ENABLED; SFRPAGE = SFRPAGE_save; OLED_WR_Byte(0xAE,OLED_CMD);//--display off OLED_WR_Byte(0x00,OLED_CMD);//---set low column address OLED_WR_Byte(0x10,OLED_CMD);//---set high column address OLED_WR_Byte(0x40,OLED_CMD);//--set start line address OLED_WR_Byte(0xB0,OLED_CMD);//--set page address OLED_WR_Byte(0x81,OLED_CMD); // contract control OLED_WR_Byte(0xFF,OLED_CMD);//--128 OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64) OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset OLED_WR_Byte(0x00,OLED_CMD);// OLED_WR_Byte(0xD5,OLED_CMD);//set osc division OLED_WR_Byte(0x80,OLED_CMD);// OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off OLED_WR_Byte(0x05,OLED_CMD);// OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period OLED_WR_Byte(0xF1,OLED_CMD);// OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion OLED_WR_Byte(0x12,OLED_CMD);// OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh OLED_WR_Byte(0x30,OLED_CMD);// OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable OLED_WR_Byte(0x14,OLED_CMD);// OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel }
测试main函数
int main (void) { u8 t1; u8 t2; sys_init(); OLED_Init(); IE_EA=0; LED=0; t1=0; t2=' '; OLED_Clear(); OLED_ShowChar(0,0,'E',16); OLED_ShowChar(8,0,'E',16); OLED_ShowChar(16,0,'P',16); OLED_ShowChar(24,0,'W',16); OLED_ShowChar(32,0,'.',16); OLED_ShowChar(40,0,'C',16); OLED_ShowChar(48,0,'O',16); OLED_ShowChar(56,0,'M',16); OLED_ShowString(64,0,".CN",16); OLED_ShowString(0,2,"NUMBER:",16); OLED_ShowString(0,4,"ASCALL:",16); while (1) { OLED_ShowNum(56,2,t1,3,16); OLED_ShowChar(56,4,t2,16); LED=!LED; t1++; if(t1>255) t1=0; t2++; if(t2>'~') t2=' '; delay(0XFFF); delay(0XFFF); } // Spin forever }
串口0采用定时器1来进行产生波特率,定时器1在写入装载值时,由于时钟的问题会产生波特率偏差,在时钟为3062500Hz的情况下,计算写入TH1和TL1的值为13,此时波特率产生实际值为117788,可以看出偏差还是很大,当为9600波特率时,写入TH1和TL1的值为97,此时计算出波特率为9630.偏差比较小。因此在这种情况下我将串口1和串口0的波特率均设置为9600.在测试时要注意,开发板的串口0是通过虚拟串口和其他片外外设进行交互数据,而虚拟串口的波特率是115200,这在手册中有提到,改变不了,因此需要用USB转TTL模块将数据传输到串口助手来查看数据是否对,这个坑坑死人,还不如板载CH340芯片方便。 虚拟串口的介绍如图所示
虚拟串口介绍图
系统的原理图如图所示,原理图首先是电源部分,电源一共包含2部分,一部分是12V转5V部分用来给OLED屏幕,以及串口转485模块供电。还有一部分为5V转3.3V部分用来给MCU供电。然后是MCU部分,MCU部门这里仅引出必要的管脚,TTL转485模块为购置的集成串口转485装置,不用增加485的半双工切换引脚,节省MCU的IO口资源;OLED接口为I2C接口的OLED屏幕,用来显示必要的信息,串口1为引出串口,用来和网关通信,实现数据入云的操作。复位按键用来手动给MCU复位,LED用来作为一些必要的信息指示,调试接口为参考官网原理图的设计的调试接口。系统采用12V供电,
系统原理图
完结撒花,花花花
源码在这里 Terminator.rar 演示视频在这里演示视频
经过几天的奋战,把试用版的功能全部实现了,再絮叨下所完成的内容,用EFM8BB52完成传感器数据的提取。将数据在OLED屏幕上进行显示,然后定时刷新OLED屏幕的数据。为了将数据入网,这里增加了自制网关,网关和EFM8BB52之间采用串口通信,网关数据在接收到数据后,将数据进行处理转换成json字符串,通过http协议上传到服务器。首先EFM8BB52显示结果图如图1所示,服务器端数据网页显示如图2所示(图2后截得图,数据和图1不一样,懒得把收起来的开发板重新开机了)。
图1 OLED采集结果图
图2 服务器网页查看图
现在对系统实物图进行详细介绍,EFM8BB52搭建的系统实物图如图3所示,图3中的电源模块为12转5V电源模块,用来给整个系统包括传感器,开发板,以及网关供电,这里用航空插头作为连接器。由于传感器为485接口,所以增加了TTL转485模块用来和传感器通信。OLED屏幕采用IIC通信的OLED。
图3 系统实物图
网关实物图如图4所示,网关主要负责对接收到的串口数据进行整合处理,处理成json字符串格式,主要是http协议传输的是字符串数据。EFM8BB52为8位MCU处理json转换有点吃力,所以该部分功能放到网关处理,而且EFM8BB52没有网口。数据处理后通过网口和路由器完成入网。监测系统连接实物图如图5所示。
图4 网关实物图
图5 系统连接图
回复
有奖活动 | |
---|---|
【有奖活动——B站互动赢积分】活动开启啦! | |
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |