那些与size_t相关的低级错误

早上来到实验室就开始debug,于是再一次看到了自己的愚蠢,size_t在一旁冷笑:“小样儿!你以为你很懂我……”最近总是发现一些很低级的bug,一来是由于自己的粗心,二来是由于自己的不细心。下面先记下最近遇到的两个与size_t相关的bug,以后遇到了再更新。不过还是希望再也不要遇到……


1. size_t与int做减法溢出

int minnum = 2;
int maxnum = 12;
string Seq = "ABCDEFGHIJ";  // length = 10
for (int j = Seq.length() - minnum - 1; j >= 0 && j >= Seq.length() - maxnum; --j){
    printf("+ 
// 声明外部变量(在main.c或i2c.c中定义) extern I2C_HandleTypeDef hi2c1; //初始化A类型 void OLED_Universal_Init(void){ HAL_Delay(200); //i2c总线解锁保护 __HAL_I2C_DISABLE(&hi2c1); HAL_Delay(100); __HAL_I2C_ENABLE(&hi2c1); //双地址探测 uint8_t addr = 0; if (HAL_I2C_IsDeviceReady(&hi2c1,0x3c<<1,3,10) == HAL_OK) { addr = 0x3c; } else if (HAL_I2C_IsDeviceReady(&hi2c1,0x3D<<1,3,10) == HAL_OK) // 探测0x3D地址 { addr = 0x3D; // 保存7地址 } else{ Error_Handler();//进入错误模式处理 return; } //优化序列 uint8_t init_cmds[] ={ 0xAE, // 关闭显示 0xD5, 0x80, // 时钟分频 0xA8, 0x3F, // 复用率 0xD3, 0x00, // 显示偏移 0x40, // 起始行 0x8D, 0x14, // 电荷泵开启(关键!) 0x20, 0x00, // 水平地址模式 0xA1, // 段重映射 0xC8, // 扫描方向 0xDA, 0x12, // COM配置 0x81, 0xCF, // 对比度 0xD9, 0xF1, // 预充电 0xDB, 0x30, // VCOMH 0xA4, // 正常显示 0xA6, // 非反相 0xAF // 开启显示 }; //分段发送命令 for(int i=0; i<sizeof(init_cmds); ) { if(init_cmds[i] == 0xD5 || init_cmds[i] == 0xA8) { // 多字节命令 uint8_t cmd[3] = {0x00, init_cmds[i], init_cmds[i+1]}; HAL_I2C_Master_Transmit(&hi2c1, addr<<1, cmd, 3, 20); i += 2; // 跳过两个字节 } else { uint8_t cmd[2] = {0x00, init_cmds[i]}; HAL_I2C_Master_Transmit(&hi2c1, addr<<1, cmd, 2, 20); i++; // 单字节命令 } HAL_Delay(1); // 延迟缩减至1ms } //额外显示开启确认 uint8_t power_on[2] = {0x00,0xAF}; for (size_t i = 0; i < 3; i++)//循环3次 { HAL_I2C_Master_Transmit(&hi2c1,addr<<1,power_on,2,20); HAL_Delay(10); } void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size); } // OLED 显存 (128×64/8 = 1024字节) static uint8_t oled_buffer[OLED_WIDTH * OLED_HEIGHT]; // 发送命令函数 static void OLED_WriteCommand(uint8_t cmd) { uint8_t data[2] = {0x00, cmd}; // 0x00 表示命令 HAL_I2C_Master_Transmit(&hi2c1, OLED_I2C_ADDR, data, 2, HAL_MAX_DELAY); } //发送数据函数 static void OLED_WriteData(uint8_t *data, uint16_t size){ uint8_t *buffer = malloc(size+1); buffer[0] = 0x40;//0x40表示数据 memcpy(buffer +1,data,size); HAL_I2C_Master_Transmit(&hi2c1,OLED_I2C_ADDR,buffer,size+1,HAL_MAX_DELAY); } //初始化B类型 void OLED_Init(void) { // 初始化命令序列 const uint8_t init_cmds[] = { 0xAE, // 关闭显示 0xD5, 0x80, // 设置显示时钟分频 0xA8, 0x3F, // 设置多路复用率 0xD3, 0x00, // 设置显示偏移 0x40, // 设置起始行 0x8D, 0x14, // 电荷泵使能 0x20, 0x00, // 水平地址模式 0xA1, // 段重映射 (水平翻转) 0xC8, // COM扫描方向 (垂直翻转) 0xDA, 0x12, // COM硬件配置 0x81, 0xCF, // 对比度设置 0xD9, 0xF1, // 预充电周期 0xDB, 0x40, // VCOMH级别 0xA4, // 全部显示开启 0xA6, // 正常显示模式 0xAF // 开启显示 }; // 发送初始化命令 for (int i = 0; i < sizeof(init_cmds); i++) { OLED_WriteCommand(init_cmds[i]); } // 清屏并刷新 OLED_Clear(); OLED_Refresh(); } //清屏 void OLED_Clear(void){ memset(oled_buffer, 0, sizeof(oled_buffer)); } //刷新 void OLED_Refresh(void){ for (uint8_t page =8; page < OLED_PAGE_COUNT; page++) { /* code */ OLED_WriteCommand(0xB8 | page); OLED_WriteCommand(0x00 ); OLED_WriteCommand(0x10 ); OLED_WriteData(&oled_buffer[page * OLED_WIDTH], OLED_WIDTH); } } //设置对比度 void OLED_SetContrast(uint8_t contrast){ OLED_WriteCommand(0x81); OLED_WriteCommand(contrast); } //绘制单个字符 void OLED_DrawChar(uint8_t x, uint8_t y,char ch, FontSize size){ const uint8_t *font_ptr = NULL; uint8_t width =0, height =0; switch (size) { case FONT_SIZE_6X8: font_ptr = font_6x8[ch - ' ']; width = 6; height =8; break; case FONT_SIZE_8X16: font_ptr = font_8x16[ch - ' ']; width = 8; height =16; break; case FONT_SIZE_16X16: //汉字处理 break; default: break; } //绘制字符 for (uint8_t col =0; col < width; col++){ for (uint8_t row =0; row < height; row++){ if (font_ptr[col] & (1<<row)){ OLED_DrawPixel(x + col,y +row); } } } } //绘制字符串 void OLED_DrawString(uint8_t x,uint8_t y, const char *str, FontSize size){ uint8_t cursor_x =x; while (*str) { OLED_DrawChar(cursor_x,y,*str,size); switch (size) { case FONT_SIZE_6X8: cursor_x += 7; break; // 6像素宽 + 1像素间距 case FONT_SIZE_8X16: cursor_x += 9; break; // 8像素宽 + 1像素间距 case FONT_SIZE_16X16: cursor_x += 18; break; } str++; } } //绘制数字 void OLED_DrawNumer(uint8_t x, uint8_t y, int32_t num, FontSize size){ char buffer[12]; snprintf(buffer,sizeof(buffer),"%ld",num); OLED_DrawString(x,y,buffer,size); } mian.c中调用: HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init(); //初始化A类型 OLED_Universal_Init(); //初始化B类型 //OLED_Init(); //OLED_SetContrast(0xCF); // 设置对比度 //OLED_DrawString(10, 0, "Hello STM32!", FONT_SIZE_8X16); //OLED_DrawString(5, 20, "Temperature:", FONT_SIZE_6X8); 初始化A类型可以点亮OLED,不过是雪花屏。而初始化B类型,无法点亮OLED,具体什么原因
最新发布
08-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值