项目简介:利用ADS1256芯片对输入电压,电流做检测。可外接5V使用,也可以使用锂电池使用。该工具具有软启动功能,也可外接NTC温度传感器测量温度,电池电量低时自动关机保护锂电池。
一:硬件设计部分:
1.1充电芯片 LTC4054介绍:
LTC 4054 是一款完整的单节锂离子电池用恒定电流/恒定电压线性充电器·其 ThinSOT 封装与较少的外部元件数目使得 LTC4054 成为便携式应用的理想选择。而且,LTC4054 是专为在 USB 电源规范内工作而设计的。由于采用了内部 MOSFET 架构,所以不需要外部检测电阻器和隔离二极管。热反馈可对充电电流进行调节,以便在大功率操作或高环境温度条件下对芯片温度加以限制·充电电压固定于4.2V,而充电电流可通过一个电阻器进行外部设置。当充电电流在达到最终浮充电压之后降至设定值的1110时,LTC4054 将自动终止充电循环。当输人电压(交流适配器或 USB 电源)被拿掉时,LTC4054自动进人一个低电流状态,将电池电流降至 2μA 以下·可将 LTC4054 置于停机模式,从而将供电电流降至 25uA。LTC4054 的其他特点包括充电电流监控器、欠压闭锁、自动再充电和一个用于指示充电结束和输人电压接人的状态引脚。
上图为:锂电池充电电路 该电路使用LTC4054电池管理芯片对锂电池进行充电,LTC4054是凌特公司的生产的锂电池充电芯片,专门为单节锂电池充电需要设计的集成芯片。外部只需要几个元器件即可,无需专门的散热器,就可以对电池进行充电,充电电流可以通过5脚的电阻进行调节,最大支持600ma的充电电流。下图为芯片充电电流与电阻的对应关系。
1.2 PS7516 升压芯片介绍
PS7516是一个效率高,固定550KHz频率,current mode PWM升压DC-DC转换器。PS7516低输入电压2.0V.内部集成了低RDS(ON)功率MOSFET,所以外部不需要肖特基二极管。使PS7516能做到高的转换效率。适用于锂电池升压5V1A的高效率应用中。
宽输入电压:2.0V~5.5V;高转换效率高达96%;低RDS(ON)集成功率MOSFET;550KHz固定开关频率;轻负载低功耗模式;±2.0%电压精度;PMOS电流限流短路保护;低静态电流;快速瞬态响应;内置软启动功能
过温保护,自恢复功能;过流保护;输出过压保护;超小型封装:SOT23-6,工作温度低
1.3 电池接口 和type-c功能选择电路、
可以选择外部接入3.7V锂电池对整个电路板进行供电,通过升压芯片为整个电路提供5V的电压,这样外部只需要一块锂电池就可以完成整个电路电压稳定;当电池电路不足时,可以使用type-c对电池进行充电,也可以使用type-c直接给电路板供电,改电路经过实际的测试,不过在使用的时候需要注意下,需要使PS7516处于升压状态,即PS7516输出端电压需要高于供电电压(锂电池),否则PS7516会处于降压状态,这时候,该芯片的电压纹波比较大,不能使用单片机的通讯功能。
1.4 2.5V基准电压电路
工作原理:TL431是一种三端可调分流并联稳压器,它被广泛应用于电源电路中,提供稳定的参考电压。TL431的内部结构包括一个2.5V的基准电压源、一个运放和一个输出开关管。它的工作原理基于运放的反馈机制,通过调整参考端电压来控制输出电压。
基本特性:TL431具有良好的温度稳定性,典型的动态输出阻抗为0.2Ω。它能够在1-100mA的阴极电流调节范围内工作,提供2.5V至36V的可调稳压输出。这使得TL431可以用于多种电路设计,包括并联稳压器、串联稳压器、开关调整控制电路和作为参考电压源。
工作机制:当TL431的参考端电压高于2.5V时,内部的运放输出高电平,导致输出开关管导通,从而将阴极和阳极之间形成导通路径。这时,阴极电压会被拉低,需要在电源正极和阴极之间接一个限流电阻。当参考端电压低于2.5V时,运放输出低电平,输出开关管截止,此时TL431的输出电压等于电源电压。
应用电路:在实际应用中,TL431可以通过外接电阻来设定输出电压。例如,在2.5V稳压电路中,将TL431的阴极和参考端连接在一起,通过调整输入电压和限流电阻,可以使输出电压稳定在2.5V。在可调稳压电路中,通过改变参考端和阴极之间的分压电阻值,可以实现不同的稳压输出。
1.5 ADS1256 芯片周围电路及其外部采样电路:
DS1256是TI(德州仪器)公司推出的一款微功耗、高精度、8通道、24位高性能模数转换器(ADC)。以下是对ADS1256的详细介绍:
1.5.1 主要特点:高精度与低噪声:
ADS1256具有24位分辨率,能提供高达23位无噪声分辨力,确保在各种测量应用中数据的精确性。
低噪声可编程增益放大器(PGA)以二进制步进提供1至64的增益,输入参考噪声为27nV。
多通道输入:该器件支持8个单端输入或4个差分输入(两者不可同时使用),可同时采集多路信号。
高速采样率:最大数据输出速率高达30kSPS(次采样/秒),满足快速数据采集的要求。
灵活的输入与配置:灵活的输入多路复用器处理差分或单端信号,包含用于验证连接到输入的外部传感器完整性的电路。
可编程滤波器允许用户在高达23位无噪声的分辨率和高达30kSPS的数据速率之间进行优化。
功耗管理:在正常工作模式下功耗低至38mW,待机模式下功耗进一步降低至0.4mW,有利于降低整体能耗和热管理问题。
校准与接口:提供板载校准,支持所有PGA设置的偏移和增益误差的自我校正和系统校正。通过SPI兼容串行接口进行通信,方便与各种数字系统进行数据交换。
电源需求:模拟供电为标准的5V,数字供电范围广,从1.8V至3.6V均可,为与其他电子系统的设计兼容提供了便利。
1.5.2 应用领域
ADS1256的高精度和低噪声特性使其成为多种高精度测量应用的理想选择,如应变计、气体分析、仪器仪表、压力传感器、血液分析以及医疗科学仪器等。
1.5.3 技术规格(部分)
分辨率和精度:24位分辨率,高达23位无噪声分辨力。采样率:最大30kSPS。输入通道:8个单端输入或4个差分输入。非线性:十万分之一(最大值)。功耗:正常模式下38mW,待机模式下0.4mW。
1.6 屏幕显示电路:
采用0.96寸的SPI屏幕进行数据显示
二:软件部分:
2.1 ADS1256底层驱动代码
ADS1256_VAR_T ADS1256 = {0}; static const uint8_t s_tabDataRate[ADS1256_DRATE_MAX] = { 0xF0, /* 复位时缺省值 */ 0xE0, 0xD0, 0xC0, 0xB0, 0xA1, 0x92, 0x82, 0x72, 0x63, 0x53, 0x43, 0x33, 0x20, 0x13, 0x03 }; //SPIx 读写一个字节 //TxData:要写入的字节 //返回值:读取到的字节 unsigned char SPIx_ReadWriteByte(unsigned char TxData) { // uint8_t buf; // HAL_SPI_TransmitReceive(&hspi1,&TxData,&buf,1,1000); // return buf; unsigned int retry=0; __HAL_SPI_ENABLE(&hspi2); while((SPI2->SR&1<<1)==0)//等待发送区空 { retry++; if(retry>2000)return 0; } SPI2->DR=TxData; //发送一个byte retry=0; while((SPI2->SR&1<<0)==0) //等待接收完一个byte { retry++; if(retry>2000)return 0; } return SPI2->DR; //返回收到的数据 } void ADS1256_ResetHard(void) { ADS1256_RESET_LOW; delay_ms(5); ADS1256_RESET_HIGH; delay_ms(5); } void ADS1256_INIT(ADS1256_GAIN_E _gain, ADS1256_DRATE_E _drate) { uint8_t ReadRate = 0; HAL_NVIC_DisableIRQ(EXTI15_10_IRQn); ADS1256_ResetHard(); delay_us(1); waitDRDY(); setPGA(_gain); delay_us(1); setDataRate(s_tabDataRate[_drate]); delay_us(1); ReadRate = readByteFromReg(REG_DRATE); while(ReadRate != s_tabDataRate[_drate]) { ReadRate = readByteFromReg(REG_DRATE); writeByteToReg(REG_DRATE, s_tabDataRate[_drate]); } setDIFFChannel(7,8); delay_us(1); writeByteToReg(REG_STATUS, 0x06); //高位在前 开启自动校准 关闭模拟缓冲区 delay_us(1); waitDRDY(); CS_0(); SPIx_ReadWriteByte(CMD_SYNC); SPIx_ReadWriteByte(CMD_WAKEUP); CS_1(); HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); } int32_t ADS1256_BACK(void) { int32_t Sum = 0; int16_t buf = 0; while(!DRDY_IS_LOW()); setDIFFChannel(3,4); CS_0(); SPIx_ReadWriteByte(CMD_SYNC); SPIx_ReadWriteByte(CMD_WAKEUP); SPIx_ReadWriteByte(CMD_RDATA); delay_us(2); buf |= (SPIx_ReadWriteByte(0) << 8); buf |= (SPIx_ReadWriteByte(0) ); Sum = ((int32_t)buf) << 8; Sum |= SPIx_ReadWriteByte(0); CS_1(); return Sum; } void setChannel(uint8_t ch) { switch(ch) { case 0: setDIFFChannel(2, 1); break; case 1: setDIFFChannel(1, 0); break; case 2: setDIFFChannel(3, 4); break; case 3: setDIFFChannel(4, 5); break; case 4: setDIFFChannel(6, 7); break; case 5: setDIFFChannel(7, 8); break; } } void setpga(uint8_t pga) { switch(pga) { case 0: setPGA(ADS1256_GAIN_1); ADS1256.Gain[0] = ADS1256_GAIN_1; break; case 1: setPGA(ADS1256_GAIN_32); ADS1256.Gain[1] = ADS1256_GAIN_32; break; case 2: setPGA(ADS1256_GAIN_1); ADS1256.Gain[2] = ADS1256_GAIN_1; break; case 3: setPGA(ADS1256_GAIN_32); ADS1256.Gain[3] = ADS1256_GAIN_32; break; case 4: setPGA(ADS1256_GAIN_16); ADS1256.Gain[4] = ADS1256_GAIN_16; break; case 5: setPGA(ADS1256_GAIN_1); ADS1256.Gain[5] = ADS1256_GAIN_1; break; } } extern int buf1 ; void ADS1256_BACK_IRQ(void) { int32_t Sum = 0; int16_t buf = 0; setChannel(ADS1256.Channel); CS_0(); SPIx_ReadWriteByte(CMD_SYNC); SPIx_ReadWriteByte(CMD_WAKEUP); SPIx_ReadWriteByte(CMD_RDATA); delay_us(2); buf |= (SPIx_ReadWriteByte(0) << 8); buf |= (SPIx_ReadWriteByte(0) ); Sum = ((int32_t)buf) << 8; Sum |= SPIx_ReadWriteByte(0); CS_1(); delay_us(2); setpga(ADS1256.Channel); if(ADS1256.Channel == 0) { ADS1256.AdcNow[5] = Sum;/* 注意保存的是上一个通道的数据 */ } else { ADS1256.AdcNow[ADS1256.Channel - 1] = Sum; } if(++ADS1256.Channel >= 6) ADS1256.Channel = 0; // writeByteToReg(REG_STATUS, 0x06); //高位在前 开启自动校准 关闭模拟缓冲区 // delay_us(1); // waitDRDY(); // delay_us(2000); buf1 ++ ; } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == GPIO_PIN_11) { HAL_NVIC_DisableIRQ(EXTI15_10_IRQn); ADS1256_BACK_IRQ(); HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_11); } } /* ********************************************************************************************************* * name: setDIFFChannel * function: Write to MUX register - set channel to read from in single-ended mode * Bit 7,6,5,4 determine the positive input channel (AINp). * Bit 3,2,1,0 determine the negative input channel (AINn). e.g. (0-1, 2,3 - 4,5 - 6,7) * parameter: * The return value: val ********************************************************************************************************* */ void setDIFFChannel(uint8_t positiveCh, uint8_t NegativeCh) { writeByteToReg(REG_MUX, positiveCh <<4 | NegativeCh); //xxxx1000 - AINp = positiveCh, AINn = NegativeCh } /* ********************************************************************************************************* * name: writeCMD * function: Send Standalone commands to register * parameter: command * The return value: None ********************************************************************************************************* */ void writeCMD(uint8_t command) { // uint8_t Txbuffer[1]; // Txbuffer[0] = command; CS_0(); SPIx_ReadWriteByte(command); CS_1(); } /* ********************************************************************************************************* * name: setDataRate * function: sampling rate of collection * parameter: pga * The return value: None ********************************************************************************************************* */ void setDataRate(uint8_t drate) { writeByteToReg(REG_DRATE,drate); } /** ********************************************************************************************************* * name: writeByteToReg * function: read 1 byte from register address registerID. * parameter: register ID * The return value: ********************************************************************************************************* */ void writeByteToReg(uint8_t registerID, uint8_t value) { uint8_t Txbuffer[3]; Txbuffer[0] = CMD_WREG | registerID; Txbuffer[1] = 0x00; Txbuffer[2] = value; CS_0(); SPIx_ReadWriteByte(Txbuffer[0]); SPIx_ReadWriteByte(Txbuffer[1]); SPIx_ReadWriteByte(Txbuffer[2]); /* send8bit(CMD_WREG | registerID); //1syt byte: address of the first register to write send8bit(0x00); //2nd byte: number of byte to write = 1. send8bit(value); //3rd byte: value to write to register */ CS_1(); } /* ********************************************************************************************************* * name: setPGA * function: Set gain of amplifier * parameter: pga * The return value: None ********************************************************************************************************* */ void setPGA(uint8_t pga) { writeByteToReg(REG_ADCON,pga); } /* ********************************************************************************************************* * name: Send8bit * function: SPI send data to SPI slave * parameter: data * The return value: NULL ********************************************************************************************************* */ void send8bit(uint8_t data) { SPIx_ReadWriteByte(data); } /* ********************************************************************************************************* * name: waitDRDY * function: Wait for DRDY is Low * parameter: data * The return value: None ********************************************************************************************************* */ void waitDRDY(void) { uint32_t i; for (i = 0; i < 40000000; i++){ if (DRDY_IS_LOW()){ break; } } } /* ********************************************************************************************************* * name: readChipID * function: Get data from Status register - chipID "check" * parameter: * The return value: val ********************************************************************************************************* */ uint8_t readChipID(void) { waitDRDY(); volatile uint8_t id = readByteFromReg(REG_STATUS); return (id >> 4); } /* ********************************************************************************************************* * name: receive8bit * function: receive data from SPI slave * parameter: data * The return value: NULL ********************************************************************************************************* */ uint8_t receive8bit(void) { /* uint8_t TXbuffer[1]; uint8_t RXbuffer[1]; TXbuffer[0] = 0xff; HAL_SPI_Transmit(&hspi1, TXbuffer ,1,50); HAL_SPI_Receive(&hspi1, RXbuffer ,1,50); return RXbuffer[0]; */ uint8_t send_data = 0xff; uint8_t read = 0; read = SPIx_ReadWriteByte(send_data); return read; } /* ********************************************************************************************************* * name: readByteFromReg * function: read 1 byte from register address registerID. * parameter: register ID * The return value: ********************************************************************************************************* */ uint8_t readByteFromReg(uint8_t registerID) { uint8_t TXbuffer[2]; TXbuffer[0] = CMD_RREG | registerID; TXbuffer[1] = 0x00; CS_0(); SPIx_ReadWriteByte(TXbuffer[0]); SPIx_ReadWriteByte(TXbuffer[1]); delay_us(10); uint8_t read = receive8bit(); CS_1(); return read; } /* ********************************************************************************************************* * name: setBuffer * function: Set the internal buffer (True-enable), (Fasle-disable) * parameter: bool val * The return value: val ********************************************************************************************************* */ void setBuffer(void) { uint8_t val = 1; uint8_t Txbuffer[2]; Txbuffer[0] = CMD_WREG | REG_STATUS; Txbuffer[1] = (0 <<3) | (1 << 2) | (val << 1); CS_0(); SPIx_ReadWriteByte(Txbuffer[0]); SPIx_ReadWriteByte(Txbuffer[1]); //send8bit(CMD_WREG | REG_STATUS); //send8bit((0 <<3) | (1 << 2) | (val << 1)); CS_1(); }
2.2 OLED屏显示部分驱动代码
u8 OLED_GRAM[128][8]; //SPIx 读写一个字节 //TxData:要写入的字节 //返回值:读取到的字节 unsigned char SPI1_ReadWriteByte(unsigned char TxData) { // uint8_t buf; // HAL_SPI_TransmitReceive(&hspi1,&TxData,&buf,1,1000); // return buf; unsigned int retry=0; __HAL_SPI_ENABLE(&hspi1); while((SPI1->SR&1<<1)==0)//等待发送区空 { retry++; if(retry>2000)return 0; } SPI1->DR=TxData; //发送一个byte retry=0; while((SPI1->SR&1<<0)==0) //等待接收完一个byte { retry++; if(retry>2000)return 0; } return SPI1->DR; //返回收到的数据 } //发送一个字节 void OLED_WR_Byte(u8 dat,u8 cmd) { if(cmd) { OLED_DC_Set(); } else { OLED_DC_Clr(); } OLED_CS_Clr(); SPI1_ReadWriteByte(dat);//检查接收标志位 delay_us(1); OLED_DC_Set(); OLED_CS_Set(); } //反显函数 void OLED_ColorTurn(u8 i) { if(i==0) { OLED_WR_Byte(0xA6,OLED_CMD);//正常显示 } if(i==1) { OLED_WR_Byte(0xA7,OLED_CMD);//反色显示 } } //屏幕旋转180度 void OLED_DisplayTurn(u8 i) { if(i==0) { OLED_WR_Byte(0xC8,OLED_CMD);//正常显示 OLED_WR_Byte(0xA1,OLED_CMD); } if(i==1) { OLED_WR_Byte(0xC0,OLED_CMD);//反转显示 OLED_WR_Byte(0xA0,OLED_CMD); } } //开启OLED显示 void OLED_DisPlay_On(void) { OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能 OLED_WR_Byte(0x14,OLED_CMD);//开启电荷泵 OLED_WR_Byte(0xAF,OLED_CMD);//点亮屏幕 } //关闭OLED显示 void OLED_DisPlay_Off(void) { OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能 OLED_WR_Byte(0x10,OLED_CMD);//关闭电荷泵 OLED_WR_Byte(0xAE,OLED_CMD);//关闭屏幕 } //更新显存到OLED void OLED_Refresh(void) { u8 i,n; for(i=0;i<8;i++) { OLED_WR_Byte(0xb0+i,OLED_CMD); //设置行起始地址 OLED_WR_Byte(0x00,OLED_CMD); //设置低列起始地址 OLED_WR_Byte(0x10,OLED_CMD); //设置高列起始地址 for(n=0;n<128;n++) OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA); } } //清屏函数 void OLED_Clear(void) { u8 i,n; for(i=0;i<8;i++) { for(n=0;n<128;n++) { OLED_GRAM[n][i]=0;//清除所有数据 } } // OLED_Refresh();//更新显示 } //画点 //x:0~127 //y:0~63 void OLED_DrawPoint(u8 x,u8 y) { u8 i,m,n; i=y/8; m=y%8; n=1<<m; OLED_GRAM[x][i]|=n; } //画线 //x:0~127 //y:0~63 void OLED_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2) { u8 i,k,k1,k2; if(x1==x2) //画竖线 { for(i=0;i<(y2-y1);i++) { OLED_DrawPoint(x1,y1+i); } } else if(y1==y2) //画横线 { for(i=0;i<(x2-x1);i++) { OLED_DrawPoint(x1+i,y1); } } else //画斜线 { k1=y2-y1; k2=x2-x1; k=k1*10/k2; for(i=0;i<(x2-x1);i++) { OLED_DrawPoint(x1+i,y1+i*k/10); } } } //x,y:圆心坐标 //r:圆的半径 void OLED_DrawCircle(u8 x,u8 y,u8 r) { int a, b,num; a = 0; b = r; while(2 * b * b >= r * r) { OLED_DrawPoint(x + a, y - b); OLED_DrawPoint(x - a, y - b); OLED_DrawPoint(x - a, y + b); OLED_DrawPoint(x + a, y + b); OLED_DrawPoint(x + b, y + a); OLED_DrawPoint(x + b, y - a); OLED_DrawPoint(x - b, y - a); OLED_DrawPoint(x - b, y + a); a++; num = (a * a + b * b) - r*r;//计算画的点离圆心的距离 if(num > 0) { b--; a--; } } } //在指定位置显示一个字符,包括部分字符 //x:0~127 //y:0~63 //size:选择字体 12/16/24 //mode: 0:正常模式 1:反白显示 void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size1,u8 mode) { u8 i,m,temp,size2,chr1; u8 y0=y; size2=(size1/8+((size1%8)?1:0))*(size1/2); //得到字体一个字符对应点阵集所占的字节数 chr1=chr-' '; //计算偏移后的值 for(i=0;i<size2;i++) { if(size1==12) {temp=asc2_1206[chr1][i];} //调用1206字体 else if(size1==16) {temp=asc2_1608[chr1][i];} //调用1608字体 else if(size1==24) {temp=asc2_2412[chr1][i];} //调用2412字体 else return; temp = (mode == 0) ? temp : ~temp; for(m=0;m<8;m++) //写入数据 { if(temp&0x80) {OLED_DrawPoint(x,y);} temp<<=1; y++; if((y-y0)==size1) { y=y0; x++; break; } } } } //显示字符串 //x,y:起点坐标 //size1:字体大小 //*chr:字符串起始地址 void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1,u8 mode) { while((*chr>=' ')&&(*chr<='~'))//判断是不是非法字符! { OLED_ShowChar(x,y,*chr,size1,mode); x+=size1/2; if(x>128-size1) //换行 { x=0; y+=2; } chr++; } } //m^n u32 OLED_Pow(u8 m,u8 n) { u32 result=1; while(n--) { result*=m; } return result; } ////显示2个数字 ////x,y :起点坐标 ////len :数字的位数 ////size:字体大小 void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1,u8 mode) { u8 t,temp; for(t=0;t<len;t++) { temp=(num/OLED_Pow(10,len-t-1))%10; if(temp==0) { OLED_ShowChar(x+(size1/2)*t,y,'0',size1,mode); } else { OLED_ShowChar(x+(size1/2)*t,y,temp+'0',size1,mode); } } } //显示汉字 //x,y:起点坐标 //num:汉字对应的序号 void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size1) { u8 i,m,n=0,temp,chr1; u8 x0=x,y0=y; u8 size3=size1/8; while(size3--) { chr1=num*size1/8+n; n++; for(i=0;i<size1;i++) { if(size1==16) {temp=Hzk1[chr1][i];}//调用16*16字体 else if(size1==24) {temp=Hzk2[chr1][i];}//调用24*24字体 else if(size1==32) {temp=Hzk3[chr1][i];}//调用32*32字体 else if(size1==64) {temp=Hzk4[chr1][i];}//调用64*64字体 else return; for(m=0;m<8;m++) { if(temp&0x01) {OLED_DrawPoint(x,y);} temp>>=1; y++; } x++; if((x-x0)==size1) {x=x0;y0=y0+8;} y=y0; } } } void OLED_ShowChinese_HZ12(u8 x,u8 y,u8 num) { u8 i,m,temp,chr1; u8 x0=x,y0=y; chr1 = num * 2; for(i=0;i<12;i++) { temp=Hzk5[chr1][i]; for(m=0;m<8;m++) { if(temp&0x01) {OLED_DrawPoint(x,y);} temp>>=1; y++; } x++; y = y0; } x=x0;y=y0+8; chr1 = num * 2 + 1; for(i=0;i<12;i++) { temp=Hzk5[chr1][i]; for(m=0;m<4;m++) { if(temp&0x01) {OLED_DrawPoint(x,y);} temp>>=1; y++; } x++; y = y0+8; } } //num 显示汉字的个数 //space 每一遍显示的间隔 void OLED_ScrollDisplay(u8 num,u8 space) { u8 i,n,t=0,m=0,r; while(1) { if(m==0) { OLED_ShowChinese(128,24,t,16); //写入一个汉字保存在OLED_GRAM[][]数组中 t++; } if(t==num) { for(r=0;r<16*space;r++) //显示间隔 { for(i=0;i<144;i++) { for(n=0;n<8;n++) { OLED_GRAM[i-1][n]=OLED_GRAM[i][n]; } } OLED_Refresh(); } t=0; } m++; if(m==16){m=0;} for(i=0;i<144;i++) //实现左移 { for(n=0;n<8;n++) { OLED_GRAM[i-1][n]=OLED_GRAM[i][n]; } } OLED_Refresh(); } } //配置写入数据的起始位置 void OLED_WR_BP(u8 x,u8 y) { OLED_WR_Byte(0xb0+y,OLED_CMD);//设置行起始地址 OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD); OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD); } //x0,y0:起点坐标 //x1,y1:终点坐标 //BMP[]:要写入的图片数组 void OLED_ShowPicture(u8 x0,u8 y0,u8 x1,u8 y1,u8 BMP[]) { u32 j=0; u8 x=0,y=0; if(y%8==0)y=0; else y+=1; for(y=y0;y<y1;y++) { OLED_WR_BP(x0,y); for(x=x0;x<x1;x++) { OLED_WR_Byte(BMP[j],OLED_DATA); j++; } } } //OLED的初始化 void OLED_Init(void) { OLED_RST_Set(); OLED_RST_Clr();//复位 delay_ms(200); OLED_RST_Set(); OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel 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 Set Mapping RAM Display Start Line (0x00~0x3F) OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register OLED_WR_Byte(0xff,OLED_CMD);// Set SEG Output Current Brightness OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常 OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常 OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64) OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F) OLED_WR_Byte(0x00,OLED_CMD);//-not offset OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration OLED_WR_Byte(0x12,OLED_CMD); OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh OLED_WR_Byte(0x70,OLED_CMD);//Set VCOM Deselect Level OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02) OLED_WR_Byte(0x02,OLED_CMD);// OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5) OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) OLED_WR_Byte(0xAF,OLED_CMD); OLED_Clear(); }
1.3 数据计算部分代码:
VI_BUF_T VI_Buffer={ .First_V_Offset = -203, .First_I_Offset = 4800, .Second_V_Offset = -130, .Second_I_Offset = -300 }; void First_V_CAL(void) { VI_Buffer.First_V_Offset = ADS1256.AdcNow[0]; } void First_I_CAL(void) { VI_Buffer.First_I_Offset = ADS1256.AdcNow[1]; } void Second_V_CAL(void) { VI_Buffer.Second_V_Offset = ADS1256.AdcNow[2]; } void Second_I_CAL(void) { VI_Buffer.Second_I_Offset = ADS1256.AdcNow[3]; } void VI_Handle(void) { VI_Buffer.First_V_value = (ADS1256.AdcNow[0]-VI_Buffer.First_V_Offset)/1.0/FULL_Range/pow(2,ADS1256.Gain[0])*2*REF2_5 \ *(First_V_UP + First_V_DOWN)/(First_V_DOWN) * xishu; VI_Buffer.First_I_value = (ADS1256.AdcNow[1]-VI_Buffer.First_I_Offset)/1.0/FULL_Range/pow(2,ADS1256.Gain[1])*2*REF2_5 \ /First_I_R; VI_Buffer.Second_V_value = (ADS1256.AdcNow[2]-VI_Buffer.Second_V_Offset)*1.0/FULL_Range/pow(2,ADS1256.Gain[2])*2*REF2_5 \ *(Second_V_UP + Second_V_DOWN)/(Second_V_DOWN); VI_Buffer.Second_I_value = (ADS1256.AdcNow[3]-VI_Buffer.Second_I_Offset)*1.0/FULL_Range/pow(2,ADS1256.Gain[3])*2*REF2_5 \ /Second_I_R; VI_Buffer.First_V_value = fabsf(VI_Buffer.First_V_value); VI_Buffer.Second_V_value = fabsf(VI_Buffer.Second_V_value); VI_Buffer.First_P_value = VI_Buffer.First_V_value * fabsf(VI_Buffer.First_I_value); VI_Buffer.Second_P_value = VI_Buffer.Second_V_value * fabsf(VI_Buffer.Second_I_value); if(VI_Buffer.First_P_value > 0.01 && VI_Buffer.Second_P_value > 0.01) VI_Buffer.VI_EFF = VI_Buffer.First_P_value > VI_Buffer.Second_P_value ? (VI_Buffer.Second_P_value/VI_Buffer.First_P_value)*100 \ : (VI_Buffer.First_P_value/VI_Buffer.Second_P_value)*100 ; else VI_Buffer.VI_EFF = 0; }
1.4 界面显示及其按键处理部分
meun_t meun={ .meun_Id1 = 0, .meun_Id2 = 0, .meun_Id1_max = 6, .meun_Id2_max = 0, .meun_button = Idle, .meun_select = 1, .meun_select_max = 1, .meun_layer = 0, .set.meun_set_idischarge = 4000, .set.meun_set_icharge = 1000, .set.meun_light_state = 1, .set.meun_set_light_time = 5, .set.meun_light_time = 10 }; void meun_disp_1(void); void meun_disp_2(void); void Function_key_en(void); void meun_disp_once(void); void meun_disp_3(void); void meun_disp_4(void); void meun_disp_5(void); void meun_disp_6(void); //发送按键状态值 void send_button_value(button_type value) { meun.meun_button = value; } //主界面 void MEUN_HOME(void) { static uint8_t state = 0; char buf[10]={0}; OLED_DrawLine(0,0,0,63); OLED_DrawLine(0,0,127,0); OLED_DrawLine(127,0,127,64); OLED_DrawLine(0,63,128,63); OLED_DrawLine(2,2,2,61); OLED_DrawLine(2,2,125,2); OLED_DrawLine(125,2,125,62); OLED_DrawLine(2,61,126,61); //第一行 OLED_ShowString(5,5,(uint8_t *)"OUT1",12,0); OLED_ShowString(29,5,(uint8_t *)":",12,0); sprintf(buf,"%05.2fV",VI_Buffer.First_V_value); OLED_ShowString(35,5,(uint8_t *)buf,12,0); sprintf(buf,"%06.3fA",VI_Buffer.First_I_value); OLED_ShowString(76,5,(uint8_t *)buf,12,0); //第二行 OLED_ShowString(5,19,(uint8_t *)"OUT2",12,0); OLED_ShowString(29,19,(uint8_t *)":",12,0); sprintf(buf,"%05.2fV",VI_Buffer.Second_V_value); OLED_ShowString(35,19,(uint8_t *)buf,12,0); sprintf(buf,"%06.3fA",VI_Buffer.Second_I_value); OLED_ShowString(76,19,(uint8_t *)buf,12,0); //第三行 OLED_ShowChinese_HZ12(5,33,18); OLED_ShowChinese_HZ12(17,33,15); OLED_ShowString(29,33,(uint8_t *)":",12,0); sprintf(buf,"%6.2f%%",VI_Buffer.VI_EFF); OLED_ShowString(35,33,(uint8_t *)buf,12,0); if(state <= 1) { OLED_ShowString(110,33,(uint8_t *)"\\",12,0); } else if(state <= 3) { OLED_ShowString(110,33,(uint8_t *)"/",12,0); } else if(state <= 5) { OLED_ShowString(110,33,(uint8_t *)"-",12,0); } state ++; if(state > 5) state = 0; //第四行 OLED_ShowChinese_HZ12(5,47,14); OLED_ShowChinese_HZ12(17,47,15); OLED_ShowString(29,47,(uint8_t *)":",12,0); if(VI_Buffer.First_P_value > 100) { sprintf(buf,"%5.1fW",VI_Buffer.First_P_value); } else { sprintf(buf,"%05.2fW",VI_Buffer.First_P_value); } OLED_ShowString(35,47,(uint8_t *)buf,12,0); if(VI_Buffer.Second_P_value > 100) { sprintf(buf,"%5.1fW",VI_Buffer.Second_P_value); } else { sprintf(buf,"%05.2fW",VI_Buffer.Second_P_value); } OLED_ShowString(82,47,(uint8_t *)buf,12,0); } //页脚显示 void MEUN_Footer(unsigned char type) { OLED_DrawLine(2,52,125,52); OLED_DrawLine(4,57,8,57); OLED_DrawLine(4,58,8,58); OLED_DrawLine(4,59,8,59); OLED_DrawLine(4,60,8,60); if(type == 0) OLED_ShowString(12,53,(uint8_t *)"EN",12,0); else if(type == 1) OLED_ShowString(12,53,(uint8_t *)"TAB",12,0); OLED_DrawLine(44,57,48,57); OLED_DrawLine(44,58,48,58); OLED_DrawLine(44,59,48,59); OLED_DrawLine(44,60,48,60); OLED_DrawLine(52,57,56,57); OLED_DrawLine(52,58,56,58); OLED_DrawLine(52,59,56,59); OLED_DrawLine(52,60,56,60); OLED_ShowString(60,53,(uint8_t *)"BA",12,0); OLED_DrawLine(84,57,96,57); OLED_DrawLine(84,58,96,58); OLED_DrawLine(84,59,96,59); OLED_DrawLine(84,60,96,60); if(type == 0) OLED_ShowString(100,53,(uint8_t *)"TAB",12,0); else if(type == 1) OLED_ShowString(100,53,(uint8_t *)"EN",12,0); } void meun_disp(void) { if(meun.meun_layer == 0) { //主界面 MEUN_HOME(); } else if(meun.meun_layer == 1) { switch(meun.meun_Id1) { case 1: MEUN_Header(); MEUN_Footer(0); OLED_ShowChinese(24,24,0,16); OLED_ShowChinese(40,24,1,16); OLED_ShowChinese(56,24,2,16); OLED_ShowChinese(72,24,9,16); OLED_ShowChinese(88,24,10,16); break; case 2: MEUN_Header(); MEUN_Footer(0); OLED_ShowChinese(24,24,3,16); OLED_ShowChinese(40,24,4,16); OLED_ShowChinese(56,24,5,16); OLED_ShowChinese(72,24,9,16); OLED_ShowChinese(88,24,10,16); break; case 3: MEUN_Header(); MEUN_Footer(0); OLED_ShowChinese(24,24,6,16); OLED_ShowChinese(40,24,7,16); OLED_ShowChinese(56,24,8,16); OLED_ShowChinese(72,24,9,16); OLED_ShowChinese(88,24,10,16); break; case 4: MEUN_Header(); MEUN_Footer(0); OLED_ShowChinese(16,24,11,16); OLED_ShowChinese(32,24,12,16); OLED_ShowChinese(48,24,13,16); OLED_ShowChinese(64,24,14,16); OLED_ShowChinese(80,24,15,16); OLED_ShowChinese(96,24,16,16); break; case 5: MEUN_Header(); MEUN_Footer(0); OLED_ShowChinese(16,24,20,16); OLED_ShowChinese(32,24,0,16); OLED_ShowChinese(48,24,0,16); OLED_ShowChinese(64,24,22,16); OLED_ShowChinese(80,24,15,16); OLED_ShowChinese(96,24,16,16); break; case 6: MEUN_Header(); MEUN_Footer(0); OLED_ShowChinese(16,24,21,16); OLED_ShowChinese(32,24,0,16); OLED_ShowChinese(48,24,0,16); OLED_ShowChinese(64,24,22,16); OLED_ShowChinese(80,24,15,16); OLED_ShowChinese(96,24,16,16); break; default: break; } } else if(meun.meun_layer == 2) { if(meun.meun_Id2_max != 0) { switch(meun.meun_Id2) { case 1: break; default: break; } } else { switch(meun.meun_Id1) { case 1: MEUN_Header(); MEUN_Footer(1); meun_disp_1(); break; case 2: MEUN_Header(); MEUN_Footer(1); meun_disp_2(); break; case 3: MEUN_Header(); MEUN_Footer(1); meun_disp_3(); break; case 4: MEUN_Header(); MEUN_Footer(1); meun_disp_4(); break; case 5: MEUN_Header(); MEUN_Footer(1); meun_disp_5(); break; case 6: MEUN_Header(); MEUN_Footer(1); meun_disp_6(); break; default: break; } } } else if(meun.meun_layer == 3) { } } void Function_key_en(void) { if(meun.meun_select == 0 || meun.meun_select_max == 0) return ; switch(meun.meun_Id1) { case 4: switch(meun.meun_select) { case 1: meun.set.meun_set_light_time = (meun.set.meun_set_light_time + 1) > 60 ? 5:(meun.set.meun_set_light_time + 1); break; case 2: meun.set.meun_set_light_time = (meun.set.meun_set_light_time + 5) > 60 ? 5:(meun.set.meun_set_light_time + 5); break; case 3: meun.set.meun_set_light_time = (meun.set.meun_set_light_time + 20) > 60 ? 5:(meun.set.meun_set_light_time + 20); break; case 4: meun.set.meun_set_light_time = (meun.set.meun_set_light_time - 1) < 5 ? 60:(meun.set.meun_set_light_time - 1); break; case 5: meun.set.meun_set_light_time = (meun.set.meun_set_light_time - 5) < 5 ? 60:(meun.set.meun_set_light_time - 5); break; case 6: meun.set.meun_set_light_time = (meun.set.meun_set_light_time - 20) < 5 ? 60:(meun.set.meun_set_light_time - 20); break; } break; case 5: switch(meun.meun_select) { case 1: meun.set.meun_set_icharge = (meun.set.meun_set_icharge + 100) > 10000 ? 500:(meun.set.meun_set_icharge + 100); break; case 2: meun.set.meun_set_icharge = (meun.set.meun_set_icharge + 500) > 10000 ? 500:(meun.set.meun_set_icharge + 500); break; case 3: meun.set.meun_set_icharge = (meun.set.meun_set_icharge + 2000) > 10000 ? 500:(meun.set.meun_set_icharge + 2000); break; case 4: meun.set.meun_set_icharge = (meun.set.meun_set_icharge - 100) < 500 ? 10000:(meun.set.meun_set_icharge - 100); break; case 5: meun.set.meun_set_icharge = (meun.set.meun_set_icharge - 500) < 500 ? 10000:(meun.set.meun_set_icharge - 500); break; case 6: meun.set.meun_set_icharge = (meun.set.meun_set_icharge - 2000) < 500 ? 10000:(meun.set.meun_set_icharge - 2000); break; } break; case 6: switch(meun.meun_select) { case 1: meun.set.meun_set_idischarge = (meun.set.meun_set_idischarge + 100) > 16000 ? 100:(meun.set.meun_set_idischarge + 100); break; case 2: meun.set.meun_set_idischarge = (meun.set.meun_set_idischarge + 500) > 16000 ? 100:(meun.set.meun_set_idischarge + 500); break; case 3: meun.set.meun_set_idischarge = (meun.set.meun_set_idischarge + 2000) > 16000 ? 100:(meun.set.meun_set_idischarge + 2000); break; case 4: meun.set.meun_set_idischarge = (meun.set.meun_set_idischarge - 100) < 100 ? 16000:(meun.set.meun_set_idischarge - 100); break; case 5: meun.set.meun_set_idischarge = (meun.set.meun_set_idischarge - 500) < 100 ? 16000:(meun.set.meun_set_idischarge - 500); break; case 6: meun.set.meun_set_idischarge = (meun.set.meun_set_idischarge - 2000) < 100 ? 16000:(meun.set.meun_set_idischarge - 2000); break; } // PL5500_SET_IDISCHARGE(meun.set.meun_set_idischarge); break; } } //设置界面显示1:电烙铁模式 void meun_disp_1(void) { uint8_t x=25,y=35,x1=5,y1=15; char buf[10]; meun.meun_select_max = 4; OLED_ShowChinese_HZ12(x,y,34); OLED_ShowChinese_HZ12(x+12,y,35); OLED_ShowChinese_HZ12(x+12*2,y,36); OLED_ShowString(x+12*3,y,(uint8_t *)":",12,0); // sprintf(buf,"%4.1fV",PL5500.OUT_V/1000.0); // OLED_ShowString(x+12*3+6,y,(uint8_t *)buf,12,0); switch(meun.meun_select) { case 1: OLED_ShowString(x1,y1,(uint8_t *)"05V",16,1); OLED_ShowString(x1+30,y1,(uint8_t *)"12V",16,0); OLED_ShowString(x1+30*2,y1,(uint8_t *)"20V",16,0); OLED_ShowString(x1+30*3,y1,(uint8_t *)"24V",16,0); break; case 2: OLED_ShowString(x1,y1,(uint8_t *)"05V",16,0); OLED_ShowString(x1+30,y1,(uint8_t *)"12V",16,1); OLED_ShowString(x1+30*2,y1,(uint8_t *)"20V",16,0); OLED_ShowString(x1+30*3,y1,(uint8_t *)"24V",16,0); break; case 3: OLED_ShowString(x1,y1,(uint8_t *)"05V",16,0); OLED_ShowString(x1+30,y1,(uint8_t *)"12V",16,0); OLED_ShowString(x1+30*2,y1,(uint8_t *)"20V",16,1); OLED_ShowString(x1+30*3,y1,(uint8_t *)"24V",16,0); break; case 4: OLED_ShowString(x1,y1,(uint8_t *)"05V",16,0); OLED_ShowString(x1+30,y1,(uint8_t *)"12V",16,0); OLED_ShowString(x1+30*2,y1,(uint8_t *)"20V",16,0); OLED_ShowString(x1+30*3,y1,(uint8_t *)"24V",16,1); break; } } //设置界面显示2:笔记本模式 void meun_disp_2(void) { uint8_t x=25,y=35,x1=25,y1=15; char buf[10]; meun.meun_select_max = 2; OLED_ShowChinese_HZ12(x,y,34); OLED_ShowChinese_HZ12(x+12,y,35); OLED_ShowChinese_HZ12(x+12*2,y,36); OLED_ShowString(x+12*3,y,(uint8_t *)":",12,0); // sprintf(buf,"%4.1fV",PL5500.OUT_V/1000.0); // OLED_ShowString(x+12*3+6,y,(uint8_t *)buf,12,0); switch(meun.meun_select) { case 1: OLED_ShowString(x1,y1,(uint8_t *)"19.5V",16,1); OLED_ShowString(x1+30*2,y1,(uint8_t *)"20V",16,0); break; case 2: OLED_ShowString(x1,y1,(uint8_t *)"19.5V",16,0); OLED_ShowString(x1+30*2,y1,(uint8_t *)"20V",16,1); break; } } //设置界面显示3:自定义模式 void meun_disp_3(void) { uint8_t x=25,y=35,x1=11,y1=17; char buf[10]; meun.meun_select_max = 6; OLED_ShowChinese_HZ12(x,y,34); OLED_ShowChinese_HZ12(x+12,y,35); OLED_ShowChinese_HZ12(x+12*2,y,36); OLED_ShowString(x+12*3,y,(uint8_t *)":",12,0); // sprintf(buf,"%4.1fV",PL5500.OUT_V/1000.0); // OLED_ShowString(x+12*3+6,y,(uint8_t *)buf,12,0); switch(meun.meun_select) { case 1: OLED_ShowString(x1,y1,(uint8_t *)"+0.1V",12,1); OLED_ShowString(x1+40,y1,(uint8_t *)"+0.5V",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"+2.0V",12,0); break; case 2: OLED_ShowString(x1,y1,(uint8_t *)"+0.1V",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"+0.5V",12,1); OLED_ShowString(x1+40*2,y1,(uint8_t *)"+2.0V",12,0); break; case 3: OLED_ShowString(x1,y1,(uint8_t *)"+0.1V",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"+0.5V",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"+2.0V",12,1); break; case 4: OLED_ShowString(x1,y1,(uint8_t *)"-0.1V",12,1); OLED_ShowString(x1+40,y1,(uint8_t *)"-0.5V",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"-2.0V",12,0); break; case 5: OLED_ShowString(x1,y1,(uint8_t *)"-0.1V",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"-0.5V",12,1); OLED_ShowString(x1+40*2,y1,(uint8_t *)"-2.0V",12,0); break; case 6: OLED_ShowString(x1,y1,(uint8_t *)"-0.1V",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"-0.5V",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"-2.0V",12,1); break; } } //设置界面显示4:背光时间 void meun_disp_4(void) { uint8_t x=25,y=35,x1=11,y1=17; char buf[10]; meun.meun_select_max = 6; OLED_ShowChinese_HZ12(x,y,34); OLED_ShowChinese_HZ12(x+12,y,35); OLED_ShowChinese_HZ12(x+12*2,y,36); OLED_ShowString(x+12*3,y,(uint8_t *)":",12,0); sprintf(buf,"%2dS",meun.set.meun_set_light_time); OLED_ShowString(x+12*3+6,y,(uint8_t *)buf,12,0); switch(meun.meun_select) { case 1: OLED_ShowString(x1,y1,(uint8_t *)"+1S",12,1); OLED_ShowString(x1+40,y1,(uint8_t *)"+5S",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"+20S",12,0); break; case 2: OLED_ShowString(x1,y1,(uint8_t *)"+1S",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"+5S",12,1); OLED_ShowString(x1+40*2,y1,(uint8_t *)"+20S",12,0); break; case 3: OLED_ShowString(x1,y1,(uint8_t *)"+1S",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"+5S",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"+20S",12,1); break; case 4: OLED_ShowString(x1,y1,(uint8_t *)"-1S",12,1); OLED_ShowString(x1+40,y1,(uint8_t *)"-5S",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"-20S",12,0); break; case 5: OLED_ShowString(x1,y1,(uint8_t *)"-1S",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"-5S",12,1); OLED_ShowString(x1+40*2,y1,(uint8_t *)"-20S",12,0); break; case 6: OLED_ShowString(x1,y1,(uint8_t *)"-1S",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"-5S",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"-20S",12,1); break; } } void meun_disp_5(void) { uint8_t x=25,y=35,x1=11,y1=17; char buf[10]; meun.meun_select_max = 6; OLED_ShowChinese_HZ12(x,y,34); OLED_ShowChinese_HZ12(x+12,y,35); OLED_ShowChinese_HZ12(x+12*2,y,36); OLED_ShowString(x+12*3,y,(uint8_t *)":",12,0); sprintf(buf,"%4.1fA",meun.set.meun_set_icharge/1000.0); OLED_ShowString(x+12*3+6,y,(uint8_t *)buf,12,0); switch(meun.meun_select) { case 1: OLED_ShowString(x1,y1,(uint8_t *)"+0.1A",12,1); OLED_ShowString(x1+40,y1,(uint8_t *)"+0.5A",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"+2A",12,0); break; case 2: OLED_ShowString(x1,y1,(uint8_t *)"+0.1A",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"+0.5A",12,1); OLED_ShowString(x1+40*2,y1,(uint8_t *)"+2A",12,0); break; case 3: OLED_ShowString(x1,y1,(uint8_t *)"+0.1A",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"+0.5A",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"+2A",12,1); break; case 4: OLED_ShowString(x1,y1,(uint8_t *)"-0.1A",12,1); OLED_ShowString(x1+40,y1,(uint8_t *)"-0.5A",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"-2A",12,0); break; case 5: OLED_ShowString(x1,y1,(uint8_t *)"-0.1A",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"-0.5A",12,1); OLED_ShowString(x1+40*2,y1,(uint8_t *)"-2A",12,0); break; case 6: OLED_ShowString(x1,y1,(uint8_t *)"-0.1A",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"-0.5A",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"-2A",12,1); break; } } void meun_disp_6(void) { uint8_t x=25,y=35,x1=11,y1=17; char buf[10]; meun.meun_select_max = 6; OLED_ShowChinese_HZ12(x,y,34); OLED_ShowChinese_HZ12(x+12,y,35); OLED_ShowChinese_HZ12(x+12*2,y,36); OLED_ShowString(x+12*3,y,(uint8_t *)":",12,0); sprintf(buf,"%4.1fA",meun.set.meun_set_idischarge/1000.0); OLED_ShowString(x+12*3+6,y,(uint8_t *)buf,12,0); switch(meun.meun_select) { case 1: OLED_ShowString(x1,y1,(uint8_t *)"+0.1A",12,1); OLED_ShowString(x1+40,y1,(uint8_t *)"+0.5A",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"+2A",12,0); break; case 2: OLED_ShowString(x1,y1,(uint8_t *)"+0.1A",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"+0.5A",12,1); OLED_ShowString(x1+40*2,y1,(uint8_t *)"+2A",12,0); break; case 3: OLED_ShowString(x1,y1,(uint8_t *)"+0.1A",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"+0.5A",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"+2A",12,1); break; case 4: OLED_ShowString(x1,y1,(uint8_t *)"-0.1A",12,1); OLED_ShowString(x1+40,y1,(uint8_t *)"-0.5A",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"-2A",12,0); break; case 5: OLED_ShowString(x1,y1,(uint8_t *)"-0.1A",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"-0.5A",12,1); OLED_ShowString(x1+40*2,y1,(uint8_t *)"-2A",12,0); break; case 6: OLED_ShowString(x1,y1,(uint8_t *)"-0.1A",12,0); OLED_ShowString(x1+40,y1,(uint8_t *)"-0.5A",12,0); OLED_ShowString(x1+40*2,y1,(uint8_t *)"-2A",12,1); break; } }
3.3电路原理图和PCB效果图
PCB图:
最后实物测试图片: