void LCD1602_ShowNum(unsigned char x,unsigned char y,unsigned char *str,unsigned char i);

时间: 2023-08-08 11:09:09 浏览: 626
这是一个用于在LCD1602上显示数字的函数,函数原型如下: ```c void LCD1602_ShowNum(unsigned char x, unsigned char y, unsigned char *str, unsigned char i); ``` 函数参数说明: - `x`:数字在LCD上显示的起始列位置,取值范围为0~15。 - `y`:数字在LCD上显示的起始行位置,取值为0或1。 - `str`:要显示的数字的字符数组,数组中每个元素存储一个数字字符。 - `i`:要显示的数字的位数,取值范围为1~4。 函数实现: ```c void LCD1602_ShowNum(unsigned char x, unsigned char y, unsigned char *str, unsigned char i) { unsigned char j; for(j=0; j<i; j++) { LCD1602_WriteData(x+j, y, str[j]); } } ``` 该函数通过调用`LCD1602_WriteData()`函数将数字一个个显示在LCD屏幕上。注意,`LCD1602_ShowNum()`函数中的参数`str`是一个字符数组,因此在调用该函数时需要将数字转换为字符并存储在数组中。例如,要在LCD屏幕上显示数字1234,可以将其转换为字符数组并传递给`LCD1602_ShowNum()`函数: ```c unsigned char num[4] = {'1', '2', '3', '4'}; LCD1602_ShowNum(0, 0, num, 4); ```
阅读全文

相关推荐

#include <STC89C5xRC.H> #include "I2C.h" #define AT24C02_ADDRESS void AT24c02_WriteByte(unsigned char WordAddress,Date) { unsigned char Ack; I2C_Start(); I2C_SendByte(AT24C02_ADDRESS); Ack=I2C_ReceiveAck(); if(Ack==0)P2=0X00; } void AT24c02_ReadByte(unsigned char WordAddress) { unsigned char Date; return Date; } #ifndef __AT24C02_H__ #define __AT24C02_H__ void AT24c02_WriteByte(unsigned char WordAddress,Date); void AT24c02_ReadByte(unsigned char WordAddress); #endif #include <STC89C5xRC.H> #include "Delay.h" #include "Key.h" #include "LCD1602.h" #include "AT24C02.h" void main() { LCD1602_Init(); LCD1602_ShowString(1,1,"Hello"); AT24c02_WriteByte(0,0); while(1) { } } #include <STC89C5xRC.H> sbit I2C_SCL=P2^1; sbit I2C_SDA=P2^0; void I2C_Start(void) { I2C_SDA=1; I2C_SCL=1; I2C_SDA=0; I2C_SCL=0; } void I2C_Stop(void) { I2C_SDA=0; I2C_SCL=1; I2C_SDA=1; } void I2C_SendByte(unsigned char Byte) { unsigned char i; for(i=0;i<8;i++) { I2C_SendByte=Byte&(0X80>>i); I2C_SCL=1; I2C_SCL=0; } } unsigned char I2C_ReceiveByte(void) { unsigned char i, Byte=0x00; I2C_SDA=1; for(i=0;i<8;i++) { I2C_SCL=1; if(I2C_SDA){Byte|0X80>>i;} I2C_SCL=0; } return Byte; } void I2C_SendAck(unsigned char I2C_bit) { I2C_SDA=I2C_bit; I2C_SCL=1; I2C_SCL=0; } unsigned char I2C_ReceiveAck(void) { unsigned char Byte,I2C_bit; I2C_SDA=1; I2C_SCL=1; I2C_bit=I2C_SDA; return Byte; } #ifndef __I2C_H__ #define __I2C_H__ void I2C_Start(void); void I2C_Stop(void); void I2C_SendByte(unsigned char Byte); unsigned char I2C_ReceiveByte(void); void I2C_SendAck(bit); unsigned char I2C_ReceiveAck(void); #endifBuild started: Project: AT24C02 Build target 'Target 1' compiling AT24c02.c... linking... *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?KEYNUMBER?KEY *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_LCD1602_SHOWCHAR?LCD1602 *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_LCD1602_SHOWNUM?LCD1602 *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_LCD1602_SHOWSIGNEDNUM?LCD1602 *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_LCD1602_SHOWHEXNUM?LCD1602 *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_LCD1602_SHOWBINNUM?LCD1602 *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_AT24C02_READBYTE?AT24C02 *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_I2C_SENDACK?I2C *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL SYMBOL: I2C_SENDACK MODULE: .\Objects\AT24c02.obj (AT24C02) *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL SYMBOL: ?I2C_SENDACK?BIT MODULE: .\Objects\AT24c02.obj (AT24C02) *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: ?I2C_SENDACK?BIT MODULE: .\Objects\AT24c02.obj (AT24C02) ADDRESS: 01FCH *** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: I2C_SENDACK MODULE: .\Objects\AT24c02.obj (AT24C02) ADDRESS: 01FEH Program Size: data=42.1 xdata=0 code=897 ".\Objects\AT24C02" - 0 Error(s), 12 Warning(s). Build Time Elapsed: 00:00:01

根据以下代码获得GY-906的引脚连接位置: #include <regx52.h> unsigned char code str[]={0x00,0x0E,0x0A,0x0E,0x00,0x00,0x00,0x00}; //????: sbit LCD_RS=P3^5; sbit LCD_RW=P2^0; sbit LCD_EN=P3^4; #define LCD_DataPort P0 //????: /** * @brief LCD1602????,12MHz?????1ms * @param ? * @retval ? */ void LCD_Delay() { unsigned char i, j; i = 2; j = 239; do { while (--j); } while (--i); } /** * @brief LCD1602??? * @param Command ?????? * @retval ? */ void LCD_WriteCommand(unsigned char Command) { LCD_RS=0; LCD_RW=0; LCD_DataPort=Command; LCD_EN=1; LCD_Delay(); LCD_EN=0; LCD_Delay(); } /** * @brief LCD1602??? * @param Data ?????? * @retval ? */ void LCD_WriteData(unsigned char Data) { LCD_RS=1; LCD_RW=0; LCD_DataPort=Data; LCD_EN=1; LCD_Delay(); LCD_EN=0; LCD_Delay(); } /** * @brief LCD1602?????? * @param Line ???,??:1~2 * @param Column ???,??:1~16 * @retval ? */ void LCD_SetCursor(unsigned char Line,unsigned char Column) { if(Line==1) { LCD_WriteCommand(0x80|(Column-1)); } else if(Line==2) { LCD_WriteCommand(0x80|(Column-1+0x40)); } } /** * @brief LCD1602????? * @param ? * @retval ? */ void LCD_Init() { LCD_WriteCommand(0x38);//??????,????,5*7?? LCD_WriteCommand(0x0c);//???,???,??? LCD_WriteCommand(0x06);//???????,??????,???? LCD_WriteCommand(0x01);//????,?? } /** * @brief ?LCD1602??????????? * @param Line ???,??:1~2 * @param Column ???,??:1~16 * @param Char ?????? * @retval ? */ void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char) { LCD_SetCursor(Line,Column); LCD_WriteData(Char); } /** * @brief ?LCD1602????????????? * @param Line ?????,??:1~2 * @param Column ?????,??:1~16 * @param String ??????? * @retval ? */ void LCD_ShowString(unsigned char Line,unsigned char Column,char *String) { unsigned char i; LCD_SetCursor(Line,Column); for(i=0;String[i]!='\0';i++) { LCD_WriteData(String[i]); } } /**

#include <STC89C5xRC.H> #include "Key.h" #include "LCD1602.h" #include "AT24C02.h" #include "Delay.h" unsigned char Date; void main() { LCD1602_Init(); LCD1602_ShowString(1,1,"Hello"); AT24c02_WriteByte(1,66); Delay_ms(5); AT24c02_ReadByte(1); LCD1602_ShowNum(2,1,Date,3); while(1) { } } #include <STC89C5xRC.H> #include "I2C.h" #include "Delay.h" #define AT24C02_ADDRESS 0xA0 void AT24c02_WriteByte(unsigned char WordAddress, unsigned char Date) { I2C_Start(); I2C_SendByte(AT24C02_ADDRESS); I2C_ReceiveAck(); I2C_SendByte(WordAddress); I2C_ReceiveAck(); I2C_SendByte(Date); I2C_ReceiveAck(); I2C_Stop(); Delay_ms(10); // 等待写入完成 } unsigned char AT24c02_ReadByte(unsigned char WordAddress) { unsigned char Date; I2C_Start(); I2C_SendByte(AT24C02_ADDRESS); I2C_ReceiveAck(); I2C_SendByte(WordAddress); I2C_ReceiveAck(); I2C_Start(); // 重复启动 I2C_SendByte(AT24C02_ADDRESS | 0x01); I2C_ReceiveAck(); Date = I2C_ReceiveByte(); I2C_SendAck(1); // 发送NACK I2C_Stop(); return Date; }#ifndef __AT24C02_H__ #define __AT24C02_H__ #define AT24C02_ADDRESS 0xA0 // 添加设备地址 void AT24c02_WriteByte(unsigned char WordAddress, unsigned char Date); unsigned char AT24c02_ReadByte(unsigned char WordAddress); #endif #include <STC89C5xRC.H> sbit I2C_SCL=P2^1; sbit I2C_SDA=P2^0; void I2C_Start(void) { I2C_SDA=1; I2C_SCL=1; I2C_SDA=0; I2C_SCL=0; } void I2C_Stop(void) { I2C_SDA=0; I2C_SCL=1; I2C_SDA=1; } void I2C_SendByte(unsigned char Byte) { unsigned char i; for(i=0; i<8; i++) { I2C_SDA = (Byte & (0x80 >> i)) ? 1 : 0; I2C_SCL = 1; I2C_SCL = 0; } } unsigned char I2C_ReceiveByte(void) { unsigned char i, Byte=0x00; I2C_SDA=1; for(i=0;i<8;i++) { I2C_SCL=1; if(I2C_SDA){Byte|0X80>>i;} I2C_SCL=0; } return Byte; } void I2C_SendAck(unsigned char I2C_bit) { I2C_SDA=I2C_bit; I2C_SCL=1; I2C_SCL=0; } bit I2C_ReceiveAck(void) // 返回bit类型更合理 { bit ack; I2C_SDA = 1; // 释放SDA I2C_SCL = 1; ack = I2C_SDA; // 读取ACK I2C_SCL = 0; return ack; } #ifndef __I2C_H__ #define __I2C_H__ void I2C_Start(void); void I2C_Stop(void); void I2C_SendByte(unsigned char Byte); unsigned char I2C_ReceiveByte(void); void I2C_SendAck(bit); unsigned char I2C_ReceiveAck(void); #endifbit AT24c02_WriteByte(unsigned char WordAddress, unsigned char Date) { I2C_Start(); if(I2C_SendByte(AT24C02_ADDRESS)) return 0; // 检测设备应答 // ...后续操作类似增加应答检测 Delay_ms(15); // 符合器件规格要求 }

用MSP430F5529 LauchPad作为是实验板,IAR Embedded Workbench IDE-MSP430为工具,根据要求及下方部分代码完成实验二,给出完整代码。 实验二: 通过对MSP430F5529开发板编程,从IO口产生一个25Hz方波信号,并用AD模块测量该方波信号的峰值幅度值显示于OLED上,要求: 1、利用MSP430定时器和通用IO产生25Hz方波。 2、利用MSP430内部AD测量出该方波峰值幅度并显示在OLED上。 详细要求如下: 1.利用定时器和IO口产生方波 初始化IO口设置,初始化定时器设置并是能中断,编写中断函数内改变IO口的高低电平 2.利用AD测量方波的峰值幅度 设置ADC对应的IO口为复用输入模式,使能参考电压、打开AD转换功能;设置采样时钟源及参数、参考电压大小,使能中断、使能转换,编写ADC12中断函数,在中断函数中读取ADC采样值并对采样值进行转换得到电压实际值。 main.c #include <msp430.h> #include "IIC.h" /********************** PWM波输出端口定义 ***********************/ void init_IO(void) { //指定输出端口选择复用模式 //指定输出端口为输出模式 } /********************* PWM波输出定时器配置 (此代码使用TA0.1输出PWM 由P1.2输出 可自行修改为其他端口) ********************/ int Vpp=0; //幅值 int ccr0= //初始化频率(根据下面的定义自行计算) int ccr1= //初始化占空比 (根据下面定义自行计算) void timer_A0_1_init() //TA0.1输出PWM 由P1.2输出 { //ACLK,增计数 (也可以选择其他时钟源,自行选择) //输出模式7 TA0CCR0 = ccr0; //时钟频率为32768HZ(ACLK) TA0CCR1 = ccr1; //占空比为CCR1/CCR0 } /******************** ADC配置模块 (以下注释配置并不唯一,仅供参考,可以自行选择需要用的寄存器来进行配置) *******************/ void ADC_init() { //AD接入端口复用 //端口输出模式选择为输入 //配置ADC12CTLx使能参考电压 //配置ADC12CTLx打开AD,设置采样时钟 //配置ADC12CTLx配置采样保持、分频系数、时钟源、转换序列 //配置ADC12MCTLx设置参考电压源以及参考电压大小 //配置ADC12IE使能AD中断 //配置ADC12CTLx使能AD转换 } void delayms(int t) //延时t ms { while(t--) { int m=200; while(m--); } } /******************* 计算采样出来的电压值 (提供一种方法,仅供参考,可以自行写) ***************/ int get_Vpp() //得到Vpp { int n; int min=0,max=4095,temp; for(n=0;n<1000;n++) { temp=ADC12MEM0; if(temp<min) min=temp; if(temp>max) max=temp; } return //返回一个计算后的电压值(自行写出计算公式) } void LCD_Show() //LCD显示函数 { LCD_ShowString(8,8,"Vpp=",16); LCD_ShowString(72,8,"mV",16); LCD_ShowNum(40,8,Vpp,4,16); } void init() //初始化 { __enable_interrupt(); init_IO(); timer_A0_1_init(); ADC_init(); LCD_Init(); init_key(); } void main( void ) { WDTCTL = WDTPW + WDTHOLD; //关闭开门狗 init(); //初始化 while(1){ Vpp=get_Vpp(); LCD_Show(); } } 这里是附加的IIC.c代码 #include "msp430.h" #include "IIC.h" #include "font.h" //IIC延时函数 void IIC_delayus(unsigned int i) { unsigned int j,k; for(k=0;k<i;k++) for(j=0;j<4;i++); } //IIC初始化函数 void IIC_ioinit() { P6DIR|=BIT1|BIT5; //配置IIC IO口为输出方向 P6REN|=BIT1|BIT5; //配置IIC IO口使能上拉电阻 } //开始一个IIC通信 void IIC_start() { SCL_HIGH; SDA_HIGH; //IIC_delayus(2); SDA_LOW; //IIC_delayus(2); SCL_LOW; } //停止IIC通信 void IIC_stop() { SCL_LOW; SDA_LOW; //IIC_delayus(2); SCL_HIGH; SDA_HIGH; //IIC_delayus(2); } //IIC发送一个byte void IIC_writebyte(unsigned char IIC_byte) { unsigned char i; for(i=0;i<8;i++) { if(IIC_byte&0x80) SDA_HIGH; else SDA_LOW; SCL_HIGH; SCL_LOW; IIC_byte<<=1; //loop } SDA_HIGH; SCL_HIGH; SCL_LOW; } void IIC_writecmd(unsigned char IIC_command) { IIC_start(); IIC_writebyte(0x78); //Slave address,SA0=0 IIC_writebyte(0x00); //write command IIC_writebyte(IIC_command); IIC_stop(); } void IIC_writedata(unsigned char IIC_data) { IIC_start(); IIC_writebyte(0x78); IIC_writebyte(0x40); //write data IIC_writebyte(IIC_data); IIC_stop(); } /**************************LCD 设置坐标*******************************/ void LCD_Set_Pos(unsigned char x, unsigned char y) { IIC_writecmd(0xb0+y); IIC_writecmd(((x&0xf0)>>4)|0x10); IIC_writecmd((x&0x0f)|0x01); } /***************************LCD复位************************************/ void LCD_CLS(void) { unsigned char y,x; for(y=0;y<8;y++) { IIC_writecmd(0xb0+y); IIC_writecmd(0x01); IIC_writecmd(0x10); for(x=0;x<X_WIDTH;x++) IIC_writedata(0); } } /***************************LCD初始化************************************/ void LCD_Init(void) { IIC_ioinit(); IIC_writecmd(0xAE); //display off IIC_writecmd(0x20); //Set Memory Addressing Mode IIC_writecmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid IIC_writecmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7 IIC_writecmd(0xc8); //Set COM Output Scan Direction IIC_writecmd(0x00);//---set low column address IIC_writecmd(0x10);//---set high column address IIC_writecmd(0x40);//--set start line address IIC_writecmd(0x81);//--set contrast control register IIC_writecmd(0x7f); IIC_writecmd(0xa1);//--set segment re-map 0 to 127 IIC_writecmd(0xa6);//--set normal display IIC_writecmd(0xa8);//--set multiplex ratio(1 to 64) IIC_writecmd(0x3F);// IIC_writecmd(0xa4);//0xa4,Output follows RAM content;0xa5,Output ignores RAM content IIC_writecmd(0xd3);//-set display offset IIC_writecmd(0x00);//-not offset IIC_writecmd(0xd5);//--set display clock divide ratio/oscillator frequency IIC_writecmd(0xf0);//--set divide ratio IIC_writecmd(0xd9);//--set pre-charge period IIC_writecmd(0x22); // IIC_writecmd(0xda);//--set com pins hardware configuration IIC_writecmd(0x12); IIC_writecmd(0xdb);//--set vcomh IIC_writecmd(0x20);//0x20,0.77xVcc IIC_writecmd(0x8d);//--set DC-DC enable IIC_writecmd(0x14);// IIC_writecmd(0xaf);//--turn on oled panel LCD_CLS(); LCD_Set_Pos(0,0); } //在指定位置显示一个字符,包括部分字符 //x:0~127 //y:0~63 //mode:0,反白显示;1,正常显示 //size:选择字体 16/12 void LCD_ShowChar(unsigned char x,unsigned char y,unsigned char chr,unsigned char Char_Size) { unsigned char c=0,i=0; c=chr-' ';//得到偏移后的值 if(x>Max_Column-1) { x=0; y=y+2; } if(Char_Size ==16) { LCD_Set_Pos(x,y); for(i=0;i<8;i++) IIC_writedata(F8X16[c*16+i]); LCD_Set_Pos(x,y+1); for(i=0;i<8;i++) IIC_writedata(F8X16[c*16+i+8]); } else { LCD_Set_Pos(x,y); for(i=0;i<6;i++) IIC_writedata(F6x8[c][i]); } } //显示一个字符号串 void LCD_ShowString(unsigned char x,unsigned char y,unsigned char *chr,unsigned char Char_Size) { unsigned char j=0; while (chr[j]!='\0') { LCD_ShowChar(x,y,chr[j],Char_Size); x+=8; if(x>128) { x=0; y+=2; } j++; } } //m^n函数 unsigned long oled_pow(unsigned char m,unsigned char n) { unsigned long result=1; while(n--)result*=m; return result; } //显示一个数字 void LCD_ShowNum(unsigned char x,unsigned char y,unsigned long num,unsigned char len,unsigned char size2) { unsigned char t,temp; //unsigned char 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) { LCD_ShowChar(x+(size2/2)*t,y,' ',size2); continue; }else enshow=1; }*/ LCD_ShowChar(x+(size2/2)*t,y,temp+'0',size2); } }

MicroLIBmotor.h(17): error C141: syntax error near 'dir', expected ')'lcd1602.h(8): error C231: 'uchar': redefinitionlcd1602.h(9): error C141: syntax error near 'uint', expected 'hdata'main.c(10): error C321: missing '"'motor.h(17): error C141: syntax error near 'dir', expected ')'motor.c(17): error C202: 'P1_0': undefined identifiermotor.c(18): error C202: 'P1_1': undefined identifiermotor.c(19): error C202: 'P1_2': undefined identifiermotor.c(20): error C202: 'P1_3': undefined identifiermotor.h(17): error C141: syntax error near 'dir', expected ')'motor.h(17): error C141: syntax error near 'dir', expected ')'motor.h(17): error C141: syntax error near 'dir', expected ')'lcd1602.h(8): error C231: 'uchar': redefinitionlcd1602.h(9): error C141: syntax error near 'uint', expected 'hdata'lcd1602.c(38): error C236: '_lcd_show_str': different length of parameter listslcd1602.c(73): error C231: 'decimal': redefinitionlcd1602.c(74): error C202: 'decimal_places': undefined identifierlcd1602.c(81): error C202: 'decimal_places': undefined identifier#include "motor.h" #include "delay.h" #include "key.h" #include "typedefs.h" // ??????(???????????) extern uchar speed_level; // ???????? // ????????(???motor.h????,???) #ifndef MOTOR_A #define MOTOR_A P1_0 #define MOTOR_B P1_1 #define MOTOR_C P1_2 #define MOTOR_D P1_3 #endif void motor_init(void) { MOTOR_A = 0; MOTOR_B = 0; MOTOR_C = 0; MOTOR_D = 0; } void motor_step(bool dir); { static uchar phase = 0; const uchar phase_table[8] = {0x08, 0x0C, 0x04, 0x06, 0x02, 0x03, 0x01, 0x09}; if (dir) phase = (phase + 1) % 8; // ?? else phase = (phase + 7) % 8; // ?? MOTOR_A = (phase_table[phase] & 0x01); MOTOR_B = (phase_table[phase] & 0x02); MOTOR_C = (phase_table[phase] & 0x04); MOTOR_D = (phase_table[phase] & 0x08); delay_ms(200 / speed_level); // ?????????? } #ifndef __MOTOR_H__ #define __MOTOR_H__ #include <STC89C5xRC.H> #include "typedefs.h" // ???????? #ifndef MOTOR_A #define MOTOR_A P1_0 #define MOTOR_B P1_1 #define MOTOR_C P1_2 #define MOTOR_D P1_3 #endif // ???? void motor_init(void); void motor_step(uint8_t dir); #endif#include "lcd1602.h" #include "delay.h" #include <STC89C5xRC.H> // ?????????? // ?????? extern uchar mode; extern uchar speed_level; extern float angle; extern float pressure; extern float target_angle; void lcd_init(void) { lcd_write_cmd(0x38); // 8???,2???,5x7?? delay_ms(5); lcd_write_cmd(0x0C); // ???,??? delay_ms(5); lcd_write_cmd(0x06); // ????,?????1 delay_ms(5); lcd_write_cmd(0x01); // ?? delay_ms(5); } void lcd_write_cmd(uchar cmd) { RS = 0; RW = 0; P0 = cmd; EN = 1; delay_us(5); EN = 0; delay_ms(2); } void lcd_write_dat(uchar dat) { RS = 1; RW = 0; P0 = dat; EN = 1; delay_us(5); EN = 0; delay_ms(2); } // ????? void lcd_show_str(uchar *str) { while(*str != '\0') { lcd_write_dat(*str++); } } // ???? void lcd_show_num(uint num, uchar len) { uchar buf[10]; uchar i = 0; if(num == 0) { lcd_write_dat('0'); return; } while(num > 0) { buf[i++] = num % 10 + '0'; num /= 10; } while(i < len) buf[i++] = '0'; // ??????,?????? for(i = i - 1; i != 255; i--) { lcd_write_dat(buf[i]); } } // ????? void lcd_show_float(float num, uchar decimal) { uint integer = (uint)num; float decimal_part = num - integer; uchar i; // ????????? // ??????????????? uint decimal = 1; for(i = 0; i < decimal_places; i++) { decimal_part *= 10; decimal *= 10; } lcd_show_num(integer, 3); lcd_write_dat('.'); lcd_show_num((uint)decimal_part, decimal_places); } // ?????? void update_display() { lcd_write_cmd(0x80); // ?????????? lcd_show_str("M:"); lcd_write_dat(mode ? 'A' : 'S'); // ??:A-??,S-?? lcd_show_str(" S:"); lcd_write_dat(speed_level + '0'); // ?????? lcd_write_cmd(0xC0); // ?????????? lcd_show_str("A:"); lcd_show_float(angle, 2); // ????,??2??? lcd_show_str(" P:"); lcd_show_float(pressure, 2); // ????,??2??? // ??????(???????) if (mode == 1) { lcd_write_cmd(0x8C); lcd_show_str("Ta:"); lcd_show_float(target_angle, 2); } }// lcd1602.h #ifndef __LCD1602_H__ #define __LCD1602_H__ #include <STC89C5xRC.H> #include "motor.h" #include "typedefs.h" typedef unsigned char uchar; typedef unsigned int uint; // ??LCD?? sbit RS = P2^0; sbit RW = P2^1; sbit EN = P2^2; // ????????(????????????) void lcd_init(void); void lcd_write_cmd(uchar cmd); void lcd_write_dat(uchar dat); void lcd_show_str(uchar x, uchar y, const uchar *str); void lcd_show_float(float num, uchar decimal); #endif

/************************************************ // //TWKJ STM32开发板 // //作者: //版本:V1.0 //修改日期:2020/06/30 //程序功能:TFT彩屏显示方法 //V1.0 完成基本功能 ************************************************/ #include "my_lcd_spi_gui.h" #include "my_lcd_spi_font.h" /******************************************************************* * @name :void GUI_DrawPoint(u16 x,u16 y,u16 color) * @date :2018-08-09 * @function :draw a point in LCD screen * @parameters :x:the x coordinate of the point y:the y coordinate of the point color:the color value of the point * @retvalue :None ********************************************************************/ void GUI_DrawPoint(u16 x,u16 y,u16 color) { LCD_SetCursor(x,y);//设置光标位置 LCD_WriteData_16Bit(color); } /***************************************************************************** * @name :void TP_Draw_Big_Point(u16 x,u16 y,u16 color) * @date :2018-08-09 * @function :Draw a big point(2*2) * @parameters :x:Read x coordinate of the point y:Read y coordinate of the point color:the color value of the point * @retvalue :None ******************************************************************************/ void LCD_DrawPoint_big(u16 x,u16 y) { LCD_DrawPoint(x,y);//中心点 LCD_DrawPoint(x+1,y); LCD_DrawPoint(x,y+1); LCD_DrawPoint(x+1,y+1); } /******************************************************************* * @name :void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color) 填充一个矩形 * @function :fill the specified area * @parameters :sx:the bebinning x coordinate of the specified area sy:the bebinning y coordinate of the specified area ex:the ending x coordinate of the specified area ey:the ending y coordinate of the specified area color:the filled color value * @retvalue :None ********************************************************************/ void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color) { u16 i,j; u16 width=ex-sx+1;//得到填充的宽度 u16 height=ey-sy+1;//高度//**All notes can be deleted and modified**// for(i=0;i<height;i++) { for(j=0;j<width;j++) LCD_WriteData_16Bit(color);//写入数据 } LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢复窗口设置为全屏 } /******************************************************************* * @name :void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2) 绘制一条线 * @function :Draw a line between two points * @parameters :x1:the bebinning x coordinate of the line y1:the bebinning y coordinate of the line x2:the ending x coordinate of the line y2:the ending y coordinate of the line * @retvalue :None ********************************************************************/ void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2) { u16 t; int xerr=0,yerr=0,delta_x,delta_y,distance; int incx,incy,uRow,uCol; delta_x=x2-x1; //计算坐标增量 delta_y=y2-y1; uRow=x1; uCol=y1; if(delta_x>0)incx=1; //设置单步方向 else if(delta_x==0)incx=0;//垂直线 else {incx=-1;delta_x=-delta_x;} if(delta_y>0)incy=1; else if(delta_y==0)incy=0;//水平线 else{incy=-1;delta_y=-delta_y;} if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴 else distance=delta_y; for(t=0;t<=distance+1;t++ )//画线输出 { LCD_DrawPoint(uRow,uCol);//画点 //**All notes can be deleted and modified**// if(xerr>distance) { xerr-=distance; uRow+=incx; } if(yerr>distance) { yerr-=distance; uCol+=incy; } } } /***************************************************************************** * @name :void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2) 绘制一个矩形框 * @function :Draw a rectangle * @parameters :x1:the bebinning x coordinate of the rectangle y1:the bebinning y coordinate of the rectangle x2:the ending x coordinate of the rectangle y2:the ending y coordinate of the rectangle * @retvalue :None ******************************************************************************/ void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2) { LCD_DrawLine(x1,y1,x2,y1); LCD_DrawLine(x1,y1,x1,y2); LCD_DrawLine(x1,y2,x2,y2); LCD_DrawLine(x2,y1,x2,y2); } /***************************************************************************** * @name :void LCD_DrawFillRectangle(u16 x1, u16 y1, u16 x2, u16 y2) 填充一个矩形 * @function :Filled a rectangle * @parameters :x1:the bebinning x coordinate of the filled rectangle y1:the bebinning y coordinate of the filled rectangle x2:the ending x coordinate of the filled rectangle y2:the ending y coordinate of the filled rectangle * @retvalue :None ******************************************************************************/ void LCD_DrawRectangle_Fill(u16 x1, u16 y1, u16 x2, u16 y2) { LCD_Fill(x1,y1,x2,y2,FRONT_COLOR); } /***************************************************************************** * @name :void _draw_circle_8(int xc, int yc, int x, int y, u16 c) 圆绘制方法 * @function :8 symmetry circle drawing algorithm (internal call) * @parameters :xc:the x coordinate of the Circular center yc:the y coordinate of the Circular center x:the x coordinate relative to the Circular center y:the y coordinate relative to the Circular center c:the color value of the circle * @retvalue :None ******************************************************************************/ void _draw_circle_8(int xc, int yc, int x, int y, u16 c) { GUI_DrawPoint(xc + x, yc + y, c); GUI_DrawPoint(xc - x, yc + y, c); GUI_DrawPoint(xc + x, yc - y, c); GUI_DrawPoint(xc - x, yc - y, c); GUI_DrawPoint(xc + y, yc + x, c); GUI_DrawPoint(xc - y, yc + x, c); GUI_DrawPoint(xc + y, yc - x, c); GUI_DrawPoint(xc - y, yc - x, c); } /***************************************************************************** * @name :void gui_circle(int xc, int yc,u16 c,int r, int fill) 绘制一个圆 实心或空心 * @function :Draw a circle of specified size at a specified location * @parameters :xc:the x coordinate of the Circular center yc:the y coordinate of the Circular center r:Circular radius fill:1-filling,0-no filling * @retvalue :None ******************************************************************************/ void LCD_DrawCircle(int xc, int yc,int r, int fill) { int x = 0, y = r, yi, d; d = 3 - 2 * r; if (fill) { // 如果填充(画实心圆) while (x <= y) { for (yi = x; yi <= y; yi++) { _draw_circle_8(xc, yc, x, yi, FRONT_COLOR); } if (d < 0) { d = d + 4 * x + 6; } else { d = d + 4 * (x - y) + 10; y--; } x++; } } else { // 如果不填充(画空心圆) while (x <= y) { _draw_circle_8(xc, yc, x, y, FRONT_COLOR); if (d < 0) { d = d + 4 * x + 6; } else { d = d + 4 * (x - y) + 10; y--; } x++; } } } /***************************************************************************** * @name :void Draw_Triangel(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2) 绘制一个三角形框 * @function :Draw a triangle at a specified position * @parameters :x0:the bebinning x coordinate of the triangular edge y0:the bebinning y coordinate of the triangular edge x1:the vertex x coordinate of the triangular y1:the vertex y coordinate of the triangular x2:the ending x coordinate of the triangular edge y2:the ending y coordinate of the triangular edge * @retvalue :None ******************************************************************************/ void LCD_DrawTriangel(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2) { LCD_DrawLine(x0,y0,x1,y1); LCD_DrawLine(x1,y1,x2,y2); LCD_DrawLine(x2,y2,x0,y0); } static void _swap(u16 *a, u16 *b) { u16 tmp; tmp = *a; *a = *b; *b = tmp; } /***************************************************************************** * @name :void Fill_Triangel(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2) 绘制一个三角形框填充 * @function :filling a triangle at a specified position * @parameters :x0:the bebinning x coordinate of the triangular edge y0:the bebinning y coordinate of the triangular edge x1:the vertex x coordinate of the triangular y1:the vertex y coordinate of the triangular x2:the ending x coordinate of the triangular edge y2:the ending y coordinate of the triangular edge * @retvalue :None ******************************************************************************/ void LCD_DrawTriangel_Fill(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2) { u16 a, b, y, last; int dx01, dy01, dx02, dy02, dx12, dy12; long sa = 0; long sb = 0; if (y0 > y1) { _swap(&y0,&y1); _swap(&x0,&x1); } if (y1 > y2) { _swap(&y2,&y1); _swap(&x2,&x1); } if (y0 > y1) { _swap(&y0,&y1); _swap(&x0,&x1); } if(y0 == y2) { a = b = x0; if(x1 < a) { a = x1; } else if(x1 > b) { b = x1; } if(x2 < a) { a = x2; } else if(x2 > b) { b = x2; } LCD_Fill(a,y0,b,y0,FRONT_COLOR); return; } dx01 = x1 - x0; dy01 = y1 - y0; dx02 = x2 - x0; dy02 = y2 - y0; dx12 = x2 - x1; dy12 = y2 - y1; if(y1 == y2) { last = y1; } else { last = y1-1; } for(y=y0; y<=last; y++) { a = x0 + sa / dy01; b = x0 + sb / dy02; sa += dx01; sb += dx02; if(a > b) { _swap(&a,&b); } LCD_Fill(a,y,b,y,FRONT_COLOR); } sa = dx12 * (y - y1); sb = dx02 * (y - y0); for(; y<=y2; y++) { a = x1 + sa / dy12; b = x0 + sb / dy02; sa += dx12; sb += dx02; if(a > b) { _swap(&a,&b); } LCD_Fill(a,y,b,y,FRONT_COLOR); } } /***************************************************************************** * @name :void Gui_Drawbmp16(u16 x,u16 y,const unsigned char *p) * @date :2018-08-09 * @function :Display a 16-bit BMP image * @parameters :x:the bebinning x coordinate of the BMP image y:the bebinning y coordinate of the BMP image p:the start address of image array * @retvalue :None ******************************************************************************/ void GUI_Drawbmp16(u16 x,u16 y,const u8 *p) //显示40*40 QQ图片 { int i; unsigned char picH,picL; LCD_SetWindows(x,y,x+40-1,y+40-1);//窗口设置 for(i=0;i<40*40;i++) { picL=*(p+i*2);//数据低位在前 picH=*(p+i*2+1); LCD_WriteData_16Bit(picH<<8|picL); } LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢复显示窗口为全屏 } /***************************************************************************** * @name :void LCD_ShowString(u16 x,u16 y,u8 size,u8 *p,u8 mode) 显示遗传英文字符 只限英文 * @function :Display English string * @parameters :x:the bebinning x coordinate of the English string y:the bebinning y coordinate of the English string p:the start address of the English string size:the size of display character mode:0-no overlying,1-overlying * @retvalue :None ******************************************************************************/ void LCD_JustString(u16 x,u16 y,char *p,u8 size) { while((*p<='~')&&(*p>=' '))//判断是不是非法字符! { if(x>(lcddev.width-1)||y>(lcddev.height-1)) return; LCD_ShowChar(x,y,*p,size,false); x+=size/2; p++; } } /***************************************************************************** * @name :u32 mypow(u8 m,u8 n) * @date :2018-08-09 * @function :get the nth power of m (internal call) * @parameters :m:the multiplier n:the power * @retvalue :the nth power of m ******************************************************************************/ u32 mypow(u8 m,u8 n) { u32 result=1; while(n--)result*=m; return result; } /***************************************************************************** * @name :void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size) * @date :2018-08-09 * @function :Display number * @parameters :x:the bebinning x coordinate of the number y:the bebinning y coordinate of the number num:the number(0~4294967295) len:the length of the display number size:the size of display number * @retvalue :None ******************************************************************************/ void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size) { u8 t,temp; u8 enshow=0; for(t=0;t<len;t++) { temp=(num/mypow(10,len-t-1))%10; if(enshow==0&&t<(len-1)) { if(temp==0) { LCD_ShowChar(x+(size/2)*t,y,' ',size,false); continue; }else enshow=1; } LCD_ShowChar(x+(size/2)*t,y,temp+'0',size,false); } } //计算汉字字模的大小(字节数) u8 My_Font_GetCodeSize_CH(u8 charSize) { return charSize*(charSize/8 + (charSize%8?1:0)); } //计算ASCII字模的大小(字节数) u8 My_Font_GetCodeSize_ASCII(u8 charSize) { //**All notes can be deleted and modified**// return charSize*(charSize/8 + (charSize%8?1:0))*2; } void LCD_ScanLine_Byte(u16 x, u16 y, u8 *charPtr,u8 pointCount,bool overlap) { u8 i; if(pointCount>8) { pointCount = 8; } for(i=0;i>i)))//顺向扫描 { if(overlap) { LCD_DrawPoint(x,y);//画一个点 } else { LCD_WriteData_16Bit(FRONT_COLOR); } } else { if(!overlap) { LCD_WriteData_16Bit(BACK_COLOR); } } x++; } } //显示字符或图片取模后的数据,如自定义特殊字符 void LCD_DrawMatrixCode(u16 x, u16 y, u8 width,u8 high,u8 *charPtr,bool overlap) { u8 i,scanPointCount; u16 x0 = x; LCD_SetWindows(x,y,x+width-1,y+high-1); for(i=0;i<high;i++)//逐行扫描 { scanPointCount = width;//计算出每一行的点数 while(scanPointCount>0)//如果这一行的点数大于7 { if(scanPointCount>7) { LCD_ScanLine_Byte(x,y,charPtr,8,overlap); scanPointCount -= 8; charPtr++; x += 8; } else { LCD_ScanLine_Byte(x,y,charPtr,scanPointCount,overlap); charPtr++; break; } } x = x0; y++; } } /***************************************************************************** * @name :void LCD_ShowChinese(u16 x, u16 y, u8 *s, u8 charSize,u8 mode) * @date :2018-08-09 * @function :Display a single Chinese character * @parameters :x:the bebinning x coordinate of the Chinese character y:the bebinning y coordinate of the Chinese character s:the start address of the Chinese character charSize:size of the Chinese character mode:0-no overlying,1-overlying * @retvalue :None ******************************************************************************/ void LCD_ShowChinese(u16 x, u16 y, u8 *s, u8 charSize,bool overlap) { u8 fontCodeSize,fontCharCount,*fontCodePtr; u16 k;//**All notes can be deleted and modified**// fontCodeSize = My_Font_GetCodeSize_CH(charSize)+2; switch(charSize) { case 12:fontCharCount = ArrayCount(fontGBK12);fontCodePtr = (u8 *)fontGBK12;break; case 16:fontCharCount = ArrayCount(tfont16);fontCodePtr = (u8 *)tfont16;break; case 24:fontCharCount = ArrayCount(tfont24);fontCodePtr = (u8 *)tfont24;break; case 32:fontCharCount = ArrayCount(tfont32);fontCodePtr = (u8 *)tfont32;break; default:break; } for (k=0;k<fontCharCount;k++)//遍历每个字模 { if ((*(fontCodePtr)==*(s))&&(*(fontCodePtr+1)==*(s+1)))//对比字符编码 { fontCodePtr+=2; LCD_DrawMatrixCode(x,y,charSize,charSize,fontCodePtr,overlap); break; //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响 } fontCodePtr += fontCodeSize;//指向下一个字模的地址 } LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢复窗口为全屏 } /***************************************************************************** * @name :void LCD_ShowChar(u16 x,u16 y,u16 fc, u16 bc, u8 num,u8 size,u8 mode) * @date :2018-08-09 * @function :Display a single English character * @parameters :x:the bebinning x coordinate of the Character display position y:the bebinning y coordinate of the Character display position num:the ascii code of display character(0~94) size:the size of display character mode:0-no overlying,1-overlying * @retvalue :None ******************************************************************************/ void LCD_ShowChar(u16 x,u16 y, u8 charCode,u8 charSize,bool overlap) { u8 *matrixPtr; if(x>(lcddev.width-charSize/2)||y>(lcddev.height-charSize)) return; charCode=charCode-' ';//得到偏移后的值 LCD_SetWindows(x,y,x+charSize/2-1,y+charSize-1);//设置单个文字显示窗口 switch(charSize) { case 12:matrixPtr=(u8 *)asc2_1206;break; case 16:matrixPtr=(u8 *)asc2_1608;break; #ifdef ACS_2412 case 24:matrixPtr=(u8 *)asc2_2412;break; #endif #ifdef ACS_3216 case 32:matrixPtr=(u8 *)asc2_3216;break; #endif default:break; } //**All notes can be deleted and modified**// LCD_DrawMatrixCode(x,y,charSize/2,charSize,matrixPtr,overlap); LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢复窗口为全屏 } /***************************************************************************** * @name :void Show_Str(u16 x, u16 y, u16 fc, u16 bc, u8 *str,u8 size,u8 mode) 显示一个字符串 可以为中文 显示的中文取模必须在放到lcd_font.h中 * @function :Display Chinese and English strings * @parameters :x:the bebinning x coordinate of the Chinese and English strings y:the bebinning y coordinate of the Chinese and English strings str:the start address of the Chinese and English strings size:the size of Chinese and English strings mode:0-no overlying,1-overlying * @retvalue :None ******************************************************************************/ void LCD_ShowString(u16 x, u16 y, char *str,u8 charSize,bool overlap) { u16 x0=x; if(charSize>32)// { charSize = 32; } while(*str!=0)//数据未结束 { if((u8)(*str)<0x80) { if(*str=='\r')//回车符号 { y+=charSize; x=x0; if(*(str+1)=='\n')//换行符号 { str++; } } else { LCD_ShowChar(x,y,*str,charSize,overlap); x+=charSize/2; //字符,为全字的一半 } str++; } else//中文 { LCD_ShowChinese(x,y,(u8 *)str,charSize,overlap); str+=2; x+=charSize;//下一个汉字偏移 } } } /***************************************************************************** * @name :void Gui_StrCenter(u16 x, u16 y, u16 fc, u16 bc, u8 *str,u8 size,u8 mode) * @date :2018-08-09 * @function :Centered display of English and Chinese strings * @parameters :x:the bebinning x coordinate of the Chinese and English strings y:the bebinning y coordinate of the Chinese and English strings str:the start address of the Chinese and English strings size:the size of Chinese and English strings mode:0-no overlying,1-overlying * @retvalue :None ******************************************************************************/ void LCD_StrCenter(u16 x, u16 y, char *str,u8 charSize,bool overlap) { u16 len=strlen((const char *)str); u16 x1=(lcddev.width-len*8)/2; LCD_ShowString(x1,y,str,charSize,overlap); } u16 LCD_GetPos_X(u8 charSize,u8 index)// { if(index<=lcddev.width/(charSize>>1)) { return index*(charSize>>1); } return 0; } u16 LCD_GetPos_Y(u8 charSize,u8 index)// { if(index<=lcddev.height/(charSize)) { return index*(charSize); } return 0; }

根据这段代码帮我写一下OLED运行的流程图#ifndef __OLED_I2C_H #define __OLED_I2C_H #include "stm32f10x.h" #include "SysTick.h" #define OLED_ADDRESS 0x78 //默认0x78 //定义IIC总线连接的GPIO端口, 用户只需要修改下面代码即可任意改变SCL和SDA的引脚 #define OLED_SCL PBout(6) //SCL引脚 #define OLED_SDA PBout(7) //SDA引脚 #define OLED_SCL_GPIO_PORT GPIOB /* GPIO端口 */ #define OLED_SCL_RCC RCC_APB2Periph_GPIOB /* GPIO端口时钟 */ #define OLED_SCL_PIN GPIO_Pin_6 /* 连接到SCL时钟线的GPIO */ #define OLED_SDA_GPIO_PORT GPIOB /* GPIO端口 */ #define OLED_SDA_RCC RCC_APB2Periph_GPIOB /* GPIO端口时钟 */ #define OLED_SDA_PIN GPIO_Pin_7 /* 连接到SDA数据线的GPIO */ #define OLED_IIC_SDA_READ() GPIO_ReadInputDataBit(OLED_SDA_GPIO_PORT, OLED_SDA_PIN) /* 读SDA口线状态 */ extern unsigned int HZ; unsigned int GB16_NUM(void); void OLED_IIC_GPIO_Config(void); void OLED_IIC_Start(void); void OLED_IIC_Stop(void); uint8_t OLED_IIC_WaitAck(void); void OLED_Write_IIC_Byte(uint8_t _ucByte); void OLED_Write_IIC_Command(u8 IIC_Command); void OLED_Fill(u8 fill_Data); void OLED_Set_Pos(u8 x, u8 y); void OLED_ON(void); void OLED_OFF(void); void OLED_Clear(void); void OLED_ShowChar(u8 x, u8 y, u8 chr); void OLED_ShowNum(u8 x, u8 y, u32 num, u8 len,u8 mode); void OLED_ShowCH(u8 x, u8 y,u8 *chs); void OLED_Init(void); void OLED_DrawBMP(u8 x0,u8 y0,u8 x1,u8 y1,u8 BMP[]); void OLED_ShowStr6x8(char x,char y, char ch[]); #endif 和#include "OLED_I2C.h" #include "SysTick.h" #include "codetab.h" #include "string.h" unsigned int HZ=0; //返回GB16字库里汉字个数 unsigned int GB16_NUM(void) { unsigned int HZ_NUM; unsigned char *PT; PT = hz_index; while(*PT++ != '\0') { HZ_NUM++; } return HZ_NUM/2; } void OLED_IIC_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(OLED_SCL_RCC|OLED_SDA_RCC, ENABLE); /* 打开GPIO时钟 */ GPIO_InitStructure.GPIO_Pin = OLED_SCL_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; /* 开漏输出 */ GPIO_Init(OLED_SCL_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = OLED_SDA_PIN; GPIO_Init(OLED_SDA_GPIO_PORT, &GPIO_InitStructure); /* 给一个停止信号, 复位IIC总线上的所有设备到待机模式 */ OLED_IIC_Stop(); } static void OLED_IIC_Delay(void) { uint8_t i; /*  下面的时间是通过逻辑分析仪测试得到的。 工作条件:CPU主频72MHz ,MDK编译环境,1级优化 循环次数为10时,SCL频率 = 205KHz 循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us 循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us */ for (i = 0; i < 10; i++); } /* ********************************************************************************************************* * 函 数 名: IIC_Start * 功能说明: CPU发起IIC总线启动信号 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ void OLED_IIC_Start(void) { /* 当SCL高电平时,SDA出现一个下跳沿表示IIC总线启动信号 */ OLED_SDA=1; OLED_SCL=1; OLED_IIC_Delay(); OLED_SDA=0; OLED_IIC_Delay(); OLED_SCL=0; OLED_IIC_Delay(); } /* ********************************************************************************************************* * 函 数 名: IIC_Start * 功能说明: CPU发起IIC总线停止信号 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ void OLED_IIC_Stop(void) { /* 当SCL高电平时,SDA出现一个上跳沿表示IIC总线停止信号 */ OLED_SDA=0; OLED_SCL=1; OLED_IIC_Delay(); OLED_SDA=1; } /* ********************************************************************************************************* * 函 数 名: IIC_WaitAck * 功能说明: CPU产生一个时钟,并读取器件的ACK应答信号 * 形 参:无 * 返 回 值: 返回0表示正确应答,1表示无器件响应 ********************************************************************************************************* */ uint8_t OLED_IIC_WaitAck(void) { uint8_t re; OLED_SDA=1; /* CPU释放SDA总线 */ OLED_IIC_Delay(); OLED_SCL=1; /* CPU驱动SCL = 1, 此时器件会返回ACK应答 */ OLED_IIC_Delay(); if (OLED_IIC_SDA_READ()) /* CPU读取SDA口线状态 */ { re = 1; } else { re = 0; } OLED_SCL=0; OLED_IIC_Delay(); return re; } //向IIC总线写数据 void OLED_Write_IIC_Byte(uint8_t _ucByte) { uint8_t i; /* 先发送字节的高位bit7 */ for (i = 0; i < 8; i++) { if (_ucByte & 0x80) { OLED_SDA=1; } else { OLED_SDA=0; } OLED_IIC_Delay(); OLED_SCL=1; OLED_IIC_Delay(); OLED_SCL=0; if (i == 7) { OLED_SDA=1; // 释放总线 } _ucByte <<= 1; /* 左移一个bit */ OLED_IIC_Delay(); } } //写命令 void OLED_Write_IIC_Command(u8 IIC_Command) { OLED_IIC_Start(); OLED_Write_IIC_Byte(OLED_ADDRESS);//OLED地址 OLED_IIC_WaitAck(); OLED_Write_IIC_Byte(0x00);//寄存器地址 OLED_IIC_WaitAck(); OLED_Write_IIC_Byte(IIC_Command); OLED_IIC_WaitAck(); OLED_IIC_Stop(); } //写数据 void OLED_Write_IIC_Data(u8 IIC_Data) { OLED_IIC_Start(); OLED_Write_IIC_Byte(OLED_ADDRESS);//OLED地址 OLED_IIC_WaitAck(); OLED_Write_IIC_Byte(0x40);//寄存器地址 OLED_IIC_WaitAck(); OLED_Write_IIC_Byte(IIC_Data); OLED_IIC_WaitAck(); OLED_IIC_Stop(); } //OLED全屏填充 void OLED_Fill(u8 fill_Data) { u8 m,n; for(m=0;m<8;m++) { OLED_Write_IIC_Command(0xb0+m); //page0-page1 OLED_Write_IIC_Command(0x00); //low column start address OLED_Write_IIC_Command(0x10); //high column start address for(n=0;n<130;n++) { OLED_Write_IIC_Data(fill_Data); } } } //设置起始点坐标 void OLED_Set_Pos(u8 x, u8 y) { OLED_Write_IIC_Command(0xb0+y); OLED_Write_IIC_Command((((x+2)&0xf0)>>4)|0x10); OLED_Write_IIC_Command(((x+2)&0x0f)|0x01); } //将OLED从休眠中唤醒 void OLED_ON(void) { OLED_Write_IIC_Command(0X8D); //设置电荷泵 OLED_Write_IIC_Command(0X14); //开启电荷泵 OLED_Write_IIC_Command(0XAF); //OLED唤醒 } //让OLED休眠 -- 休眠模式下,OLED功耗不到10uA void OLED_OFF(void) { OLED_Write_IIC_Command(0X8D); //设置电荷泵 OLED_Write_IIC_Command(0X10); //关闭电荷泵 OLED_Write_IIC_Command(0XAE); //OLED休眠 } //清屏 void OLED_Clear(void) { OLED_Fill(0x00); } //在指定位置显示一个字符,包括部分字符 //x:0~127 //y:0~63 void OLED_ShowChar(u8 x, u8 y, u8 chr) { u8 c = 0, i = 0; c = chr - ' '; //得到偏移后的值 if(x > 130 - 1) { x = 0; y = y + 2; } OLED_Set_Pos(x, y); for(i = 0; i < 8; i++) OLED_Write_IIC_Data(zf[c * 16 + i]); OLED_Set_Pos(x, y + 1); for(i = 0; i < 8; i++) OLED_Write_IIC_Data(zf[c * 16 + i + 8]); } //m^n函数 u32 oled_pow(u8 m, u8 n) { u32 result = 1; while(n--)result *= m; return result; } //显示个数字 //x,y :起点坐标 //len :数字的位数 //num:数值(0~4294967295); //mode: 为1:显示0 为0:显示空格 void OLED_ShowNum(u8 x, u8 y, u32 num, u8 len,u8 mode) { u8 t, temp; for(t = 0; t < len; t++) { temp = (num / oled_pow(10, len - t - 1)) % 10; if(temp == 0) { if(mode) OLED_ShowChar(x + 8*t, y, '0'); else OLED_ShowChar(x + 8*t, y, ' '); continue; } else OLED_ShowChar(x + 8*t, y, temp + '0'); } } //显示中英文字符 void OLED_ShowCH(u8 x, u8 y,u8 *chs) { u32 i=0; u32 j; char* m; while (*chs != '\0') { if (*chs > 0xa0) //汉字内码都是大于0xa0 { for (i=0 ;i < HZ;i++) { if(x>112) { x=0; y=y+2; } if ((*chs == hz_index[i*2]) && (*(chs+1) == hz_index[i*2+1])) { OLED_Set_Pos(x, y); for(j=0;j<16;j++) OLED_Write_IIC_Data(hz[i*32+j]); OLED_Set_Pos(x,y+1); for(j=0;j<16;j++) OLED_Write_IIC_Data(hz[i*32+j+16]); x +=16; break; } } chs+=2; } else { if(x>122) { x=0; y=y+2; } m=strchr(zf_index,*chs); if (m!=NULL) { OLED_Set_Pos(x, y); for(j = 0; j < 8; j++) OLED_Write_IIC_Data(zf[((u8)*m-' ') * 16 + j]); OLED_Set_Pos(x, y + 1); for(j = 0; j < 8; j++) OLED_Write_IIC_Data(zf[((u8)*m-' ') * 16 + j + 8]); x += 8; } chs++; } } } void OLED_ShowStr6x8(char x,char y, char ch[]) { char TextSize=1; char c = 0,i = 0,j = 0; switch(TextSize) { case 1: { while(ch[j] != '\0') { c = ch[j] - 32; if(x > 126) { x = 0; y++; } OLED_Set_Pos(x,y); for(i=0;i<6;i++) OLED_Write_IIC_Data(F6x8[c][i]); x += 6; j++; } }break; } } //初始化SSD1306 void OLED_Init(void) { HZ= GB16_NUM(); OLED_IIC_GPIO_Config(); OLED_Write_IIC_Command(0xAE); //--display off OLED_Write_IIC_Command(0x00); //---set low column address OLED_Write_IIC_Command(0x10); //---set high column address OLED_Write_IIC_Command(0x40); //--set start line address OLED_Write_IIC_Command(0xB0); //--set page address OLED_Write_IIC_Command(0x81); // contract control OLED_Write_IIC_Command(0xFF); //--128 OLED_Write_IIC_Command(0xA1); //set segment remap OLED_Write_IIC_Command(0xA6); //--normal / reverse OLED_Write_IIC_Command(0xA8); //--set multiplex ratio(1 to 64) OLED_Write_IIC_Command(0x3F); //--1/32 duty OLED_Write_IIC_Command(0xC8); //Com scan direction OLED_Write_IIC_Command(0xD3); //-set display offset OLED_Write_IIC_Command(0x00); // OLED_Write_IIC_Command(0xD5); //set osc division OLED_Write_IIC_Command(0x80); // OLED_Write_IIC_Command(0xD8); //set area color mode off OLED_Write_IIC_Command(0x05); // OLED_Write_IIC_Command(0xD9); //Set Pre-Charge Period OLED_Write_IIC_Command(0xF1); // OLED_Write_IIC_Command(0xDA); //set com pin configuartion OLED_Write_IIC_Command(0x12); // OLED_Write_IIC_Command(0xDB); //set Vcomh OLED_Write_IIC_Command(0x30); // OLED_Write_IIC_Command(0x8D); //set charge pump enable OLED_Write_IIC_Command(0x14); // OLED_Write_IIC_Command(0xAF); //--turn on oled panel } // x0,y0 -- 起始点坐标(x0:0~127, y0:0~7); x1,y1 -- 起点对角线(结束点)的坐标(x1:1~128,y1:1~8) void OLED_DrawBMP(u8 x0,u8 y0,u8 x1,u8 y1,u8 BMP[]) { u16 j=0; u8 x,y; if(y1%8==0) y = y1/8; else y = y1/8 + 1; for(y=y0;y<y1;y++) { OLED_Set_Pos(x0,y); for(x=x0;x<x1;x++) { OLED_Write_IIC_Data(BMP[j++]); } } }

基于stm32cubemx,stm32f103c8t6,kile5mdk,和oled.c,oled.h文件帮我写雨滴传感器的驱动文件rain.c和rain.h,并在main.c中写出显示语句在显示屏上显示,雨量大小,雨滴传感器的AO接PA6,用到的电位器是3362#ifndef __OLED_H_ #define __OLED_H_ #include "stdint.h" #include "i2c.h" void WriteCmd(void); //向设备写控制命令 void OLED_WR_CMD(uint8_t cmd); //向设备写数据 void OLED_WR_DATA(uint8_t data); //初始化oled屏幕 void OLED_Init(void); //清屏 void OLED_Clear(void); //开启OLED显示 void OLED_Display_On(void); //关闭OLED显示 void OLED_Display_Off(void); //设置光标 void OLED_Set_Pos(uint8_t x, uint8_t y); void OLED_On(void); //在指定位置显示一个字符,包括部分字符 //x:0~127 //y:0~63 //mode:0,反白显示;1,正常显示 //size:选择字体 16/12 void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size); //显示2个数字 //x,y :起点坐标 //len :数字的位数 //size:字体大小 //mode:模式 0,填充模式;1,叠加模式 //num:数值(0~4294967295); void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2); //显示一个字符号串 void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size); //显示汉字 //hzk 用取模软件得出的数组 void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no); #endif #include "oled.h" #include "oledfont.h" //几个变量声明 uint8_t **Hzk; //初始化命令 uint8_t CMD_Data[]={ 0xAE, 0x00, 0x10, 0x40, 0xB0, 0x81, 0xFF, 0xA1, 0xA6, 0xA8, 0x3F, 0xC8, 0xD3, 0x00, 0xD5, 0x80, 0xD8, 0x05, 0xD9, 0xF1, 0xDA, 0x12, 0xD8, 0x30, 0x8D, 0x14, 0xAF}; void WriteCmd() { uint8_t i = 0; for(i=0; i<27; i++){ HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,CMD_Data+i,1,0x100); } } //向设备写控制命令 void OLED_WR_CMD(uint8_t cmd) { HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&cmd,1,0x100); } //向设备写数据 void OLED_WR_DATA(uint8_t data) { HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&data,1,0x100); } //初始化oled屏幕 void OLED_Init(void) { HAL_Delay(200); WriteCmd(); } //清屏 void OLED_Clear() { uint8_t i,n; for(i=0;i<8;i++) { OLED_WR_CMD(0xb0+i); OLED_WR_CMD (0x00); OLED_WR_CMD (0x10); for(n=0;n<128;n++) OLED_WR_DATA(0); } } //开启OLED显示 void OLED_Display_On(void) { OLED_WR_CMD(0X8D); //SET DCDC命令 OLED_WR_CMD(0X14); //DCDC ON OLED_WR_CMD(0XAF); //DISPLAY ON } //关闭OLED显示 void OLED_Display_Off(void) { OLED_WR_CMD(0X8D); //SET DCDC命令 OLED_WR_CMD(0X10); //DCDC OFF OLED_WR_CMD(0XAE); //DISPLAY OFF } void OLED_Set_Pos(uint8_t x, uint8_t y) { OLED_WR_CMD(0xb0+y); OLED_WR_CMD(((x&0xf0)>>4)|0x10); OLED_WR_CMD(x&0x0f); } void OLED_On(void) { uint8_t i,n; for(i=0;i<8;i++) { OLED_WR_CMD(0xb0+i); //设置页地址(0~7) OLED_WR_CMD(0x00); //设置显示位置—列低地址 OLED_WR_CMD(0x10); //设置显示位置—列高地址 for(n=0;n<128;n++) OLED_WR_DATA(1); } //更新显示 } unsigned int oled_pow(uint8_t m,uint8_t n) { unsigned int result=1; while(n--)result*=m; return result; } //在指定位置显示一个字符,包括部分字符 //x:0~127 //y:0~63 //mode:0,反白显示;1,正常显示 //size:选择字体 16/12 void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size) { unsigned char c=0,i=0; c=chr-' ';//得到偏移后的值 if(x>128-1){x=0;y=y+2;} if(Char_Size ==16) { OLED_Set_Pos(x,y); for(i=0;i<8;i++) OLED_WR_DATA(F8x16[c*16+i]); OLED_Set_Pos(x,y+1); for(i=0;i<8;i++) OLED_WR_DATA(F8x16[c*16+i+8]); } else { OLED_Set_Pos(x,y); for(i=0;i<6;i++) OLED_WR_DATA(F6x8[c][i]); } } //显示2个数字 //x,y :起点坐标 //len :数字的位数 //size:字体大小 //mode:模式 0,填充模式;1,叠加模式 //num:数值(0~4294967295); void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2) { uint8_t t,temp; uint8_t 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); } } //显示一个字符号串 void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t 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++; } } //显示汉字 //hzk 用取模软件得出的数组 void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no) { uint8_t t,adder=0; OLED_Set_Pos(x,y); for(t=0;t<16;t++) { OLED_WR_DATA(Hzk[2*no][t]); adder+=1; } OLED_Set_Pos(x,y+1); for(t=0;t<16;t++) { OLED_WR_DATA(Hzk[2*no+1][t]); adder+=1; } } /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "adc.h" #include "i2c.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "OLED.h" #include "stdio.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ double yudi=0; int data=0; //sprintf((char *)LCD_r37_adc," R37:%.2fV ",r37); /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_ADC1_Init(); MX_USART1_UART_Init(); MX_I2C1_Init(); MX_ADC2_Init(); /* USER CODE BEGIN 2 */ OLED_Init(); OLED_Display_On();//����OLED��ʾ //���� OLED_Clear(); // OLED_ShowNum(10,10,10,8,8); // OLED_ShowChar(0, 0,'C',16); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_ADC_Start(&hadc2); HAL_ADC_PollForConversion(&hadc2,HAL_MAX_DELAY); yudi= 4095-HAL_ADC_GetValue(&hadc2) * 1000/4095.0; uint8_t A[]="hdilisa !!"; OLED_ShowString(0,0,A,sizeof(A)); //OLED_ShowString(0,2,YUDI,sizeof(YUDI)); char display_str[16]; sprintf(display_str, "data:%.2fL/m2", yudi); // 在OLED指定位置显示(x=0,y=0,10) OLED_ShowString(0, 2, (uint8_t*)display_str,10); } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */

基于stm32cubemx,stm32f103c8t6,四针脚的oled,帮我写雨滴传感器的驱动文件,实现测量雨量大小并在屏幕上,雨量处理数据和显示数据在main.c中写,其中oled.c:#include "oled.h" #include "oledfont.h" //几个变量声明 uint8_t **Hzk; //初始化命令 uint8_t CMD_Data[]={ 0xAE, 0x00, 0x10, 0x40, 0xB0, 0x81, 0xFF, 0xA1, 0xA6, 0xA8, 0x3F, 0xC8, 0xD3, 0x00, 0xD5, 0x80, 0xD8, 0x05, 0xD9, 0xF1, 0xDA, 0x12, 0xD8, 0x30, 0x8D, 0x14, 0xAF}; void WriteCmd() { uint8_t i = 0; for(i=0; i<27; i++){ HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,CMD_Data+i,1,0x100); } } //向设备写控制命令 void OLED_WR_CMD(uint8_t cmd) { HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&cmd,1,0x100); } //向设备写数据 void OLED_WR_DATA(uint8_t data) { HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&data,1,0x100); } //初始化oled屏幕 void OLED_Init(void) { HAL_Delay(200); WriteCmd(); } //清屏size12 size16要清两行,其他函数有类似情况 void OLED_Clear() { uint8_t i,n; for(i=0;i<8;i++) { OLED_WR_CMD(0xb0+i); OLED_WR_CMD (0x00); OLED_WR_CMD (0x10); for(n=0;n<128;n++) OLED_WR_DATA(0); } } //清行 void OLED_Clearrow(uint8_t i) { uint8_t n; OLED_WR_CMD(0xb0+i); OLED_WR_CMD (0x00); OLED_WR_CMD (0x10); for(n=0;n<128;n++) OLED_WR_DATA(0); } //开启OLED显示 void OLED_Display_On(void) { OLED_WR_CMD(0X8D); //SET DCDC命令 OLED_WR_CMD(0X14); //DCDC ON OLED_WR_CMD(0XAF); //DISPLAY ON } //关闭OLED显示 void OLED_Display_Off(void) { OLED_WR_CMD(0X8D); //SET DCDC命令 OLED_WR_CMD(0X10); //DCDC OFF OLED_WR_CMD(0XAE); //DISPLAY OFF } void OLED_Set_Pos(uint8_t x, uint8_t y) { OLED_WR_CMD(0xb0+y); OLED_WR_CMD(((x&0xf0)>>4)|0x10); OLED_WR_CMD(x&0x0f); } void OLED_On(void) { uint8_t i,n; for(i=0;i<8;i++) { OLED_WR_CMD(0xb0+i); //设置页地址(0~7) OLED_WR_CMD(0x00); //设置显示位置—列低地址 OLED_WR_CMD(0x10); //设置显示位置—列高地址 for(n=0;n<128;n++) OLED_WR_DATA(1); } //更新显示 } unsigned int oled_pow(uint8_t m,uint8_t n) { unsigned int result=1; while(n--)result*=m; return result; } //在指定位置显示一个字符,包括部分字符 //x:0~127 //y:0~63 //mode:0,反白显示;1,正常显示 //size:选择字体 16/12 void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size) { unsigned char c=0,i=0; c=chr-' ';//得到偏移后的值 if(x>128-1){x=0;y=y+2;} if(Char_Size ==16) { OLED_Set_Pos(x,y); for(i=0;i<8;i++) OLED_WR_DATA(F8x16[c*16+i]); OLED_Set_Pos(x,y+1); for(i=0;i<8;i++) OLED_WR_DATA(F8x16[c*16+i+8]); } else { OLED_Set_Pos(x,y); for(i=0;i<6;i++) OLED_WR_DATA(F6x8[c][i]); } } //显示2个数字 //x,y :起点坐标 //len :数字的位数 //size:字体大小 //mode:模式 0,填充模式;1,叠加模式 //num:数值(0~4294967295); void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2) { uint8_t t,temp; uint8_t 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); } } //显示一个字符号串 void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t 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++; } } //显示汉字 //hzk 用取模软件得出的数组 void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no) { uint8_t t,adder=0; OLED_Set_Pos(x,y); for(t=0;t<16;t++) { OLED_WR_DATA(Hzk[2*no][t]); adder+=1; } OLED_Set_Pos(x,y+1); for(t=0;t<16;t++) { OLED_WR_DATA(Hzk[2*no+1][t]); adder+=1; } } oled.h:#ifndef __OLED_H_ #define __OLED_H_ #include "stdint.h" #include "i2c.h" void WriteCmd(void); //向设备写控制命令 void OLED_WR_CMD(uint8_t cmd); //向设备写数据 void OLED_WR_DATA(uint8_t data); //初始化oled屏幕 void OLED_Init(void); //清屏 void OLED_Clear(void); //清行 void OLED_Clearrow(uint8_t i); //开启OLED显示 void OLED_Display_On(void); //关闭OLED显示 void OLED_Display_Off(void); //设置光标 void OLED_Set_Pos(uint8_t x, uint8_t y); void OLED_On(void); //在指定位置显示一个字符,包括部分字符 //x:0~127 //y:0~63 //mode:0,反白显示;1,正常显示 //size:选择字体 16/12 void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size); //显示2个数字 //x,y :起点坐标 //len :数字的位数 //size:字体大小 //mode:模式 0,填充模式;1,叠加模式 //num:数值(0~4294967295); void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2); //显示一个字符号串 void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size); //显示汉字 //hzk 用取模软件得出的数组 void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no); #endif main.c:/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** ** This notice applies to any and all portions of this file * that are not between comment pairs USER CODE BEGIN and * USER CODE END. Other portions of this file, whether * inserted by the user or by software development tools * are owned by their respective copyright owners. * * COPYRIGHT(c) 2019 STMicroelectronics * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "i2c.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "oled.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_I2C1_Init(); /* USER CODE BEGIN 2 */ uint8_t A[]="hdilisa !!"; //初始化oled屏幕 OLED_Init(); //开启OLED显示 OLED_Display_On(); //清屏 OLED_Clear(); // OLED_ShowNum(10,10,10,8,8); // OLED_ShowChar(0, 0,'C',16); OLED_ShowString(0,0,A,sizeof(A)); // //清行 // OLED_Clearrow(2); // OLED_Clearrow(3); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /**Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /**Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

#include <reg52.h> #include <intrins.h> #include // 硬件引脚定义 // 电机控制 sbit mor_en1 = P1^2; // 右后轮使能 sbit mor1_1 = P1^3; sbit mor1_2 = P1^4; sbit mor_en2 = P1^7; // 左后轮使能 sbit mor2_1 = P1^5; sbit mor2_2 = P1^6; sbit mor_en3 = P0^2; // 左前轮使能 sbit mor3_1 = P0^3; sbit mor3_2 = P0^4; sbit mor_en4 = P0^7; // 右前轮使能 sbit mor4_1 = P0^5; sbit mor4_2 = P0^6; // 超声波 sbit TRIG = P3^7; sbit ECHO = P3^6; // 红外传感器 sbit MH_Sensor1 = P2^0; sbit MH_Sensor2 = P2^2; // 右 sbit MH_Sensor3 = P2^3; // 中 sbit MH_Sensor4 = P2^4; // 左 // 参数定义 #define PWM_PERIOD 200 #define SPEED_1 30 #define SPEED_2 35 #define SPEED_3 40 #define SPEED_TURN 60 #define STOP 0 #define SAFE_DISTANCE 25 // 安全距离(cm) // 全局变量 unsigned int motor1_duty = 0; unsigned int motor2_duty = 0; unsigned int motor3_duty = 0; unsigned int motor4_duty = 0; unsigned int timer_count = 0; // 函数声明 void Delay(unsigned int xms); void Delay_Us(unsigned char us); unsigned int CSB_GetDistance(); void motor_control(); void UART_Init(); void UART_SendString(char *str); void OLED_Display(unsigned int dist); // 运动控制函数 void stop(); void forward(); void backward(); void turn_left(); void turn_right(); void set_speed(unsigned char speed); /*********************** * 延时函数 ***********************/ void Delay(unsigned int xms) { while(xms--) { unsigned char i, j; i = 2; j = 239; do { while (--j); } while (--i); } } // 微秒级延时(误差±1us) void Delay_Us(unsigned char us) { while (us--) { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } } /*********************** * 超声波测距(不使用定时器) ***********************/ unsigned int CSB_GetDistance() { unsigned int time = 0; // unsigned char i; // 发送触发脉冲 TRIG = 0; Delay_Us(2); TRIG = 1; Delay_Us(10); TRIG = 0; // 等待回波开始 while(!ECHO); // 测量高电平持续时间 while(ECHO) { Delay_Us(1); time++; if(time > 4000) break; // 超时处理(约400cm) } // 计算距离(单位:cm) // 时间(us)/58 = 距离(cm) return time/58; } /*********************** * 电机PWM控制 ***********************/ void motor_control() { // 电机1 PWM mor_en1 = (timer_count < motor1_duty) ? 1 : 0; // 电机2 PWM mor_en2 = (timer_count < motor2_duty) ? 1 : 0; // 电机3 PWM mor_en3 = (timer_count < motor3_duty) ? 1 : 0; // 电机4 PWM mor_en4 = (timer_count < motor4_duty) ? 1 : 0; timer_count++; if(timer_count >= PWM_PERIOD) timer_count = 0; } /*********************** * 运动控制函数 ***********************/ void stop() { mor1_1 = mor1_2 = 0; mor2_1 = mor2_2 = 0; mor3_1 = mor3_2 = 0; mor4_1 = mor4_2 = 0; set_speed(STOP); } void forward() { mor1_1 = 1; mor1_2 = 0; mor2_1 = 1; mor2_2 = 0; mor3_1 = 1; mor3_2 = 0; mor4_1 = 1; mor4_2 = 0; } void backward() { mor1_1 = 0; mor1_2 = 1; mor2_1 = 0; mor2_2 = 1; mor3_1 = 0; mor3_2 = 1; mor4_1 = 0; mor4_2 = 1; } void turn_left() { mor1_1 = 1; mor1_2 = 0; // 右后前进 mor2_1 = 0; mor2_2 = 1; // 左后后退 mor3_1 = 0; mor3_2 = 1; // 左前后退 mor4_1 = 1; mor4_2 = 0; // 右前进 } void turn_right() { mor1_1 = 0; mor1_2 = 1; // 右后后退 mor2_1 = 1; mor2_2 = 0; // 左后前进 mor3_1 = 1; mor3_2 = 0; // 左前进 mor4_1 = 0; mor4_2 = 1; // 右前后退 } void set_speed(unsigned char speed) { motor1_duty = motor2_duty = motor3_duty = motor4_duty = speed; } /*********************** * 避障逻辑 ***********************/ void avoid_obstacle() { unsigned int dist = CSB_GetDistance(); if(dist < SAFE_DISTANCE) { stop(); Delay(200); backward(); Delay(300); // 简单转向策略 turn_left(); Delay(400); } else { forward(); set_speed(SPEED_2); } } /*********************** * 主函数 ***********************/ void main() { // 初始化 TMOD = 0x01; // 定时器0模式1 TH0 = (65536 - 1000) / 256; // 1ms中断 TL0 = (65536 - 1000) % 256; ET0 = 1; EA = 1; TR0 = 1; OLED_Init(); OLED_Clear(); // OLED_ShowString(1, 0, "Ultrasonic Car", 16); while(1) { unsigned int distance = CSB_GetDistance(); // OLED显示距离 OLED_ShowString(2, 1, "Dist:", 16); OLED_ShowNum(2, 3, distance, 8, 16); // OLED_ShowString(2, 9, "cm", 16); // 自动避障 avoid_obstacle(); Delay(100); // 控制循环速度 } } /*********************** * 定时器中断 ***********************/ void timer0_isr() interrupt 1 { TH0 = (65536 - 1000) / 256; TL0 = (65536 - 1000) % 256; motor_control(); // PWM控制 }这个程序为什么距离一直显示0,不会变化

oledfont.h代码为////////////////////////////////////////////////////////////////////////////////// //本程序只供学习使用,未经作者许可,不得用于其它任何用途 /*************************************** * 文件名 :spi_oled.h * 描述 :配置硬件spi驱动oled * 实验平台:基于STM32F103C8T6 * 硬件连接:------------------------OLED 7接口硬件SPI演示例程 // 说明: // ---------------------------------------------------------------- // GND 电源地 // VCC 接5V或3.3v电源 // D0 接PA5(SCL) // D1 接PA7(SDA) // RES 接PB2 // CS 接PB1 // DC 接PB0 // ---------------------------------------------------------------- * 库版本 :V3.5.0 ******************************************************************************/ #ifndef __SPI_OLED_H #define __SPI_OLED_H #include "stc8a8k64d4.h" #include "stdlib.h" #include <stdint.h> //OLED模式设置 //0:4线串行模式 //1:并行8080模式 #define OLED_MODE 0 #define SIZE 16 #define XLevelL 0x00 #define XLevelH 0x10 #define Max_Column 128 #define Max_Row 64 #define Brightness 0xFF #define X_WIDTH 128 #define Y_WIDTH 64 //-----------------OLED端口定义---------------- #define OLED_SCLK_Clr() ClrBits(P1,PIN_5)//CLK #define OLED_SCLK_Set() SetBits(P1,PIN_5) #define OLED_SDIN_Clr() ClrBits(P1,PIN_3)//DIN #define OLED_SDIN_Set() SetBits(P1,PIN_3) #define OLED_RST_Clr() ClrBits(P6,PIN_2)//RES #define OLED_RST_Set() SetBits(P6,PIN_2) #define OLED_DC_Clr() ClrBits(P6,PIN_0)//DC #define OLED_DC_Set() SetBits(P6,PIN_0) #define OLED_CS_Clr() ClrBits(P6,PIN_1)//CS #define OLED_CS_Set() SetBits(P6,PIN_1) #define OLED_CMD 0 //写命令 #define OLED_DATA 1 //写数据 //OLED控制用函数 uint8_t SPI1_WriteByte(uint8_t TxData); void SPI_OLED_WR_Byte(uint8_t dat,uint8_t cmd); void SPI_OLED_Set_Pos(unsigned char x, unsigned char y); void SPI_OLED_Display_On(void); void SPI_OLED_Display_Off(void); void SPI_OLED_Clear(void); void SPI_OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr); void SPI_OLED_ShowNum(uint8_t x,uint8_t y,uint16_t num,uint8_t len,uint8_t size); void SPI_OLED_ShowString(uint8_t x,uint8_t y, char *p); void SPI_OLED_Set_Pos(unsigned char x, unsigned char y); void SPI_OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no); void SPI_OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]); void spi_oled_init(void); #endif main.c文件为/** ****************************************************************************** * @ 名称 SPI OLED屏显示中文实验 * @ 描述 按照如下方式将 OLED 连接到 STC8A8K64D4 * GND 电源地 * VCC 接5V或3.3v电源 * CLK 接P1.5 * MOSI 接P1.3 * RES 接P6.2 * CS 接P6.1 * DC 接P6.0 * * @ 注意 显示坐标与标准二维坐标轴不同,坐标原点的位置跟数学的坐标原点不一样, * 位置从左上角出发,横x轴,竖y轴。OLED显示屏分辨率是128*64,既每行有 * 128个像素点,每列是64个像素点 ****************************************************************************** */ #include "stc8a8k64d4.h" #include <string.h> #include <math.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <delay.h> #include <uart.h> #include <spi_oled.h> void main(void) { serial_init(); //spi1以及oled的初始化 spi_oled_init(); // OLED屏中并没有存储汉字,汉字的显示是通过取模软件生成特定的字库,并将字库信息放在一个二维矩阵作为索引 // 通过不同汉字的索引,点亮特定区域内的像素点来呈现汉字 // 字摸索引位于 oledfont.h 中 // 注意由于51单片机的IRAM空间不多,所以声明字模时需要加上__xdata修饰词, // 将字模放在更大的XRAM中 SPI_OLED_ShowCHinese(0,0,0);//好 SPI_OLED_ShowCHinese(16,0,1);//好 SPI_OLED_ShowCHinese(32,0,2);//学 SPI_OLED_ShowCHinese(48,0,3);//习 SPI_OLED_ShowCHinese(64,0,4);//天 SPI_OLED_ShowCHinese(80,0,5);//天 SPI_OLED_ShowCHinese(96,0,6);//向 SPI_OLED_ShowCHinese(112,0,7);//上 delay_ms(50); SPI_OLED_ShowCHinese(0,2,0);//好 SPI_OLED_ShowCHinese(16,2,1);//好 SPI_OLED_ShowCHinese(32,2,2);//学 SPI_OLED_ShowCHinese(48,2,3);//习 SPI_OLED_ShowCHinese(64,2,4);//天 SPI_OLED_ShowCHinese(80,2,5);//天 SPI_OLED_ShowCHinese(96,2,6);//向 SPI_OLED_ShowCHinese(112,2,7);//上 delay_ms(50); SPI_OLED_ShowCHinese(0,4,0);//好 SPI_OLED_ShowCHinese(16,4,1);//好 SPI_OLED_ShowCHinese(32,4,2);//学 SPI_OLED_ShowCHinese(48,4,3);//习 SPI_OLED_ShowCHinese(64,4,4);//天 SPI_OLED_ShowCHinese(80,4,5);//天 SPI_OLED_ShowCHinese(96,4,6);//向 SPI_OLED_ShowCHinese(112,4,7);//上 delay_ms(50); SPI_OLED_ShowCHinese(0,6,0);//好 SPI_OLED_ShowCHinese(16,6,1);//好 SPI_OLED_ShowCHinese(32,6,2);//学 SPI_OLED_ShowCHinese(48,6,3);//习 SPI_OLED_ShowCHinese(64,6,4);//天 SPI_OLED_ShowCHinese(80,6,5);//天 SPI_OLED_ShowCHinese(96,6,6);//向 SPI_OLED_ShowCHinese(112,6,7);//上 delay_ms(50); while(1) { ; } } 我要怎么修改这两个文件使oled显示器显示的第一行是温度(暂时先空着),第二行是班级(电科232),第三行是名字(喂喂喂),第四行是学号202300324059,

/********************************************************************************************** Copyright 2008 - 2019 深圳市信盈达电子有限公司. All rights reserved. 描述 : 作者 : 何文宾 版本 : V1.0 修改 : 完成日期: 2019年2月17日 信盈达官网:http://www.edu118.com/ 信盈达网校:http://www.edu118.cn/ 信盈达技术论坛:http://bbs.edu118.com/ Notice :本程序只供学习使用,未经作者许可,不得用于其它任何用途。版权所有,盗版必究 ***********************************************************************************************/ /********************************************************************************************** * INCLUDES */ #include "oled.h" #include "systick.h" #include "font.h" #include "rtc.h" /********************************************************************************************** * CONSTANTS */ /********************************************************************************************** * TYPEDEFS */ /********************************************************************************************** * LOCAL VARIABLES */ /********************************************************************************************** * LOCAL FUNCTIONS DECLARE */ /********************************************************************************************** * LOCAL FUNCTIONS */ /********************************************************************************************** * PUBLIC FUNCTIONS */ /******************************************************************* * 函数名: OLED_Init() * 功能描述 : 初始化oled * 作者: 何文宾 * 参数说明: 无 * 返回值说明: 无 * 修改记录: * 其他: *******************************************************************/ /** SCK----PB13 MOSI---PB15 CS-----PA15 DC-----PA11 RES----PA12 */ void OLED_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; SPI_InitTypeDef SPI_InitStruct; /***********************管脚定义********************************************/ if(SPI_MODE) { /*************************硬件SPI*********************************************/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);//使能A&&B时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启AFIO时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);//SPI2时钟使能 /*CS-----PA15*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_CS_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(OLED_GPIO,&GPIO_InitStruct); /*DC-----PA11*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_DC_PIN; GPIO_Init(OLED_GPIO,&GPIO_InitStruct); /*RES-----PA12*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_RES_PIN; GPIO_Init(OLED_GPIO,&GPIO_InitStruct); OLED_RES_H; /*SCK----PB13*/ //复用推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_SCK_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(OLED_SPI_GPIO,&GPIO_InitStruct); /*MOSI---PB15*/ //复用推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_MOSI_PIN; GPIO_Init(OLED_SPI_GPIO,&GPIO_InitStruct); /*MISO---PB14*/ //浮空输入 GPIO_InitStruct.GPIO_Pin = OLED_MISO_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(OLED_SPI_GPIO,&GPIO_InitStruct); SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//波特率 SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;//在时钟第二个电平发送数据 SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;//时钟空闲状态为高电平 SPI_InitStruct.SPI_CRCPolynomial = DISABLE; SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;//8位数据帧 SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//双线双向模式 SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;//先发高位 SPI_InitStruct.SPI_Mode = SPI_Mode_Master;//主机模式 SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;//软件从设备管理 SPI_Init(SPI2,&SPI_InitStruct); SPI_Cmd(SPI2,ENABLE); spi_read_write(0xff); } else { /*软件模拟SPI*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);//使能A&&B时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启AFIO时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); /*SCK----PB13*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_SCK_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(OLED_SPI_GPIO,&GPIO_InitStruct); /*MOSI---PB15*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_MOSI_PIN; GPIO_Init(OLED_SPI_GPIO,&GPIO_InitStruct); /*CS-----PA15*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_CS_PIN; GPIO_Init(OLED_GPIO,&GPIO_InitStruct); /*DC-----PA11*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_DC_PIN; GPIO_Init(OLED_GPIO,&GPIO_InitStruct); /*RES-----PA12*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_RES_PIN; GPIO_Init(OLED_GPIO,&GPIO_InitStruct); OLED_RES_H; } /***********************初始化时序********************************************/ delay_ms(200); Oled_Write_Cmd(0xAE); //关闭显示 Oled_Write_Cmd(0xD5); //设置时钟分频因子,震荡频率 Oled_Write_Cmd(80); //[3:0],分频因子;[7:4],震荡频率 Oled_Write_Cmd(0xA8); //设置驱动路数 Oled_Write_Cmd(0X3F); //默认0X3F(1/64) Oled_Write_Cmd(0xD3); //设置显示偏移 Oled_Write_Cmd(0X00); //默认为0 Oled_Write_Cmd(0x40); //设置显示开始行 [5:0],行数. Oled_Write_Cmd(0x8D); //电荷泵设置 Oled_Write_Cmd(0x14); //bit2,开启/关闭 Oled_Write_Cmd(0x20); //设置内存地址模式 Oled_Write_Cmd(0x02); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10; Oled_Write_Cmd(0xA1); //段重定义设置,bit0:0,0->0;1,0->127; Oled_Write_Cmd(0xC8); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数 Oled_Write_Cmd(0xDA); //设置COM硬件引脚配置 Oled_Write_Cmd(0x12); //[5:4]配置 Oled_Write_Cmd(0x81); //对比度设置 Oled_Write_Cmd(0xEF); //1~255;默认0X7F (亮度设置,越大越亮) Oled_Write_Cmd(0xD9); //设置预充电周期 Oled_Write_Cmd(0xf1); //[3:0],PHASE 1;[7:4],PHASE 2; Oled_Write_Cmd(0xDB); //设置VCOMH 电压倍率 Oled_Write_Cmd(0x30); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc; Oled_Write_Cmd(0xA4); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏) Oled_Write_Cmd(0xA6); //设置显示方式;bit0:1,反相显示;0,正常显示 Oled_Write_Cmd(0xAF); //开启显示 OLED_Clear(0,128,0,8,0x00); } /******************************************************************* * 函数名: spi_read_write() * 功能描述 : SPI读写数据 * 作者: 何文宾 * 参数说明: 待发送的数据 * 返回值说明: 读取的值 * 修改记录: * 其他: *******************************************************************/ //SPI读写数据 u8 spi_read_write(u8 dat) { if (SPI_MODE) { while(!SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)); //等待发送缓冲为空 SPI_I2S_SendData(SPI2,dat); while(!SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)); //等待接收缓冲不为空 return SPI_I2S_ReceiveData(SPI2); //返回收到的数据 } else { u8 i; OLED_CS_L; for(i=0;i<8;i++) { OLED_SCK_L; if((dat&0x80)) { OLED_MOSI_H; } else OLED_MOSI_L; OLED_SCK_H; dat<<=1; } OLED_CS_H; return dat; } } /******************************************************************* * 函数名: Oled_Write_Data() * 功能描述 : OLED写数据 * 作者: 何文宾 * 参数说明: 待发送的指令 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void Oled_Write_Data(u8 dat) { OLED_DC_H; OLED_CS_L; spi_read_write(dat); OLED_CS_H; } /******************************************************************* * 函数名: Oled_Write_Cmd() * 功能描述 : OLED写指令 * 作者: 何文宾 * 参数说明: 待发送的指令 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void Oled_Write_Cmd(u8 cmd) { OLED_DC_L; OLED_CS_L; spi_read_write(cmd); OLED_CS_H; } /******************************************************************* * 函数名: OLED_Setpos() * 功能描述 : OLED设置位置 * 作者: 何文宾 * 参数说明: 待发送的指令 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_Setpos(u8 sx,u8 sy) { Oled_Write_Cmd(0xb0+sy); //哪一页 Oled_Write_Cmd(0x10+(sx>>4)); //高4位地址 Oled_Write_Cmd(0x00+(sx&0x0f));//低4位地址 } /******************************************************************* * 函数名: OLED_Clear() * 功能描述 : OLED设置位置 * 作者: 何文宾 * 参数说明: 待发送的指令 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_Clear(u8 sx,u8 ex,u8 sy,u8 ey,u8 data) { u8 i,j; for(i=sy;i<ey;i++) //页 { Oled_Write_Cmd(0xb0+i); //哪一页 Oled_Write_Cmd(0x10+(sx>>4)); //高4位地址 Oled_Write_Cmd(0x00+(sx&0x0f));//低4位地址 for(j=0;j<(ex-sx);j++) //列 { Oled_Write_Data(data); } } } /******************************************************************* * 函数名: OLED_ShowChar() * 功能描述 : 显示字符 * 作者: 何文宾 * 参数说明: x:X坐标,y:Y坐标,p:显示的字符,size:字符大小 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_ShowChar(u8 x,u8 y,u8 p,u8 size) { u8 i; u8 ex,ey; u8 res=p-' '; ex=x;ey=y; if(size==16) { OLED_Setpos(ex,ey); for(i=0;i<16;i++) { if(((i%8)==0)&&(i!=0)) { ex=x; ey+=1; OLED_Setpos(ex,ey); } Oled_Write_Data(char16X16[res][i]); } } else if(size==12) { OLED_Setpos(ex,ey); for(i=0;i<12;i++) { if(((i%6)==0)&&(i!=0)) { ex=x; ey+=1; OLED_Setpos(ex,ey); } Oled_Write_Data(char12X12[res][i]); } } else if(size==24) { OLED_Setpos(ex,ey); for(i=0;i<36;i++) { if(((i%12)==0)&&(i!=0)) { ex=x; ey+=1; OLED_Setpos(ex,ey); } Oled_Write_Data(char24X24[res][i]); } } } /******************************************************************* * 函数名: OLED_ShowString() * 功能描述 : 显示字符串 * 作者: 何文宾 * 参数说明: x:X坐标,y:Y坐标,p:显示的字符串,size:字符串大小 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_ShowString(u8 x,u8 y,u8 *p,u8 size) { while(*p!='\0') { OLED_ShowChar(x,y,*p,size); p+=1; x+=(size/2); } } /******************************************************************* * 函数名: OLED_ShowNum() * 功能描述 : 显示数字 * 作者: 何文宾 * 参数说明: x:X坐标,y:Y坐标,num:显示的数字,size:数字大小,len:长度 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_ShowNum(u8 x,u8 y,u32 num,u8 size) { u8 cnum,cnum2; u8 nn; u8 i; u8 length=0; nn=1; cnum=num; cnum2=num; if(num!=0) { while(num>0) { length+=1; num/=10; } } else { length=1; } while(length) { for(i=0;i<(length-1);i++) { nn=nn*10; } cnum=cnum/nn; OLED_ShowChar(x,y,cnum+48,size); x+=(size/2); cnum=cnum2%nn; nn=1; length--; } } /******************************************************************* * 函数名: OLED_ShowTime() * 功能描述 : 显示当前时间 * 作者: 何文宾 * 参数说明: x:X坐标,y:Y坐标,size:数字大小 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_ShowTime(u8 x,u8 y,u8 size) { u8 sx=x; /*显示当前时间*/ RTC_Get_Time(); OLED_ShowNum(sx,y,my_time.hour,16); sx+=size; OLED_ShowChar(sx,y,':',16); sx+=(size/2); OLED_ShowNum(sx,y,my_time.min,16); sx+=size; OLED_ShowChar(sx,y,':',16); sx+=(size/2); OLED_ShowNum(sx,y,my_time.sec ,16); } /******************************************************************* * 函数名: OLED_Showpic() * 功能描述 : 显示图片 * 作者: 何文宾 * 参数说明: * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_Showpic(u8 sx,u8 sy,u8 ex,u8 ey,const unsigned char * p) { u8 i,j; for(j=0;j<(ey-sy);j++) { OLED_Setpos(sx,sy+j); for(i=0;i<(ex-sx);i++) { Oled_Write_Data(*p); p++; } } } /******************************************************************* * 函数名: OLED_Show_Font() * 功能描述 : 显示单个汉字 * 作者: 何文宾 * 参数说明: * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_Show_Font(u8 x,u8 y,u8 size,u8 num) { u8 i; u8 temp; u8 ssize; u8 x0=x; u8 *zk; ssize=size*(size/8+(size%8?1:0)); //计算不同字体大小所占用的字节数 switch(size) { case 12: zk=(u8*)F12X12[num]; //得到汉字编号对应的点阵库 for(i=0;i<ssize;i++) { if(i==size) { x=x0; y++; } temp=zk[i]; //得到点阵数据 OLED_Setpos(x,y); Oled_Write_Data(temp); x++; } break; case 16: zk=(u8*)F16X16[num]; //得到汉字编号对应的点阵库 for(i=0;i<ssize;i++) { if(i==size) { x=x0; y++; } temp=zk[i]; //得到点阵数据 OLED_Setpos(x,y); Oled_Write_Data(temp); x++; } break; case 24: zk=(u8*)F24X24[num]; //得到汉字编号对应的点阵库 for(i=0;i<ssize;i++) { if(i==size) { x=x0; y++; } temp=zk[i]; //得到点阵数据 OLED_Setpos(x,y); Oled_Write_Data(temp); x++; } break; default:break; } } /******************************************************************* * 函数名: OLED_Show_Font() * 功能描述 : 显示多个汉字 * 作者: 何文宾 * 参数说明: * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_ShowMultiple_Font(u8 x,u8 y,u8 size,u8 *p) { while(*p!=0) { OLED_Show_Font(x,y,size,*p); p++; x+=size; } } /******************************************************************* * 函数名: OLED_Show_gezi() * 功能描述 : 显示下划线 * 作者: 何文宾 * 参数说明: mode:1 密码格子 0:时间格子 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_Show_gezi(u8 sx,u8 sy,u8 ex,u8 ey) { u8 i; for(i=0;i<6;i++) { OLED_Showpic(sx,sy,ex,ey,&gezi[0]); sx+=15; ex+=15; } } void show_voice(u8 sx,u8 sy,u8 vol) { u8 i=0; u8 x=sx; OLED_Clear(sx,sx+80,sy,sy+1,0x00); for(i=0;i<vol;i++) { OLED_Showpic(x,sy,x+8,sy+1,&voice[i][0]); x+=10; } } /*********************************************************************************************** ***********************************************************************************************/ 我想在此基础上添加切换屏幕的功能,并且屏幕显示请输入密码

我想使用STM32的定时器(如TIM3)计数的两路正交方波脉冲,该方波是由弦波经迟滞比较器转换后的方波,幅值只要近400mv,这种情况下实现我上述要求(脉冲四倍频计数,计数结果用Proteus里的OLED12864I2C显示,没有使用I2C,使用PB6,PB7模拟SCL,SDA,基于我上述提供的OLED相关代码)。给出实现流程。tim.c代码:/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file tim.c * @brief This file provides code for the configuration * of the TIM instances. ****************************************************************************** * @attention * * Copyright (c) 2025 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "tim.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ TIM_HandleTypeDef htim3; /* TIM3 init function */ void MX_TIM3_Init(void) { /* USER CODE BEGIN TIM3_Init 0 */ /* USER CODE END TIM3_Init 0 */ TIM_Encoder_InitTypeDef sConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; /* USER CODE BEGIN TIM3_Init 1 */ /* USER CODE END TIM3_Init 1 */ htim3.Instance = TIM3; htim3.Init.Prescaler = 0; htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 65535; htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; sConfig.EncoderMode = TIM_ENCODERMODE_TI12; sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; sConfig.IC1Prescaler = TIM_ICPSC_DIV1; sConfig.IC1Filter = 15; sConfig.IC2Polarity = TIM_ICPOLARITY_RISING; sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; sConfig.IC2Prescaler = TIM_ICPSC_DIV1; sConfig.IC2Filter = 15; if (HAL_TIM_Encoder_Init(&htim3, &sConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM3_Init 2 */ /* USER CODE END TIM3_Init 2 */ } void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef* tim_encoderHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(tim_encoderHandle->Instance==TIM3) { /* USER CODE BEGIN TIM3_MspInit 0 */ /* USER CODE END TIM3_MspInit 0 */ /* TIM3 clock enable */ __HAL_RCC_TIM3_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**TIM3 GPIO Configuration PA6 ------> TIM3_CH1 PA7 ------> TIM3_CH2 */ GPIO_InitStruct.Pin = TIM3_CH1_Pin|TIM3_CH2_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN TIM3_MspInit 1 */ /* USER CODE END TIM3_MspInit 1 */ } } void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef* tim_encoderHandle) { if(tim_encoderHandle->Instance==TIM3) { /* USER CODE BEGIN TIM3_MspDeInit 0 */ /* USER CODE END TIM3_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_TIM3_CLK_DISABLE(); /**TIM3 GPIO Configuration PA6 ------> TIM3_CH1 PA7 ------> TIM3_CH2 */ HAL_GPIO_DeInit(GPIOA, TIM3_CH1_Pin|TIM3_CH2_Pin); /* USER CODE BEGIN TIM3_MspDeInit 1 */ /* USER CODE END TIM3_MspDeInit 1 */ } } /* USER CODE BEGIN 1 */ /* USER CODE END 1 */OLED.c:#include "OLED_Font.h" #include "OLED.h" /*引脚配置*/ #define OLED_W_SCL(x) HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, (GPIO_PinState)(x)) #define OLED_W_SDA(x) HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, (GPIO_PinState)(x)) /** * @brief I2C开始 * @param 无 * @retval 无 */ void OLED_I2C_Start(void) { OLED_W_SDA(1); OLED_W_SCL(1); OLED_W_SDA(0); OLED_W_SCL(0); } /** * @brief I2C停止 * @param 无 * @retval 无 */ void OLED_I2C_Stop(void) { OLED_W_SDA(0); OLED_W_SCL(1); OLED_W_SDA(1); } /** * @brief I2C发送一个字节 * @param Byte 要发送的一个字节 * @retval 无 */ void OLED_I2C_SendByte(uint8_t Byte) { uint8_t i; for (i = 0; i < 8; i++) { OLED_W_SDA(Byte & (0x80 >> i)); OLED_W_SCL(1); OLED_W_SCL(0); } OLED_W_SCL(1); //额外的一个时钟,不处理应答信号 OLED_W_SCL(0); } /** * @brief OLED写命令 * @param Command 要写入的命令 * @retval 无 */ void OLED_WriteCommand(uint8_t Command) { OLED_I2C_Start(); OLED_I2C_SendByte(0x78); //从机地址 OLED_I2C_SendByte(0x00); //写命令 OLED_I2C_SendByte(Command); OLED_I2C_Stop(); } /** * @brief OLED写数据 * @param Data 要写入的数据 * @retval 无 */ void OLED_WriteData(uint8_t Data) { OLED_I2C_Start(); OLED_I2C_SendByte(0x78); //从机地址 OLED_I2C_SendByte(0x40); //写数据 OLED_I2C_SendByte(Data); OLED_I2C_Stop(); } /** * @brief OLED设置光标位置 * @param Y 以左上角为原点,向下方向的坐标,范围:0~7 * @param X 以左上角为原点,向右方向的坐标,范围:0~127 * @retval 无 */ void OLED_SetCursor(uint8_t Y, uint8_t X) { OLED_WriteCommand(0xB0 | Y); //设置Y位置 OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4)); //设置X位置高4位 OLED_WriteCommand(0x00 | (X & 0x0F)); //设置X位置低4位 } /** * @brief OLED清屏 * @param 无 * @retval 无 */ void OLED_Clear(void) { for (uint8_t page = 0; page < 8; page++) { OLED_WriteCommand(0xB0 | page); // 设置页地址 OLED_WriteCommand(0x00); // 列低位 OLED_WriteCommand(0x10); // 列高位 OLED_I2C_Start(); OLED_I2C_SendByte(0x78); // 地址 OLED_I2C_SendByte(0x40); // 数据模式 for (uint8_t col = 0; col < 128; col++) { OLED_I2C_SendByte(0x00); // 一次传输整页数据 } OLED_I2C_Stop(); } } /** * @brief OLED显示一个字符 * @param Line 行位置,范围:1~4 * @param Column 列位置,范围:1~16 * @param Char 要显示的一个字符,范围:ASCII可见字符 * @retval 无 */ void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char) { uint8_t page = Line; // 每行对应一个页(8像素高) ddddddddddddddddd uint8_t col = Column * 8; // 每字符占8列 ddddddddddddddddddd OLED_WriteCommand(0xB0 | page); // 设置页地址 ddddddddddddddddd OLED_WriteCommand(0x00 | (col & 0x0F)); // 列低位 dddddddddddddddd OLED_WriteCommand(0x10 | (col >> 4)); // 列高位 ddddddddddddddddddddddddd for (uint8_t i = 0; i < 8; i++) { OLED_WriteData(OLED_F8x16[Char - ' '][i]); } } /** * @brief OLED显示字符串 * @param Line 起始行位置,范围:1~4 * @param Column 起始列位置,范围:1~16 * @param String 要显示的字符串,范围:ASCII可见字符 * @retval 无 */ void OLED_ShowString(uint8_t Line, uint8_t Column, char *String) { uint8_t i; for (i = 0; String[i] != '\0'; i++) { OLED_ShowChar(Line, Column + i, String[i]); } } /** * @brief OLED次方函数 * @retval 返回值等于X的Y次方 */ uint32_t OLED_Pow(uint32_t X, uint32_t Y) { uint32_t Result = 1; while (Y--) { Result *= X; } return Result; } /** * @brief OLED显示数字(十进制,正数) * @param Line 起始行位置,范围:1~4 * @param Column 起始列位置,范围:1~16 * @param Number 要显示的数字,范围:0~4294967295 * @param Length 要显示数字的长度,范围:1~10 * @retval 无 */ void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i; for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + '0'); } } /** * @brief OLED显示数字(十进制,带符号数) * @param Line 起始行位置,范围:1~4 * @param Column 起始列位置,范围:1~16 * @param Number 要显示的数字,范围:-2147483648~2147483647 * @param Length 要显示数字的长度,范围:1~10 * @retval 无 */ void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length) { uint8_t i; uint32_t Number1; if (Number >= 0) { OLED_ShowChar(Line, Column, '+'); Number1 = Number; } else { OLED_ShowChar(Line, Column, '-'); Number1 = -Number; } for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i + 1, Number1 / OLED_Pow(10, Length - i - 1) % 10 + '0'); } } /** * @brief OLED显示数字(十六进制,正数) * @param Line 起始行位置,范围:1~4 * @param Column 起始列位置,范围:1~16 * @param Number 要显示的数字,范围:0~0xFFFFFFFF * @param Length 要显示数字的长度,范围:1~8 * @retval 无 */ void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i, SingleNumber; for (i = 0; i < Length; i++) { SingleNumber = Number / OLED_Pow(16, Length - i - 1) % 16; if (SingleNumber < 10) { OLED_ShowChar(Line, Column + i, SingleNumber + '0'); } else { OLED_ShowChar(Line, Column + i, SingleNumber - 10 + 'A'); } } } /** * @brief OLED显示数字(二进制,正数) * @param Line 起始行位置,范围:1~4 * @param Column 起始列位置,范围:1~16 * @param Number 要显示的数字,范围:0~1111 1111 1111 1111 * @param Length 要显示数字的长度,范围:1~16 * @retval 无 */ void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i; for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i, Number / OLED_Pow(2, Length - i - 1) % 2 + '0'); } } /** * @brief 显示BMP图片 * @param 图片大小:128×64 * @param 起始点坐标(x,y) * @param x的范围0~127 * @param y的范围0~7 * @retval 无 */ void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]) { unsigned int j=0; unsigned char x,y; if(y1%8==0) y=y1/8; else y=y1/8+1; for(y=y0;y<y1;y++) { OLED_SetCursor(y,x0); for(x=x0;x<x1;x++) { OLED_WriteData(BMP[j++]); } } } /** * @brief OLED初始化 * @param 无 * @retval 无 */ void OLED_Init(void) { //uint32_t i, j; //for (i = 0; i < 1000; i++) //上电延时 //{ //for (j = 0; j < 1000; j++); //} OLED_WriteCommand(0xAE); //关闭显示 OLED_WriteCommand(0xD5); //设置显示时钟分频比/振荡器频率 OLED_WriteCommand(0x80); OLED_WriteCommand(0xA8); //设置多路复用率 OLED_WriteCommand(0x3F); OLED_WriteCommand(0xD3); //设置显示偏移 OLED_WriteCommand(0x00); OLED_WriteCommand(0x40); //设置显示开始行 OLED_WriteCommand(0xA1); //设置左右方向,0xA1正常 0xA0左右反置 OLED_WriteCommand(0xC8); //设置上下方向,0xC8正常 0xC0上下反置 OLED_WriteCommand(0xDA); //设置COM引脚硬件配置 OLED_WriteCommand(0x12); OLED_WriteCommand(0x81); //设置对比度控制 OLED_WriteCommand(0xCF); OLED_WriteCommand(0xD9); //设置预充电周期 OLED_WriteCommand(0xF1); OLED_WriteCommand(0xDB); //设置VCOMH取消选择级别 OLED_WriteCommand(0x30); OLED_WriteCommand(0xA4); //设置整个显示打开/关闭 OLED_WriteCommand(0xA6); //设置正常/倒转显示 OLED_WriteCommand(0x8D); //设置充电泵 OLED_WriteCommand(0x14); OLED_WriteCommand(0xAF); //开启显示 OLED_Clear(); //OLED清屏 }

Build started: Project: STC8H8K64U Build target 'Target 1' linking... *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: BMP MODULE: .\Objects\I2C.obj (I2C) *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: HZK MODULE: .\Objects\I2C.obj (I2C) *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: ASC2_1608 MODULE: .\Objects\I2C.obj (I2C) *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: ASC2_0806 MODULE: .\Objects\I2C.obj (I2C) *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: BMP MODULE: .\Objects\OLED_.obj (OLED_) *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: HZK MODULE: .\Objects\OLED_.obj (OLED_) *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: ASC2_1608 MODULE: .\Objects\OLED_.obj (OLED_) *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: ASC2_0806 MODULE: .\Objects\OLED_.obj (OLED_) *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: _OLED_POW MODULE: .\Objects\OLED_.obj (OLED_) *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_OLED_SHOWSTRING?OLED *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_OLED_SHOWNUM?OLED *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_OLED_SHOWSIGNEDNUM?OLED *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_OLED_SHOWHEXNUM?OLED *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_OLED_SHOWBINNUM?OLED *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?OLED0_DISPLAY_ON?OLED_ *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?OLED0_DISPLAY_OFF?OLED_ *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_OLED0_COLORTURN?OLED_ *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_OLED0_DISPLAYTURN?OLED_ *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_OLED0_SHOWNUM?OLED_ *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_OLED0_SHOWSTRING?OLED_ *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_OLED0_SHOWCHINESE?OLED_ *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_OLED0_DRAWBMP?OLED_ *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?OLED0_INIT?OLED_ Program Size: data=89.0 xdata=23688 code=25895 Target not created. Build Time Elapsed: 00:00:01

#include “OLED_Font.h” #include “OLED.h” /引脚配置/ #define OLED_W_SCL(x) HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, (GPIO_PinState)(x)) #define OLED_W_SDA(x) HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, (GPIO_PinState)(x)) /** @brief I2C开始 @param 无 @retval 无 / void OLED_I2C_Start(void) { OLED_W_SDA(1); OLED_W_SCL(1); OLED_W_SDA(0); OLED_W_SCL(0); } /* @brief I2C停止 @param 无 @retval 无 / void OLED_I2C_Stop(void) { OLED_W_SDA(0); OLED_W_SCL(1); OLED_W_SDA(1); } /* @brief I2C发送一个字节 @param Byte 要发送的一个字节 @retval 无 / void OLED_I2C_SendByte(uint8_t Byte) { uint8_t i; for (i = 0; i < 8; i++) { OLED_W_SDA(Byte & (0x80 >> i)); OLED_W_SCL(1); OLED_W_SCL(0); } OLED_W_SCL(1); //额外的一个时钟,不处理应答信号 OLED_W_SCL(0); } /* @brief OLED写命令 @param Command 要写入的命令 @retval 无 / void OLED_WriteCommand(uint8_t Command) { OLED_I2C_Start(); OLED_I2C_SendByte(0x78); //从机地址 OLED_I2C_SendByte(0x00); //写命令 OLED_I2C_SendByte(Command); OLED_I2C_Stop(); } /* @brief OLED写数据 @param Data 要写入的数据 @retval 无 / void OLED_WriteData(uint8_t Data) { OLED_I2C_Start(); OLED_I2C_SendByte(0x78); //从机地址 OLED_I2C_SendByte(0x40); //写数据 OLED_I2C_SendByte(Data); OLED_I2C_Stop(); } /* @brief OLED设置光标位置 @param Y 以左上角为原点,向下方向的坐标,范围:0~7 @param X 以左上角为原点,向右方向的坐标,范围:0~127 @retval 无 / void OLED_SetCursor(uint8_t Y, uint8_t X) { OLED_WriteCommand(0xB0 | Y); //设置Y位置 OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4)); //设置X位置高4位 OLED_WriteCommand(0x00 | (X & 0x0F)); //设置X位置低4位 } /* @brief OLED清屏 @param 无 @retval 无 / void OLED_Clear(void) { uint8_t i, j; for (j = 0; j < 8; j++) { OLED_SetCursor(j, 0); for(i = 0; i < 128; i++) { OLED_WriteData(0x00); } } } /* @brief OLED显示一个字符 @param Line 行位置,范围:1~4 @param Column 列位置,范围:1~16 @param Char 要显示的一个字符,范围:ASCII可见字符 @retval 无 / void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char) { uint8_t i; OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8); //设置光标位置在上半部分 for (i = 0; i < 8; i++) { OLED_WriteData(OLED_F8x16[Char - ’ '][i]); //显示上半部分内容 } OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8); //设置光标位置在下半部分 for (i = 0; i < 8; i++) { OLED_WriteData(OLED_F8x16[Char - ’ '][i + 8]); //显示下半部分内容 } } /* @brief OLED显示字符串 @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param String 要显示的字符串,范围:ASCII可见字符 @retval 无 / void OLED_ShowString(uint8_t Line, uint8_t Column, char String) { uint8_t i; for (i = 0; String[i] != ‘\0’; i++) { OLED_ShowChar(Line, Column + i, String[i]); } } / @brief OLED次方函数 @retval 返回值等于X的Y次方 / uint32_t OLED_Pow(uint32_t X, uint32_t Y) { uint32_t Result = 1; while (Y–) { Result = X; } return Result; } / @brief OLED显示数字(十进制,正数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:0~4294967295 @param Length 要显示数字的长度,范围:1~10 @retval 无 / void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i; for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + ‘0’); } } /* @brief OLED显示数字(十进制,带符号数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:-2147483648~2147483647 @param Length 要显示数字的长度,范围:1~10 @retval 无 / void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length) { uint8_t i; uint32_t Number1; if (Number >= 0) { OLED_ShowChar(Line, Column, ‘+’); Number1 = Number; } else { OLED_ShowChar(Line, Column, ‘-’); Number1 = -Number; } for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i + 1, Number1 / OLED_Pow(10, Length - i - 1) % 10 + ‘0’); } } /* @brief OLED显示数字(十六进制,正数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:0~0xFFFFFFFF @param Length 要显示数字的长度,范围:1~8 @retval 无 / void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i, SingleNumber; for (i = 0; i < Length; i++) { SingleNumber = Number / OLED_Pow(16, Length - i - 1) % 16; if (SingleNumber < 10) { OLED_ShowChar(Line, Column + i, SingleNumber + ‘0’); } else { OLED_ShowChar(Line, Column + i, SingleNumber - 10 + ‘A’); } } } /* @brief OLED显示数字(二进制,正数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:0~1111 1111 1111 1111 @param Length 要显示数字的长度,范围:1~16 @retval 无 / void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i; for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i, Number / OLED_Pow(2, Length - i - 1) % 2 + ‘0’); } } /* @brief 显示BMP图片 @param 图片大小:128×64 @param 起始点坐标(x,y) @param x的范围0~127 @param y的范围0~7 @retval 无 */ void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]) { unsigned int j=0; unsigned char x,y; if(y1%8==0) y=y1/8; else y=y1/8+1; for(y=y0;y<y1;y++) { OLED_SetCursor(y,x0); for(x=x0;x<x1;x++) { OLED_WriteData(BMP[j++]); } } } /** @brief OLED初始化 @param 无 @retval 无 */ void OLED_Init(void) { uint32_t i, j; for (i = 0; i < 1000; i++) //上电延时 { for (j = 0; j < 1000; j++); } OLED_WriteCommand(0xAE); //关闭显示 OLED_WriteCommand(0xD5); //设置显示时钟分频比/振荡器频率 OLED_WriteCommand(0x80); OLED_WriteCommand(0xA8); //设置多路复用率 OLED_WriteCommand(0x3F); OLED_WriteCommand(0xD3); //设置显示偏移 OLED_WriteCommand(0x00); OLED_WriteCommand(0x40); //设置显示开始行 OLED_WriteCommand(0xA1); //设置左右方向,0xA1正常 0xA0左右反置 OLED_WriteCommand(0xC8); //设置上下方向,0xC8正常 0xC0上下反置 OLED_WriteCommand(0xDA); //设置COM引脚硬件配置 OLED_WriteCommand(0x12); OLED_WriteCommand(0x81); //设置对比度控制 OLED_WriteCommand(0xCF); OLED_WriteCommand(0xD9); //设置预充电周期 OLED_WriteCommand(0xF1); OLED_WriteCommand(0xDB); //设置VCOMH取消选择级别 OLED_WriteCommand(0x30); OLED_WriteCommand(0xA4); //设置整个显示打开/关闭 OLED_WriteCommand(0xA6); //设置正常/倒转显示 OLED_WriteCommand(0x8D); //设置充电泵 OLED_WriteCommand(0x14); OLED_WriteCommand(0xAF); //开启显示 OLED_Clear(); //OLED清屏 }该代码为我的OLED.C #ifndef __OLED_H #define __OLED_H #include “main.h” void OLED_Init(void); void OLED_Clear(void); void OLED_I2C_Start(void); void OLED_I2C_Stop(void); void OLED_I2C_SendByte(uint8_t Byte); void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char); void OLED_ShowString(uint8_t Line, uint8_t Column, char *String); void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length); void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length); void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length); void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length); void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]); #endif这段代码为OLED.H #ifndef __OLED_FONT_H #define __OLED_FONT_H #include “main.h” /OLED字模库,宽8像素,高16像素/ const uint8_t OLED_F8x16[][16]= { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1 0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2 0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00, 0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3 0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00, 0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00, 0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5 0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00, 0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6 0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//’ 7 0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00, 0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8 0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00, 0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9 0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00, 0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10 0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00, 0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14 0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04, 0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00, 0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00, 0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00, 0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00, 0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00, 0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00, 0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00, 0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00, 0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00, 0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00, 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00, 0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00, 0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30 0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00, 0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00, 0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00, 0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33 0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00, 0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34 0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00, 0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35 0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00, 0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00, 0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00, 0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38 0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00, 0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08, 0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40 0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41 0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00, 0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42 0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00, 0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43 0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00, 0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44 0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00, 0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45 0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08, 0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00, 0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47 0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00, 0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00, 0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49 0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00, 0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50 0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00, 0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51 0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00, 0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08, 0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08, 0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00, 0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55 0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08, 0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56 0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00, 0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57 0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00, 0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58 0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00, 0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59 0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60 0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00, 0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61 0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63 0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 64 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00, 0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65 0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00, 0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, 0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67 0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00, 0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00, 0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69 0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00, 0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71 0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00, 0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72 0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73 0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00, 0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74 0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00, 0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75 0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, 0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77 0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00, 0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00, 0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79 0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00, 0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00, 0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81 0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00, 0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00, 0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83 0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00, 0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84 0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00, 0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80, 0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86 0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80, 0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87 0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00, 0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80, 0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00, 0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90 0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02, 0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92 0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00, 0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93 0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94 }; #endif这段代码为我的OLED.Font.h。基于这三个OLED相关驱动代码,实现基于STM32 HAL库,使用STM32CUBEMX进行引脚配置,keil运行代码,生成hex文件,Proteus展示实验结果,实现对来自外部两路正交的方波进行计数,然后计数结果用Proteus里的OLED12864I2C显示(没有使用I2C,使用PB6,PB7模拟SCL,SDA,基于我上述提供的OLED相关代码)。给出实现流程。 回答 向我提问的人太多了。正在努力扩容中,请稍后再试。 #include “OLED_Font.h” #include “OLED.h” /引脚配置/ #define OLED_W_SCL(x) HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, (GPIO_PinState)(x)) #define OLED_W_SDA(x) HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, (GPIO_PinState)(x)) /** @brief I2C开始 @param 无 @retval 无 / void OLED_I2C_Start(void) { OLED_W_SDA(1); OLED_W_SCL(1); OLED_W_SDA(0); OLED_W_SCL(0); } /* @brief I2C停止 @param 无 @retval 无 / void OLED_I2C_Stop(void) { OLED_W_SDA(0); OLED_W_SCL(1); OLED_W_SDA(1); } /* @brief I2C发送一个字节 @param Byte 要发送的一个字节 @retval 无 / void OLED_I2C_SendByte(uint8_t Byte) { uint8_t i; for (i = 0; i < 8; i++) { OLED_W_SDA(Byte & (0x80 >> i)); OLED_W_SCL(1); OLED_W_SCL(0); } OLED_W_SCL(1); //额外的一个时钟,不处理应答信号 OLED_W_SCL(0); } /* @brief OLED写命令 @param Command 要写入的命令 @retval 无 / void OLED_WriteCommand(uint8_t Command) { OLED_I2C_Start(); OLED_I2C_SendByte(0x78); //从机地址 OLED_I2C_SendByte(0x00); //写命令 OLED_I2C_SendByte(Command); OLED_I2C_Stop(); } /* @brief OLED写数据 @param Data 要写入的数据 @retval 无 / void OLED_WriteData(uint8_t Data) { OLED_I2C_Start(); OLED_I2C_SendByte(0x78); //从机地址 OLED_I2C_SendByte(0x40); //写数据 OLED_I2C_SendByte(Data); OLED_I2C_Stop(); } /* @brief OLED设置光标位置 @param Y 以左上角为原点,向下方向的坐标,范围:0~7 @param X 以左上角为原点,向右方向的坐标,范围:0~127 @retval 无 / void OLED_SetCursor(uint8_t Y, uint8_t X) { OLED_WriteCommand(0xB0 | Y); //设置Y位置 OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4)); //设置X位置高4位 OLED_WriteCommand(0x00 | (X & 0x0F)); //设置X位置低4位 } /* @brief OLED清屏 @param 无 @retval 无 / void OLED_Clear(void) { uint8_t i, j; for (j = 0; j < 8; j++) { OLED_SetCursor(j, 0); for(i = 0; i < 128; i++) { OLED_WriteData(0x00); } } } /* @brief OLED显示一个字符 @param Line 行位置,范围:1~4 @param Column 列位置,范围:1~16 @param Char 要显示的一个字符,范围:ASCII可见字符 @retval 无 / void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char) { uint8_t i; OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8); //设置光标位置在上半部分 for (i = 0; i < 8; i++) { OLED_WriteData(OLED_F8x16[Char - ’ '][i]); //显示上半部分内容 } OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8); //设置光标位置在下半部分 for (i = 0; i < 8; i++) { OLED_WriteData(OLED_F8x16[Char - ’ '][i + 8]); //显示下半部分内容 } } /* @brief OLED显示字符串 @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param String 要显示的字符串,范围:ASCII可见字符 @retval 无 / void OLED_ShowString(uint8_t Line, uint8_t Column, char String) { uint8_t i; for (i = 0; String[i] != ‘\0’; i++) { OLED_ShowChar(Line, Column + i, String[i]); } } / @brief OLED次方函数 @retval 返回值等于X的Y次方 / uint32_t OLED_Pow(uint32_t X, uint32_t Y) { uint32_t Result = 1; while (Y–) { Result = X; } return Result; } / @brief OLED显示数字(十进制,正数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:0~4294967295 @param Length 要显示数字的长度,范围:1~10 @retval 无 / void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i; for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + ‘0’); } } /* @brief OLED显示数字(十进制,带符号数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:-2147483648~2147483647 @param Length 要显示数字的长度,范围:1~10 @retval 无 / void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length) { uint8_t i; uint32_t Number1; if (Number >= 0) { OLED_ShowChar(Line, Column, ‘+’); Number1 = Number; } else { OLED_ShowChar(Line, Column, ‘-’); Number1 = -Number; } for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i + 1, Number1 / OLED_Pow(10, Length - i - 1) % 10 + ‘0’); } } /* @brief OLED显示数字(十六进制,正数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:0~0xFFFFFFFF @param Length 要显示数字的长度,范围:1~8 @retval 无 / void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i, SingleNumber; for (i = 0; i < Length; i++) { SingleNumber = Number / OLED_Pow(16, Length - i - 1) % 16; if (SingleNumber < 10) { OLED_ShowChar(Line, Column + i, SingleNumber + ‘0’); } else { OLED_ShowChar(Line, Column + i, SingleNumber - 10 + ‘A’); } } } /* @brief OLED显示数字(二进制,正数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:0~1111 1111 1111 1111 @param Length 要显示数字的长度,范围:1~16 @retval 无 / void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i; for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i, Number / OLED_Pow(2, Length - i - 1) % 2 + ‘0’); } } /* @brief 显示BMP图片 @param 图片大小:128×64 @param 起始点坐标(x,y) @param x的范围0~127 @param y的范围0~7 @retval 无 */ void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]) { unsigned int j=0; unsigned char x,y; if(y1%8==0) y=y1/8; else y=y1/8+1; for(y=y0;y<y1;y++) { OLED_SetCursor(y,x0); for(x=x0;x<x1;x++) { OLED_WriteData(BMP[j++]); } } } /** @brief OLED初始化 @param 无 @retval 无 */ void OLED_Init(void) { uint32_t i, j; for (i = 0; i < 1000; i++) //上电延时 { for (j = 0; j < 1000; j++); } OLED_WriteCommand(0xAE); //关闭显示 OLED_WriteCommand(0xD5); //设置显示时钟分频比/振荡器频率 OLED_WriteCommand(0x80); OLED_WriteCommand(0xA8); //设置多路复用率 OLED_WriteCommand(0x3F); OLED_WriteCommand(0xD3); //设置显示偏移 OLED_WriteCommand(0x00); OLED_WriteCommand(0x40); //设置显示开始行 OLED_WriteCommand(0xA1); //设置左右方向,0xA1正常 0xA0左右反置 OLED_WriteCommand(0xC8); //设置上下方向,0xC8正常 0xC0上下反置 OLED_WriteCommand(0xDA); //设置COM引脚硬件配置 OLED_WriteCommand(0x12); OLED_WriteCommand(0x81); //设置对比度控制 OLED_WriteCommand(0xCF); OLED_WriteCommand(0xD9); //设置预充电周期 OLED_WriteCommand(0xF1); OLED_WriteCommand(0xDB); //设置VCOMH取消选择级别 OLED_WriteCommand(0x30); OLED_WriteCommand(0xA4); //设置整个显示打开/关闭 OLED_WriteCommand(0xA6); //设置正常/倒转显示 OLED_WriteCommand(0x8D); //设置充电泵 OLED_WriteCommand(0x14); OLED_WriteCommand(0xAF); //开启显示 OLED_Clear(); //OLED清屏 }该代码为我的OLED.C #ifndef __OLED_H #define __OLED_H #include “main.h” void OLED_Init(void); void OLED_Clear(void); void OLED_I2C_Start(void); void OLED_I2C_Stop(void); void OLED_I2C_SendByte(uint8_t Byte); void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char); void OLED_ShowString(uint8_t Line, uint8_t Column, char *String); void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length); void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length); void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length); void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length); void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]); #endif这段代码为OLED.H #ifndef __OLED_FONT_H #define __OLED_FONT_H #include “main.h” /OLED字模库,宽8像素,高16像素/ const uint8_t OLED_F8x16[][16]= { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1 0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2 0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00, 0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3 0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00, 0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00, 0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5 0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00, 0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6 0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//’ 7 0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00, 0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8 0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00, 0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9 0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00, 0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10 0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00, 0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14 0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04, 0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00, 0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00, 0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00, 0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00, 0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00, 0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00, 0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00, 0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00, 0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00, 0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00, 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00, 0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00, 0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30 0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00, 0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00, 0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00, 0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33 0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00, 0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34 0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00, 0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35 0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00, 0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00, 0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00, 0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38 0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00, 0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08, 0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40 0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41 0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00, 0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42 0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00, 0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43 0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00, 0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44 0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00, 0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45 0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08, 0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00, 0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47 0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00, 0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00, 0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49 0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00, 0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50 0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00, 0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51 0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00, 0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08, 0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08, 0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00, 0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55 0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08, 0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56 0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00, 0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57 0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00, 0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58 0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00, 0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59 0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60 0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00, 0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61 0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63 0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 64 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00, 0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65 0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00, 0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, 0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67 0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00, 0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00, 0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69 0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00, 0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71 0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00, 0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72 0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73 0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00, 0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74 0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00, 0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75 0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, 0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77 0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00, 0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00, 0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79 0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00, 0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00, 0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81 0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00, 0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00, 0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83 0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00, 0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84 0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00, 0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80, 0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86 0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80, 0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87 0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00, 0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80, 0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00, 0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90 0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02, 0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92 0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00, 0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93 0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94 }; #endif这段代码为我的OLED.Font.h。基于这三个OLED相关驱动代码,实现基于STM32 HAL库,使用STM32CUBEMX进行引脚配置,keil运行代码,生成hex文件,Proteus展示实验结果,实现对来自外部两路正交的方波(该方波为弦波经迟滞比较器后形成的方波,幅值为400mv)进行计数,然后计数结果用Proteus里的OLED12864I2C显示(没有使用I2C,使用PB6,PB7模拟SCL,SDA,基于我上述提供的OLED相关代码)。给出实现流程。

大家在看

recommend-type

CH340 驱动安装,硬件连接和软件安装,配置软件使用说明书

配置软件使用说明
recommend-type

基于MATLAB实现的电磁场仿真,有限长通电螺线管的仿真程序,网格计算实验效果好+使用说明文档.zip

CSDN IT狂飙上传的代码均可运行,功能ok的情况下才上传的,直接替换数据即可使用,小白也能轻松上手 【资源说明】 基于MATLAB实现的电磁场仿真,有限长通电螺线管的仿真程序,网格计算实验效果好+使用说明文档.zip 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2020b;若运行有误,根据提示GPT修改;若不会,私信博主(问题描述要详细); 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可后台私信博主; 4.1 期刊或参考文献复现 4.2 Matlab程序定制 4.3 科研合作 功率谱估计: 故障诊断分析: 雷达通信:雷达LFM、MIMO、成像、定位、干扰、检测、信号分析、脉冲压缩 滤波估计:SOC估计 目标定位:WSN定位、滤波跟踪、目标定位 生物电信号:肌电信号EMG、脑电信号EEG、心电信号ECG 通信系统:DOA估计、编码译码、变分模态分解、管道泄漏、滤波器、数字信号处理+传输+分析+去噪、数字信号调制、误码率、信号估计、DTMF、信号检测识别融合、LEACH协议、信号检测、水声通信 5、欢迎下载,沟通交流,互相学习,共同进步!
recommend-type

IFPUG工作量算法总结.pdf

对IFPUG功能点评估算法使用的概述总结
recommend-type

基于遗传算法的机场延误航班起飞调度模型python源代码

本资源提供机场航班延误调度模型的实现代码,采用遗传算法进行求解。 文本说明:https://blog.csdn.net/qq_43627520/article/details/128652626?spm=1001.2014.3001.5502 本资源提供机场航班延误调度模型的实现代码,采用遗传算法进行求解。 文本说明:https://blog.csdn.net/qq_43627520/article/details/128652626?spm=1001.2014.3001.5502 本资源提供机场航班延误调度模型的实现代码,采用遗传算法进行求解。 文本说明:https://blog.csdn.net/qq_43627520/article/details/128652626?spm=1001.2014.3001.5502 本资源提供机场航班延误调度模型的实现代码,采用遗传算法进行求解。 文本说明:https://blog.csdn.net/qq_43627520/article/details/128652626?spm=1001.2014.3001.5502
recommend-type

Toolbox使用说明.pdf

Toolbox 是快思聪公司新近推出的一款集成多种调试功能于一体的工具软件,它可以实现多种硬件检 测, 调试功能。完全可替代 Viewport 实现相应的功能。它提供了有 Text Console, SMW Program Tree, Network Device Tree, Script Manager, System Info, File Manager, Network Analyzer, Video Test Pattern 多个 检测调试工具, 其中 Text Console 主要执行基于文本编辑的命令; SMW Program Tree 主要罗列出相应 Simpl Windows 程序中设计到的相关快思聪设备, 并可对显示出的相关设备进行效验, 更新 Firmware, 上传 Project 等操作; Network Device Tree 主要使用于显示检测连接到 Cresnet 网络上相关设备, 可对网络上设备进行 ID 设置,侦测设备线路情况; Script Manager 主要用于运行脚本命令; System Info 则用于显示联机的控制系统 软硬件信息,也可对相应信息进行修改,刷新; File Manager 显示控制系统主机内存文件系统信息,可进行 修改,建立等管理操作; Video Test Pattern 则用于产生一个测试图调较屏幕显示; Network Analyzer 用于检 测连接到 Cresnet 网络上所有设备的通信线路情况。以上大致介绍了 Toolbox 中各工具软件的用途,下面将 分别讲述一下各工具的实际用法

最新推荐

recommend-type

XX企业网络安全培训.pptx

XX企业网络安全培训.pptx
recommend-type

游戏开发中的中文输入法IME实现与应用

从给定文件信息来看,我们主要关注的领域集中在如何在游戏开发中实现输入法编辑器(IME)来支持汉字输入。由于这个话题与编程实践紧密相关,我们将展开以下几个方面的知识点:IME的工作原理、游戏开发中实现IME的一般方法、以及中文输入法相关的编程资源。 IME(输入法编辑器)是一种软件工具,允许用户输入汉字和其他亚洲语言的字符。它提供了比标准键盘布局更高效的方式输入文字。由于游戏开发中可能需要支持多语言,其中包含中文用户的需求,因此实现一个稳定的IME支持至关重要。 ### IME工作原理 IME的实现是基于Unicode编码标准。当用户输入一个拼音时,IME会将这个拼音转换成一个或多个汉字候选,用户随后可以从候选列表中选择合适的汉字。此过程涉及以下步骤: 1. **拼音输入**:用户通过键盘输入拼音。 2. **拼音转换**:IME将输入的拼音转换成对应的汉字候选列表。 3. **选择与确认**:用户从候选列表中选择想要的汉字,然后确认输入。 ### 游戏开发中的IME实现 在游戏中实现IME,需要考虑如何将IME集成到游戏界面中,并确保用户输入的流畅性和正确性。以下是一些关键步骤和考虑事项: 1. **选择合适的开发平台和工具**:不同的游戏开发平台(如Unity、Unreal Engine等)可能提供不同的支持和接口来集成IME。 2. **集成IME组件**:开发人员需要将IME组件集成到游戏的用户界面中。这涉及到游戏引擎提供的UI系统以及可能的第三方IME库。 3. **处理键盘事件**:需要捕捉用户的键盘输入事件,并将其传递给IME进行处理。 4. **显示候选词窗口**:当用户输入拼音后,游戏需要能够显示一个候选词窗口,并在窗口中列出汉字候选。 5. **选择和确认机制**:游戏需要提供机制允许用户选择并确认输入的汉字,以及在必要时进行错误修正。 6. **性能优化**:IME的处理可能会消耗系统资源,因此需要进行适当的优化以保证游戏运行流畅。 ### 中文输入法相关的编程资源 从给定的文件名称列表中,我们可以得知有一些与“GameRes_com”相关的资源。尽管文件的具体内容未提供,我们可以推测这些资源可能是关于如何在游戏中实现中文输入法的示例代码或者库文件。通常,这些资源可能包括: 1. **GameRes_com.htm**:可能是一个HTML文件,其中包含关于IME集成的说明文档,或者是相关代码的参考文档。 2. **GameRes_com.files**:可能是一组文件,包含必要的类定义、资源文件、图像、样式表等,这些都可以被整合进游戏工程来支持中文输入。 3. **ime**:这可能是一个目录,里面包含了实现IME功能所需的所有资源,包括脚本、配置文件以及第三方库等。 ### 总结 在游戏开发中实现IME以支持汉字输入是一个复杂的过程,它不仅涉及到对开发环境和工具的深入理解,还需要考虑如何优化用户输入体验。由于中文用户的特殊需求,游戏开发者需要将IME集成到游戏中,并确保这一过程对玩家而言无缝且直观。以上提供的文件名称表明有一些现成的资源可以被利用,开发者可以通过阅读文档、示例代码或直接使用相关资源来快速实现这一功能。由于具体内容未提供,开发者还需要关注到细节实现的调整,以及针对特定游戏引擎或平台的开发指南。
recommend-type

【性能测试基准】:为RK3588选择合适的NVMe性能测试工具指南

# 1. NVMe性能测试基础 ## 1.1 NVMe协议简介 NVMe,全称为Non-Volatile Memory Express,是专为固态驱动器设计的逻辑设备接口规范。与传统的SATA接口相比,NVMe通过使用PCI Express(PCIe)总线,大大提高了存储设备的数据吞吐量和IOPS(每秒输入输出操作次数),特别适合于高速的固态存储设备。
recommend-type

implicit declaration of function 'Complementary_Init' [-Wimplicit-function-declaration] 这个报错是什么意思

<think>我们遇到了一个编译错误:`implicitdeclarationoffunction'Complementary_Init'`。这个错误表示在调用函数`Complementary_Init`时,编译器没有找到它的声明(即函数原型)。在C语言中,如果函数在使用之前没有被声明,编译器会按照旧的C标准(如C89)假设该函数返回`int`类型,并且参数类型根据实际调用进行推断。但在C99及以后的标准中,这种隐式声明是不允许的,因此会报错。###错误原因分析根据引用[2]的分析,出现`implicitdeclarationoffunction`错误通常有以下几种原因:1.**函数未声明**
recommend-type

MATLAB图像分析新手入门教程

MATLAB是一种高性能的数值计算和可视化软件,广泛应用于工程计算、控制设计、信号处理和通信等众多领域。在图像分析领域,MATLAB提供了强大的工具箱,使得图像处理和分析变得简单高效。本文将详细解析MATLAB在图像分析中的应用,并提供相关资源下载链接。 首先,需要明确MATLAB图像分析主要集中在以下几个方面: 1. 图像读取与显示:MATLAB提供了诸如`imread`、`imshow`等函数,可以很方便地读取和显示图像。`imread`可以读取不同格式的图像文件,而`imshow`则用于显示这些图像。对于初学者而言,掌握这些基础函数是进行图像分析的前提。 2. 图像类型和格式:MATLAB支持多种图像格式,如常见的`.jpg`、`.png`、`.bmp`等。不同格式图像的数据结构在MATLAB中可能有所不同,例如彩色图像和灰度图像的像素数据表示。了解不同图像格式的特点及其在MATLAB中的表示,对于后续的图像处理至关重要。 3. 图像基本操作:MATLAB可以进行图像的裁剪、缩放、旋转、平移等基本操作。例如,使用`imcrop`函数裁剪图像,`imresize`函数调整图像大小等。掌握这些操作对于图像预处理尤为重要。 4. 图像变换:包括傅立叶变换、离散余弦变换等。MATLAB中的`fft2`、`dct2`等函数可以实现这些变换。图像变换是图像分析中非常重要的一个环节,可以帮助我们从不同角度理解图像信息。 5. 图像增强:图像增强主要目的是改善图像的视觉效果,包括对比度调整、锐化、滤波去噪等。MATLAB中的`imadjust`、`fspecial`、`imfilter`等函数可以实现这些操作。 6. 图像分割:在图像分析中,将感兴趣的物体从背景中分割出来是常见需求。MATLAB提供了如`imsegfuzz`、`regionprops`等函数,帮助用户完成图像分割任务。 7. 特征提取与分析:MATLAB能够提取图像特征(如纹理、形状、颜色等),并进行统计分析。例如,使用`graythresh`进行阈值分割,`edge`函数进行边缘检测等。 8. 图像识别与分类:基于提取的特征,MATLAB可以利用机器学习算法对图像进行识别和分类。如使用MATLAB的机器学习工具箱中的`fitcknn`等函数来训练分类器。 通过使用MATLAB进行图像分析,可以实现从简单到复杂的各种图像处理任务。针对初学者,文件包中的“使用帮助:新手必看.htm”提供了入门指导,帮助新手快速理解MATLAB在图像处理方面的基本知识和操作;而“Matlab中文论坛--助努力的人完成毕业设计.url”可能指向一个在线论坛或社区,提供交流和求助的平台;“face_detection”表示该文件可能包含与人脸识别相关的示例代码或者教程。 对于初学者来说,MATLAB图像分析的难点往往在于对图像处理算法的理解和实际应用的结合。在实际操作中,建议从简单的图像读取与显示开始,逐步深入到图像处理的各个方面。同时,利用MATLAB强大的工具箱和社区资源,通过示例学习和实践,可以在实践中不断提升自身的图像分析能力。 上述文件包中提供的“face_detection”文件,很可能是一个关于人脸检测的应用示例。人脸检测作为图像分析中的一个重要领域,在计算机视觉和模式识别中占有重要地位。MATLAB在这一领域的工具箱如Computer Vision Toolbox提供了人脸检测的现成函数和算法,可以高效地帮助开发者完成人脸检测任务。 总结以上所述,MATLAB图像分析的知识点包括图像读取显示、格式转换、基本操作、变换、增强、分割、特征提取和图像识别分类等多个方面。对于初学者来说,通过实践操作和案例学习,可以逐步掌握这些知识,并应用到实际问题解决中。同时,利用好MATLAB提供的各种资源和社区,可以更快地学习和进步。
recommend-type

【固态硬盘寿命延长】:RK3588平台NVMe维护技巧大公开

# 1. 固态硬盘寿命延长的基础知识 ## 1.1 固态硬盘的基本概念 固态硬盘(SSD)是现代计算设备中不可或缺的存储设备之一。与传统的机械硬盘(HDD)相比,SSD拥有更快的读写速度、更小的体积和更低的功耗。但是,SSD也有其生命周期限制,主要受限于NAND闪存的写入次数。 ## 1.2 SSD的写入次数和寿命 每块SSD中的NAND闪存单元都有有限的写入次数。这意味着,随着时间的推移,SSD的
recommend-type

Reg.exe add "HKLM\SOFTWARE\Microsoft\DirectX" /v "DXGI_PREEMPTION_MODE" /t REG_DWORD /d "3" /f Reg.exe add "HKLM\SOFTWARE\Microsoft\DirectX" /v "DXGI_FRAME_LATENCY_WAITABLE_OBJECT" /t REG_DWORD /d "1" /f Reg.exe add "HKLM\SOFTWARE\Microsoft\DirectX" /v "DXGI_SWAP_CHAIN_WAITABLE_OBJECT" /t REG_DWORD /d "1" /f Reg.exe add "HKLM\SOFTWARE\Microsoft\DirectX" /v "DXGI_FORCE_FLIP_DISCARD" /t REG_DWORD /d "1" /f Reg.exe add "HKLM\SOFTWARE\Microsoft\DirectX" /v "DXGI_SWAP_CHAIN_SCALE" /t REG_DWORD /d "1" /f Reg.exe add "HKLM\SOFTWARE\Microsoft\DirectX" /v "DXGI_SWAP_CHAIN_ALLOW_MODE_SWITCH" /t REG_DWORD /d "1" /f Reg.exe add "HKLM\SOFTWARE\Microsoft\DirectX" /v "DXGI_SWAP_CHAIN_FULLSCREEN_FLIP_MODE" /t REG_DWORD /d "1" /f Reg.exe add "HKLM\SOFTWARE\Microsoft\DirectX" /v "DXGI_DISABLE_DWM_THROTTLING" /t REG_DWORD /d "1" /f Reg.exe add "HKLM\SOFTWARE\Microsoft\DirectX" /v "DXGI_FORCE_FLIP_SEQUENTIAL" /t REG_DWORD /d "1" /f Reg.exe add "HKLM\SOFTWARE\Microsoft\DirectX" /v "DXGI_FORCE_FULLSCREEN_FLIP_MODE" /t REG_DWORD /d "3" /f Reg.exe add "HKLM\SOFTWARE\Microsoft\DirectX" /v "DXGI_MAX_FRAME_LATENCY" /t REG_DWORD /d "2" /f Reg.exe add "HKLM\SOFTWARE\Microsoft\DirectX" /v "DXGI_USE_OPTIMIZED_SWAP_CHAIN" /t REG_DWORD /d "1" /f 这些注册表值有什么用,逐一解答

<think>我们正在讨论DirectX相关的注册表值。用户询问的是DXGI_PREEMPTION_MODE、DXGI_FRAME_LATENCY_WAITABLE_OBJECT、DXGI_SWAP_CHAIN_WAITABLE_OBJECT等的作用。注意:这些注册表值可能是用于调试或特定配置的,但并不是标准的DXGI公开接口。因此,它们可能不是官方文档中明确说明的,而是内部使用的或者特定驱动/调试设置。根据我的知识,这些值并不常见于公开文档,但我们可以尝试根据名称和上下文进行解释,并参考一些开发经验。1.DXGI_PREEMPTION_MODE:-这个注册表值可能与GPU抢占(Preempt
recommend-type

初学者C#商品销售管理系统源码分享与评价

标题“C#商品销售管理系统源代码.rar”暗示了一个包含C#语言编写的软件应用程序的压缩包文件。这个系统是用于处理商品销售相关数据和流程的软件,其主要目的是帮助用户有效地管理销售活动。该系统可能包含了商品信息管理、销售记录、库存跟踪、客户信息管理等核心功能。 描述中提到“用于学习”,说明这个源代码包是作为学习材料使用的,而不是作为商业软件销售。请求评价表明作者渴望得到反馈,以便于改进和完善代码。作者自称为“初学者”,意味着源代码可能更适合那些刚开始学习C#或者正在学习如何开发商品销售管理系统的开发者。 标签“源代码”表明这是一个代码级别的资源,适合那些需要查看、分析或修改实际代码的用户。 压缩包文件的文件名称列表中的“第4章 商品销售管理系统”可能指的是在某个教程或书籍中的一个章节,其中详细介绍了如何构建一个商品销售管理系统。这个章节很可能是针对有初步C#编程基础的读者,希望通过实际案例学习如何开发具体的商业应用。 基于以上信息,以下是关于C#商品销售管理系统源代码的相关知识点: 1. **C#基础**: 系统是基于C#开发的,C#是一种面向对象的编程语言,由微软开发。学习C#通常需要理解面向对象编程(OOP)的概念,如类、对象、继承、多态和封装等。 2. **软件开发周期**: 开发商品销售管理系统需要经历需求分析、设计、编码、测试和部署等多个阶段。了解这些开发流程对于构建一个有效且稳定的系统至关重要。 3. **数据库管理**: 商品销售管理系统通常需要处理大量数据,如商品信息、销售记录、库存水平和客户数据。这些数据的存储和管理往往需要数据库技术,如Microsoft SQL Server或其他数据库系统。 4. **用户界面设计**: 一个成功的商品销售管理系统需要一个直观易用的用户界面(UI)。UI设计涉及到窗体、控件和布局等元素,可能还会使用到WPF (Windows Presentation Foundation) 或 Windows Forms。 5. **事件驱动编程**: C#应用程序大多是事件驱动的。了解事件处理机制对于编写响应用户输入和其他系统事件的代码是必不可少的。 6. **LINQ (语言集成查询)**: LINQ是C#语言的一个重要特性,它允许开发者以声明方式查询和操作数据。在商品销售管理系统中,可能会使用LINQ来简化数据的检索和处理过程。 7. **错误处理**: 在开发任何系统时,编写健壮的错误处理代码是关键。学习如何捕获和处理异常对于创建一个稳定可靠的系统是不可或缺的。 8. **安全性**: 商品销售管理系统会处理敏感信息,如客户数据和交易记录。因此,理解并应用适当的安全措施来保护这些数据免受未授权访问是非常重要的。 9. **软件测试**: 开发过程中需要进行单元测试、集成测试和系统测试,以确保系统的各个部分都能正确地一起工作。 10. **部署和维护**: 了解如何将应用程序部署到生产环境,并对系统进行维护和更新,是整个开发周期中非常重要的一部分。 综上所述,C#商品销售管理系统源代码是一个极好的学习资源,尤其是对于那些想要加深对C#和商业应用开发理解的初学者而言。通过分析和运行源代码,开发者不仅可以学习如何使用C#语言和.NET框架构建实际应用,还可以掌握数据库设计、UI设计、系统测试和软件维护等关键技能。
recommend-type

【故障恢复策略】:RK3588与NVMe固态硬盘的容灾方案指南

# 1. RK3588处理器与NVMe固态硬盘的概述 ## 1.1 RK3588处理器简介 RK3588是Rockchip推出的一款高端处理器,具备强大的性能和多样的功能,集成了八核CPU和六核GPU,以及专用的AI处理单元,主要用于高端移动设备、边缘计算和
recommend-type

牺牲时域提高对比度具体内容是什么

<think>我们正在讨论的是在行扫描中通过牺牲时域(即时间分辨率或扫描速度)来提高图像对比度的方法。根据用户的问题和之前的回答,我们需要具体阐述图像处理或信号处理中如何通过增加时间(牺牲时域)来提升对比度。同时,用户提供的引用内容可以作为参考,但重点还是围绕牺牲时域提高对比度的核心方法。主要思路:通过延长每个像素或每行的采集时间(即增加曝光时间、积分时间等),可以累积更多的信号,从而提高信噪比(SNR),进而提升图像对比度。但这样会降低时间分辨率(即扫描速度变慢),这就是牺牲时域。具体方法:1.**增加积分时间(ExposureTime)**:在行扫描中,每个像素的采集时间可以独立控制。通过