怀揣少年梦

  • 2024-11-21
  • 加入了学习《DIY作品演示》,观看 【FM33LG0系列开发板测评】07.LCD & 段码显示软件实现框架

  • 2024-09-26
  • 回复了主题帖: 【2024 DigiKey 创意大赛】智能睡眠环境监测--05采集温湿度和气压传感器数据

    Jacktang 发表于 2024-9-26 07:29 温度、湿度、空气质量、气压,四合一的传感器,以后集成传感器可能就是一种趋势了 是的,主要是尺寸小,功能强大。不过价格贵

  • 2024-09-25
  • 发表了主题帖: 【2024 DigiKey 创意大赛】智能睡眠环境监测--06 OV5647摄像头测试

    本帖最后由 怀揣少年梦 于 2024-9-25 21:56 编辑 本次使用摄像头,主要使用摄像头进行图像识别。 这次先简单来测试一下摄像头是否正常,因为也是第一次在树莓派上使用摄像头。 一、摄像头型号 链接: 【淘宝】限时满100减5 http://e.tb.cn/h.gIpLq61FTSJ87vw?tk=qGhx3RCDEuG CZ3460 「树莓派5 CSI摄像头模块 OV5647 IMX219传感器相机 视觉识别摄像头」 点击链接直接打开 或者 淘宝搜索直接打开 具体型号:OV5647 二、连接 三、测试 1、查看树莓派的摄像头及其可用的传感器模式。 rpicam-hello --list-cameras   可以看到打印出了摄像头型号OV5647; 2、图片捕获 rpicam-jpeg -o test1.jpg 照片捕获完成,并且在当前目录下,生成一张test1.jpg的照片     3、生成视频文件 rpicam-vid -t 10s -o test.h264 // rpicam-vid -t 10s -o test.mp4 //生成MP4格式的视频 生成完成,并且在当前目录下,生成一个视频文件。     4、打开摄像头预览界面 sudo libcamera-hello -t 0//注意是在树莓派控制终端输入 显示的视频如下:   初步测试就到这里了

  • 2024-09-24
  • 发表了主题帖: 【2024 DigiKey 创意大赛】智能睡眠环境监测--05采集温湿度和气压传感器数据

    背景 由于智能睡眠环境监测,最主要的数据是温度、湿度、空气质量、气压,那么最好是采用四合一的传感器,那么博世正好有这一款传感器BME680,因此本篇文章主要是记录一下驱动BME680。 一、BME680传感器介绍 BME680是一款气压、气体、温湿度的四合一传感器,主要特性有低功耗,能够计算出空气质量。 并且1s内能够显示计算出气体电阻。数据手册的特性如下图:   二、编写代码 主要参照网络大神使用wiringPi库进行I2C驱动,大神,直接造了轮子,就拿来用了。个人主要是把微雪的代码拿来用就可以了。 参考链接:BME680 Environmental Sensor - Waveshare Wiki 主要代码如下: #include "main.h" #define BME68X_VALID_DATA UINT8_C(0xB0) //Raspberry 5 platform's default I2C device file #define IIC_Dev "/dev/i2c-1" struct bme68x_dev dev; int fd; void user_delay_us(uint32_t period, void *intf_ptr) { usleep(period); } int8_t user_i2c_read(uint8_t reg_addr, uint8_t *data, uint32_t len,void *intf_ptr) { write(fd, &reg_addr,1); read(fd, data, len); return 0; } int8_t user_i2c_write(uint8_t reg_addr, const uint8_t *data, uint32_t len,void *intf_ptr) { int8_t *buf; buf = malloc(len +1); buf[0] = reg_addr; memcpy(buf +1, data, len); write(fd, buf, len +1); free(buf); return 0; } void print_sensor_data(struct bme68x_data *comp_data) { #ifdef BME68X_USE_FPU printf("temperature:%0.2f*C pressure:%0.2fhPa humidity:%0.2f%% Gas resistance:%0.2f ohm\r\n",\ comp_data->temperature, comp_data->pressure/100, comp_data->humidity, comp_data->gas_resistance ); sysData.envTemp = comp_data->temperature; sysData.envHumidity = comp_data->humidity; sysData.airPressure = comp_data->pressure / 100; //sysData.airQuality = comp_data->gas_resistance / 100; printf("\r\b\r"); #else printf("temperature:%ld*C pressure:%ldhPa humidity:%ld%% Gas resistance:%lu ohm\r\n",comp_data->temperature, comp_data->pressure/100, comp_data->humidity, comp_data->gas_resistance ); printf("\r\b\r"); #endif } int8_t stream_sensor_data_forced_mode(struct bme68x_dev *dev) { int8_t rslt; uint8_t n_fields; uint32_t del_period; struct bme68x_conf conf; struct bme68x_heatr_conf heatr_conf; struct bme68x_data comp_data; /* Recommended mode of operation: Indoor navigation */ conf.os_hum = BME68X_OS_1X; conf.os_pres = BME68X_OS_16X; conf.os_temp = BME68X_OS_2X; conf.filter = BME68X_FILTER_SIZE_15; rslt = bme68x_set_conf(&conf, dev); dev->delay_us(40*1000,dev->intf_ptr); heatr_conf.enable = BME68X_ENABLE; heatr_conf.heatr_temp = 300; heatr_conf.heatr_dur = 100; rslt = bme68x_set_heatr_conf(BME68X_FORCED_MODE, &heatr_conf, dev); dev->delay_us(40*1000,dev->intf_ptr); printf("Temperature Pressure Humidity Gas resistance\r\n"); /* Continuously stream sensor data */ rslt = bme68x_set_op_mode(BME68X_FORCED_MODE, dev); /* Wait for the measurement to complete and print data [url=home.php?mod=space&uid=1140227]@25Hz[/url] */ del_period = bme68x_get_meas_dur(BME68X_FORCED_MODE, &conf, dev) + (heatr_conf.heatr_dur * 1000); dev->delay_us(del_period*5, dev->intf_ptr); rslt = bme68x_get_data(BME68X_FORCED_MODE, &comp_data, &n_fields, dev); if(n_fields) { print_sensor_data(&comp_data); } return rslt; } int8_t stream_sensor_data_parallel_mode(struct bme68x_dev *dev) { int8_t rslt; uint8_t n_fields; struct bme68x_conf conf; struct bme68x_heatr_conf heatr_conf; struct bme68x_data comp_data[3]; uint16_t temp_prof[10] = { 320, 100, 100, 100, 200, 200, 200, 320, 320, 320 }; uint16_t mul_prof[10] = { 5, 2, 10, 30, 5, 5, 5, 5, 5, 5 }; /* Recommended mode of operation: Indoor navigation */ conf.os_hum = BME68X_OS_1X; conf.os_pres = BME68X_OS_16X; conf.os_temp = BME68X_OS_2X; conf.filter = BME68X_FILTER_SIZE_15; conf.odr = BME68X_ODR_62_5_MS; rslt = bme68x_set_conf(&conf, dev); dev->delay_us(40*1000,dev->intf_ptr); heatr_conf.enable = BME68X_ENABLE; heatr_conf.heatr_temp_prof = temp_prof; heatr_conf.heatr_dur_prof = mul_prof; heatr_conf.shared_heatr_dur = 140 - (bme68x_get_meas_dur(BME68X_PARALLEL_MODE, &conf, dev) / 1000); heatr_conf.profile_len = 10; rslt = bme68x_set_heatr_conf(BME68X_PARALLEL_MODE, &heatr_conf, dev); dev->delay_us(40*1000,dev->intf_ptr); rslt = bme68x_set_op_mode(BME68X_PARALLEL_MODE, dev); dev->delay_us(40*1000,dev->intf_ptr); printf("Temperature Pressure Humidity Gas resistance\r\n"); while (1) { /* Delay while the sensor completes a measurement */ dev->delay_us(70*1000,dev->intf_ptr); rslt = bme68x_get_data(BME68X_FORCED_MODE, comp_data, &n_fields, dev); for (uint8_t i = 0; i < n_fields; i++) { if (comp_data[i].status == BME68X_VALID_DATA) { print_sensor_data(&comp_data[i]); } } } return rslt; } void bme680Init(void) { static uint8_t dev_addr=BME68X_I2C_ADDR_HIGH; int8_t rslt = BME68X_OK; int8_t bsec_ret = BSEC_OK; uint8_t bsec_state[BSEC_MAX_STATE_BLOB_SIZE] = {0}; uint8_t bsec_config[BSEC_MAX_PROPERTY_BLOB_SIZE] = {0}; uint8_t work_buffer[BSEC_MAX_WORKBUFFER_SIZE] = {0}; int bsec_state_len, bsec_config_len; if ((fd = open(IIC_Dev, O_RDWR)) < 0) { printf("Failed to open the i2c bus"); exit(1); } if (ioctl(fd, I2C_SLAVE, 0x77) < 0) { printf("Failed to acquire bus access and/or talk to slave.\n"); exit(1); } //dev.dev_id = BME68X_I2C_ADDR_PRIM;//0x76 dev.intf_ptr = &dev_addr; //0x77 dev.intf = BME68X_I2C_INTF; dev.read = user_i2c_read; dev.write = user_i2c_write; dev.delay_us = user_delay_us; rslt = bme68x_init(&dev); printf("\r\n BME68X Init Result is:%d \r\n",rslt); /* Initialize BSEC library */ bsec_ret = bsec_init(); if (bsec_ret != BSEC_OK) { printf("\r\n bsec_init Result is:%d \r\n",rslt); } /* Load library config, if available */ bsec_config_len = config_load(bsec_config, sizeof(bsec_config)); if (bsec_config_len != 0) { bsec_ret = bsec_set_configuration(bsec_config, bsec_config_len, work_buffer, sizeof(work_buffer)); if (bsec_ret != BSEC_OK) { return ret; } } /* Load previous library state, if available */ bsec_state_len = state_load(bsec_state, sizeof(bsec_state)); if (bsec_state_len != 0) { bsec_ret = bsec_set_state(bsec_state, bsec_state_len, work_buffer, sizeof(work_buffer)); if (bsec_ret != BSEC_OK) { return ret; } } /* Set temperature offset */ //bme680_temperature_offset_g = temperature_offset; /* Call to the function which sets the library with subscription information */ bsec_ret = bme680_bsec_update_subscription(BSEC_SAMPLE_RATE_LP); if (bsec_ret != BSEC_OK) { return ret; } } void bme680_test(void) { stream_sensor_data_forced_mode(&dev); //stream_sensor_data_parallel_mode(&dev); } 三、硬件连接 使用树莓派的I2C1,将如图的I2C1的引脚与BME680的I2C1的SDA&SCL连接即可。   四、验证 1、使能I2C 1) 运行sudo raspi-config 选择Interface Option   2)选择I2C接口   3)进行使能即可   2、检测I2C器件 1)查看i2c设备 ls /dev/ | grep i2c*   2)安装i2c-tools sudo apt-get install -y i2c-tools 3)检测IC设备器件 一开始全是0,找不到数据,进行如下操作就可以了。记得重启 sudo modprobe -r i2c_bcm2708 #卸载设备 -r代表remove sudo modprobe i2c_bcm2708 #重新载入设备 检测到BME680的器件地址为0x77,与实际器件地址一致   3、编译代码 gcc -Wall *.c -o bme68x -lwiringPi 4、运行 运行之后可以看到打印气体电阻、气压、温湿度的值   5、与OLED联合显示  

  • 2024-09-15
  • 回复了主题帖: 树莓派5开启一直卡在限流,求教各位大佬支招

    tagetage 发表于 2024-9-15 12:05 大概率是TF卡长期使用,系统文件出现问题。 重新做系统就能好。 树莓派建议使用闪迪的高端V30 ... 多谢大佬,也确实换了一张闪迪的SD卡,

  • 2024-09-14
  • 发表了主题帖: 【2024 DigiKey 创意大赛】智能睡眠环境监测--04使用SPI点亮OLED

    本次大赛将使用OLED屏,作为主要显示器件,因此,驱动OLED显示屏,作为大赛的第一步。 话不多说,直接见现象。 一、安装WiringPi库 具体步骤不赘述,此前已经说明。参考【2024 DigiKey 创意大赛】智能睡眠环境监测--03点亮LED - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn) 二、硬件连接 直接看图即可   三、编写软件 OLED代码: #include "OLED.h" #include "oledfont.h" /*OLED段码分布 正常 (page0) SEG0-SEG128 COM0 | COM7 反置 (page0) SEG128-SEG0 COM63 | COM56 写命令,其实是写寄存器 */ void GpioInit(void) { pinMode(OLED_DC_Pin,OUTPUT); pinMode(OLED_CS_Pin,OUTPUT); pinMode(OLED_RST_Pin,OUTPUT); } /**************************************************************************** * 名 称:void OLED_Init(void) * 功 能:OLED初始化 * 入口参数:无 * 出口参数:无 * 说 明:参照上电序列初始化(24/40) ****************************************************************************/ void OLED_Init(void) { int result = 0; int spifd = 0; result = wiringPiSetup () ; // 初始化wiringPI系统; if (result == -1) { printf("gpio system init failed"); } spifd = wiringPiSPISetup(SPI_CHAN, SPI_SPEED);//默认SPI模式0 if (spifd < 0) { printf("spi init failed"); } GpioInit(); OLED_CS_High; //复位OLED OLED_RST_High; delay(200); OLED_RST_Low; delay(200); OLED_RST_High; OLED_Write_Operate(OLED_Mode_Cmd,0xAE); //关闭OLED OLED_Write_Operate(OLED_Mode_Cmd,0x00); //设置列低位地址 OLED_Write_Operate(OLED_Mode_Cmd,0x10); //设置列高位地址 OLED_Write_Operate(OLED_Mode_Cmd,0x40); //设置起始行地址及映射RAM显示起始行 (0x00~0x3F) OLED_Write_Operate(OLED_Mode_Cmd,0xB0); //设置页地址 OLED_Write_Operate(OLED_Mode_Cmd,0x81); //对比度设置 OLED_Write_Operate(OLED_Mode_Cmd,0xCF); //Set SEG Output Current Brightness OLED_Write_Operate(OLED_Mode_Cmd,0xA1); //Set SEG/Column Mapping 0xa0左右反置 0xa1正常 OLED_Write_Operate(OLED_Mode_Cmd,0xA6); // OLED_Write_Operate(OLED_Mode_Cmd,0xA8); //设置驱动路数(1 to 64) OLED_Write_Operate(OLED_Mode_Cmd,0x3F); //*duty = 1/64*/ OLED_Write_Operate(OLED_Mode_Cmd,0xC8); //0xc0上下反置 0xc8正常 OLED_Write_Operate(OLED_Mode_Cmd,0xD3); //设置显示偏移(0x00~0x3F) OLED_Write_Operate(OLED_Mode_Cmd,0x00); //not offset OLED_Write_Operate(OLED_Mode_Cmd,0xD5); //--set Display clock divide ratio/oscillator frequency OLED_Write_Operate(OLED_Mode_Cmd,0x80); //--set divide ratio, Set Clock as 100 Frames/Sec OLED_Write_Operate(OLED_Mode_Cmd,0xD9); //*set pre-charge period*/ OLED_Write_Operate(OLED_Mode_Cmd,0Xf1); //Set Pre-Charge as 15 Clocks & Discharge as 1 Clock OLED_Write_Operate(OLED_Mode_Cmd,0xDA); //*set COM pins*/ OLED_Write_Operate(OLED_Mode_Cmd,0x12); // OLED_Write_Operate(OLED_Mode_Cmd,0xdb); //*set vcomh*/ OLED_Write_Operate(OLED_Mode_Cmd,0x40); //Set VCOM Deselect Level /**/ OLED_Write_Operate(OLED_Mode_Cmd,0x20); //设置存储模式(0x00,0x02,0x01) OLED_Write_Operate(OLED_Mode_Cmd,0x02); //页地址模式 OLED_Write_Operate(OLED_Mode_Cmd,0x8d); //*set charge pump disable*/ OLED_Write_Operate(OLED_Mode_Cmd,0x14); //--set(0x10) disable /**/ OLED_Write_Operate(OLED_Mode_Cmd,0xA4); //显示开启(A4,显示,A5无显示) OLED_Write_Operate(OLED_Mode_Cmd,0xA6); //背景正反向显示(0xa6,正显,0xa7,反显) OLED_Display_Clear(); //清屏 OLED_Write_Operate(OLED_Mode_Cmd,0xAF); //打开显示 } /**************************************************************************** * 名 称:uint8_t OLED_Write_Byte(uint8_t data) * 功 能:OLED写一个字节 * 入口参数:无 * 出口参数:接收的数据 * 返回值 :0失败,1成功 * 说 明:无 ****************************************************************************/ void OLED_Write_Byte(uint8_t data) { wiringPiSPIDataRW(SPI_CHAN, &data, 1); } /**************************************************************************** * 名 称:void OLED_Write_Operate(uint8_t mode,uint8_t data) * 功 能:OLED写操作 * 入口参数:模式,数据 * 出口参数:无 * 返回值 :无 * 说 明:无 ****************************************************************************/ void OLED_Write_Operate(uint8_t mode,uint8_t data) { OLED_CS_Low; if(mode) { OLED_Write_Data; } else { OLED_Write_Cmd; } OLED_Write_Byte(data); OLED_CS_High; } /**************************************************************************** * 名 称:void OLED_Display_Clear(void) * 功 能:OLED清屏 * 入口参数:无 * 出口参数:无 * 返回值 :无 * 说 明:无 ****************************************************************************/ void OLED_Display_Clear(void) { uint8_t page = 0; uint8_t i=0; OLED_CS_Low; for(page=0;page < 8; page++) { OLED_Write_Operate(OLED_Mode_Cmd,0xB0+page);//设置页地址 OLED_Write_Operate(OLED_Mode_Cmd,0x00); //设置显示位置-列低地址 OLED_Write_Operate(OLED_Mode_Cmd,0x10); //设置显示位置-列高地址 for(i = 0;i< 128; i++) { OLED_Write_Operate(OLED_Mode_Data,0x00); //清屏 } } } /**************************************************************************** * 名 称:void OLED_Set_Positon(void) * 功 能:设置显示坐标 * 入口参数:x,y * 出口参数:无 * 返回值 :无 * 说 明:无 ****************************************************************************/ void OLED_Set_Positon(uint8_t x,uint8_t y) { OLED_Write_Operate(OLED_Mode_Cmd,0xB0 + y); //设置页地址 OLED_Write_Operate(OLED_Mode_Cmd,((x & 0xf0) >>4 ) | 0x10); //设置列高四位地址 OLED_Write_Operate(OLED_Mode_Cmd,(x & 0x0f) | 0x01); //设置列低四位地址 } /**************************************************************************** * 名 称:void OLED_Display_on(void) * 功 能:显示打开 * 入口参数:无 * 出口参数:无 * 返回值 :无 * 说 明:无 ****************************************************************************/ void OLED_Display_on(void) { OLED_Write_Operate(OLED_Mode_Cmd,0x8d); //写充电泵寄存器 OLED_Write_Operate(OLED_Mode_Cmd,0x14); //打开充电泵 OLED_Write_Operate(OLED_Mode_Cmd,0xAF); //打开OLED显示 } /**************************************************************************** * 名 称:void OLED_Display_offvoid) * 功 能:显示关闭 * 入口参数:无 * 出口参数:无 * 返回值 :无 * 说 明:无 ****************************************************************************/ void OLED_Display_off(void) { OLED_Write_Operate(OLED_Mode_Cmd,0x8d); //写充电泵寄存器 OLED_Write_Operate(OLED_Mode_Cmd,0x10); //关闭充电泵 OLED_Write_Operate(OLED_Mode_Cmd,0xAE); //关闭OLED显示 } /**************************************************************************** * 名 称:void OLED_Display_onechar(uint8_t x,uint8_t y,uint8_t character,uint8_t size) * 功 能:显示单个字符 * 入口参数: x ,y坐标位置 character 字符 size 字号大小 * 出口参数:无 * 返回值 :无 * 说 明:无 ****************************************************************************/ void OLED_Display_onechar(uint8_t x,uint8_t y,uint8_t character,uint8_t size) { uint8_t c=0,i=0; c = character-' '; if(x > MAX_COLUMN - 1) { x= 0; if(size == SIZE8) { y = y+1; } if(size == SIZE16) { y = y+2; } } if(size == SIZE16) { OLED_Set_Positon(x,y); for( i =0;i< 8; i++) { OLED_Write_Operate(OLED_Mode_Data,F8X16[c*16 + i]); } OLED_Set_Positon(x,y+1); for( i =0;i< 8; i++) { OLED_Write_Operate(OLED_Mode_Data,F8X16[c*16 + i+8]); } } else { OLED_Set_Positon(x,y+1); for( i =0;i< 6; i++) { OLED_Write_Operate(OLED_Mode_Data,F6x8[c][i]); } } } /**************************************************************************** * 名 称:void OLED_Display_string(uint8_t x,uint8_t y,uint8_t *str,uint8_t size) * 功 能:显示字符串 * 入口参数: x ,y坐标位置 str 字符串 size 字号大小 * 出口参数:无 * 返回值 :无 * 说 明:无 ****************************************************************************/ void OLED_Display_string(uint8_t x,uint8_t y,uint8_t *str,uint8_t size) { uint8_t i=0; while(str[i]!='\0') { OLED_Display_onechar(x,y,str[i],size); x += 8; if(x > 120) { x = 0; y += 2; } i++; } } /**************************************************************************** * 名 称:void OLED_Display_Chinese(uint8_t x,uint8_t y,uint8_t Sno) * 功 能:显示单个字符 * 入口参数: x ,y坐标位置 Sno 表示汉字数组中一个字的码所占的序号 * 出口参数:无 * 返回值 :无 * 说 明:无 ****************************************************************************/ void OLED_Display_Chinese(uint8_t x,uint8_t y,uint8_t Sno) { uint8_t addr=0,i=0; OLED_Set_Positon(x,y); for(i = 0;i< 16;i++) { OLED_Write_Operate(OLED_Mode_Data,Hzk[2*Sno][i]); addr += 1; } OLED_Set_Positon(x,y+1); for(i = 0;i< 16;i++) { OLED_Write_Operate(OLED_Mode_Data,Hzk[2*Sno+1][i]); addr += 1; } } /**************************************************************************** * 名 称:uint32_t OLED_POW(uint8_t m, uint8_t n) * 功 能:m的n次方 * 入口参数: m为底数,n为指数 * 出口参数:无 * 返回值 :无 * 说 明:无 ****************************************************************************/ uint32_t OLED_POW(uint8_t m, uint8_t n) { uint32_t result=1; while(n--) { result *= m; } return result; } /**************************************************************************** * 名 称:void OLED_Display_Num(uint8_t x,uint8_t y,uint32_t num, uint8_t Len,uint8_t size) * 功 能:显示单个字符 * 入口参数: x ,y坐标位置 Sno 表示汉字数组中一个字的码所占的序号 * 出口参数:无 * 返回值 :无 * 说 明:无 ****************************************************************************/ void OLED_Display_Num(uint8_t x,uint8_t y,uint32_t num, uint8_t len,uint8_t size) { uint8_t i=0; uint8_t endisplay=0; uint8_t temp=0; for(i = 0;i < len;i++) { temp = (num / (OLED_POW(10,len-i-1)))%10; if(endisplay == 0 && i < len-1) { if(temp == 0) { OLED_Display_onechar(x + size * i,y,'0',size); continue; } else { endisplay = 1; } } //OLED_Display_onechar(x + (size / 2) * i,y,temp + '0',size); OLED_Display_onechar(x + size * i,y,temp + '0', size); } } /**************************************************************************** * 名 称:void OLED_Display_Picture(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t BMP[]) * 功 能:显示一张图片 * 入口参数: x0 ,y0,x1,y1图片的大小 BMP[] 图片的码 * 出口参数:无 * 返回值 :无 * 说 明:无 ****************************************************************************/ void OLED_Display_Picture(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t BMP[]) { uint8_t i=0; uint8_t x,y; if(y1 == 8) { y= y1/ 8; } else { y = y1/ 8 + 1; } for(y = y0;y < y1;y++) { OLED_Set_Positon(x0,y); for(x = x0;x< x1; x++) { OLED_Write_Operate(OLED_Mode_Data,BMP[i++]); } } } 主函数代码 /* * @Author: liuxingguo 1017041908[url=home.php?mod=space&uid=803337]@qq.com[/url] * @Date: 2024-09-12 23:41:20 * @LastEditors: liuxingguo 1017041908@qq.com * @LastEditTime: 2024-09-13 14:46:59 * @FilePath: \OLED\main.c * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE */ #include "main.h" SysDataStruct sysData; void DataDisplay(int sig); int main(void) { OLED_Init(); signal(SIGALRM,DataDisplay); SetTimer(); GetLocalIp(); while(1) { GetSysTime(); GetCpuTemp(); sleep(1); } return 0; } void DataDisplay(int sig) { OLED_Display_Clear(); //显示主题 OLED_Display_string(16,0,(uint8_t *)"Data Display",SIZE8); //显示时间 OLED_Display_Num(0,1,sysData.year,4,SIZE8); OLED_Display_onechar(31,1,(uint8_t)'-',SIZE8); OLED_Display_Num(35,1,sysData.month,2,SIZE8); OLED_Display_onechar(51,1,(uint8_t)'-',SIZE8); OLED_Display_Num(54,1,sysData.day,2,SIZE8); OLED_Display_Num(72,1,sysData.hour,2,SIZE8); OLED_Display_onechar(87,1,(uint8_t)':',SIZE8); OLED_Display_Num(91,1,sysData.min,2,SIZE8); OLED_Display_onechar(107,1,(uint8_t)':',SIZE8); OLED_Display_Num(110,1,sysData.sec,2,SIZE8); //显示设备温度 OLED_Display_string(0,2,(uint8_t *)"C-T:",SIZE8); OLED_Display_Num(36,2,sysData.cpuTemp,2,SIZE8); //显示环境温度 OLED_Display_string(76,2,(uint8_t *)"E-T:",SIZE8); OLED_Display_Num(112,2,(uint32_t)sysData.envTemp,2,SIZE8); if (sysData.envTemp < 250) { sysData.envTemp += 5; } else { sysData.envTemp = 0; } //显示环境湿度 OLED_Display_string(0,3,(uint8_t *)"hud:",SIZE8); OLED_Display_Num(36,3,sysData.envHumidity,2,SIZE8); //显示环境光强 OLED_Display_string(76,3,(uint8_t *)"lig:",SIZE8); OLED_Display_Num(108,3,sysData.lightIntensity,2,SIZE8); //显示气压 OLED_Display_string(0,4,(uint8_t *)"AP:",SIZE8); OLED_Display_Num(24,4,sysData.airPressure,4,SIZE8); //显示空气质量 OLED_Display_string(60,4,(uint8_t *)"IAQ:",SIZE8); OLED_Display_Num(90,4,sysData.airQuality,4,SIZE8); //显示IP地址 OLED_Display_string(0,6,(uint8_t *)"IP:",SIZE8); OLED_Display_string(20,6,(uint8_t *)sysData.localIpAddress,SIZE8); } 四、打开SPI驱动设备 树莓派5默认没有打开SPI驱动设备,使用sudo raspi-config打开SPI设备 1)打开界面后,选择Interface Options   2)选择SPI,最后选择使能即可   3)输入 ls /dev | grep spi 终端打印SPI设备数字,即打开成功。   五、编译 将相关文件上传至树莓派 使用如下指令编译 gcc main.c OLED.c usersys.c -o OLED -lwiringPi 没有错误,没有警告;即可运行 六、运行 sudo ./OLED 现象如下: [localvideo]65ca7e34b830be7ba088f35c4f43f6cf[/localvideo]

  • 回复了主题帖: 树莓派5开启一直卡在限流,求教各位大佬支招

    多谢各位大佬的支持,换了一张64G的卡,重新烧录系统即可重新正常开机

  • 回复了主题帖: 树莓派5开启一直卡在限流,求教各位大佬支招

    ly87802541 发表于 2024-9-14 22:55 啥也不说了,直接上小米67瓦快充头,不接HDMI显示器毫无问题哈哈   666啊  

  • 回复了主题帖: 树莓派5开启一直卡在限流,求教各位大佬支招

    tagetage 发表于 2024-9-14 16:38 USB没接设备而报这个错误,  第一步就是重新安装一下系统。 我用SD卡安装的系统额;可能是SD卡系统有点问题。

  • 回复了主题帖: 【2024 DigiKey 创意大赛】智能睡眠环境监测--03点亮LED

    okhxyyo 发表于 2024-9-14 09:56 真好,打比赛玩板子的同时又学新技能啦~~期待你的作品呀 多谢鼓励

  • 回复了主题帖: 树莓派5开启一直卡在限流,求教各位大佬支招

    tagetage 发表于 2024-9-14 09:27 你没说是树莓派几代,没说插在USB2.0还是3.0的口上,没说你USB插了哪些设备,这么关键的问题都没说,没法帮 ... 已经修改描述,多谢大佬。USB没有接任何设备

  • 回复了主题帖: 树莓派5开启一直卡在限流,求教各位大佬支招

    lansebuluo 发表于 2024-9-14 08:20 把USB上的设备都拔掉,然后上电试一下,看看行不行 USB没接设备

  • 回复了主题帖: 树莓派5开启一直卡在限流,求教各位大佬支招

    Jacktang 发表于 2024-9-14 07:39 是不是异物造成短路 应该过压或限流保护了 准备重新烧写系统试试

  • 2024-09-13
  • 发表了主题帖: 【2024 DigiKey 创意大赛】智能睡眠环境监测--03点亮LED

    背景: 这是本人第一次玩树莓派,属于妥妥的树莓派小白,因此小从点灯开始,进行树莓派的入门。 介于本人目前只擅长C语言,因此使用C语言进行控制树莓派40 pin的GPIO。从网络上学习到,大部分大佬入门是安装第三方库进行点灯,我也依葫芦画瓢吧。本人就使用wiring进行点灯。之所以学习wiringPi,主要是因为这个库支持C语言开发。 一、WiringPi库简介。 WiringPi库是由Gordon Henderson用C语言写成的类库。最开始,主要是作为 BCM2835 芯片的 GPIO 库,不过,现在是非常丰富,还包括了I2C 库、SPI 库、UART 库和软件 PWM 库等。现在支持所有的树莓派板(包含树莓派5) WiringPi库主要有以下特点: 二、安装 1、下载WiringPi库源码 git clone https://github.com/WiringPi/WiringPi.git 2、编译安装 cd WiringPi sudo ./build sudo make install 3、安装好之后,查看版本 gpio -v gpio readall //查看已经分布 三、编写程序 1、使用说明 要使用gpio操作,必须 1)包含头文件 2)进行GPIO 配置初始化 #include <wiringPi.h> void main(void) { wiringPiSetup () ; // 初始化wiringPI系统; } 2、编写点灯程序 #include <wiringPi.h> #include <stdio.h> int main (void) { uint8_t result = 0; result = wiringPiSetup () ; // 初始化 这个必须写在最前面 if (result != -1) { printf("gpio sys init successfully\r\n"); } pinMode (0, OUTPUT) ; // 设置GPIO.0 为输出 for (;;) // 无限循环 { digitalWrite (0, HIGH); // GPIO.0 输出高 delay (500); // 延时500毫秒 digitalWrite (0, LOW); // GPIO.0 输出低 delay (500); } return 0 ; } 3、编译 gcc -Wall -o gpio gpio.c -lwiringPi 4、运行 sudo ./gpio 5、现象 [localvideo]f3bdf6818e451c61a59694ad699b941b[/localvideo] 四、参考资料 1、源码 GitHub - WiringPi/WiringPi:Raspberry Pi 可以说是最快的 GPIO 库 2、WiringPi库介绍 树莓派 wiringPi 用户手册 - 小鹏STEM (xpstem.com) 下次就进行OLED驱动显示

  • 发表了主题帖: 树莓派5开启一直卡在限流,求教各位大佬支招

    本帖最后由 怀揣少年梦 于 2024-9-14 15:41 编辑 背景:         9月12号晚上还能开机,今天晚上开机,就一直卡在Selecting USB low current limit;         如图:   使用的是小米转换头 5V 3A供电;前几天还可以正常开机,今天就不行。 现象就是一直卡在限流那里,并且风扇一直在转,重启了几次了,还是不行。 USB没有接任何设备。 使用3p debug 进行串口打印 求教论坛各位大佬

  • 2024-09-11
  • 回复了主题帖: 中秋芯积分兑换月饼、实用工具健身器材啦!

    不错不错,积分兑换得活动不嫌多

  • 2024-09-10
  • 回复了主题帖: 下载MPS AI电源资料包,赢【Keep体脂秤、按摩眼罩、电脑支架】

    已经参加

  • 2024-09-09
  • 回复了主题帖: 测评颁奖:NUCLEO H533RE测评,集体通关~

    向各位大佬学习,也谢谢管管鼓励

  • 2024-08-17
  • 发表了主题帖: 【NUCLEO-H533RE开发板测评】07 LCD显示性能杠杠的

    LCD是嵌入式开发过程中常用屏之一,也是DIY开发者必备屏幕之一,因此本篇测评进行LCD测试,主要看一下H533驱动LCD屏显示的速度 一、所需硬件 1、NUCLEO-H533 开发板 2、2.5寸 TFT-LCD 显示屏(ILI9341驱动芯片)模块 3、8根杜邦线(主要用于与LCD屏连接) 4、Type-C的USB线 二、显示原理 简单地可以理解为LCD屏上有很多个像素点(这些个像素点就像是一个小小的LED灯),把图片的像素点对应屏上像素点,就可以显示对应的图片或者文字。显示原理就不赘述了,网络实在太多了。话不多少,直接上代码测试。 三、代码编写 基本代码都是移植厂家提供的案例,已经有大佬写了轮子,为什么还需要重新造轮子呢?所以,本篇主要显示测试结果。 1、核心代码 就是SPI写数据以及写LCD寄存器的代码,如下: /* @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, QD electronic SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. **************************************************************************************************/ #include "lcd.h" #include "spi.h" #include <stdio.h> //管理LCD重要参数 //默认为竖屏 _lcd_dev lcddev; //画笔颜色,背景颜色 uint16_t POINT_COLOR = 0x0000,BACK_COLOR = 0xFFFF; uint16_t DeviceCode; uint8_t LCD_SPI_WriteByte(uint8_t TxData) { uint8_t RxData = 0X00; #if LCD_FAST_WRITE SPI2->CR1 = SPI_CR1_SSI; SPI2->CR2 = 1; SPI2->CR1 = SPI_CR1_SPE | SPI_CR1_SSI; SPI2->CR1 = SPI_CR1_SPE | SPI_CR1_SSI | SPI_CR1_CSTART; while ((SPI2->SR & SPI_FLAG_TXP) == 0); *((__IO uint8_t *)&SPI2->TXDR) = TxData; while ((SPI2->SR & SPI_FLAG_TXC) == 0); SPI2->IFCR = SPI_IFCR_EOTC | SPI_IFCR_TXTFC; SPI2->CR1 &= ~(SPI_CR1_SPE); return RxData; #else if(HAL_SPI_TransmitReceive(LCD_SPI_Handle, &TxData, &RxData, 1, 100) != HAL_OK) { RxData = 0XFF; } #endif return RxData; } /***************************************************************************** * [url=home.php?mod=space&uid=32621]@name[/url] :void LCD_WR_REG(uint8_t data) * [url=home.php?mod=space&uid=311857]@date[/url] :2018-08-09 * [url=home.php?mod=space&uid=665173]@FUNCTION[/url] :Write an 8-bit command to the LCD screen * @parameters :data:Command value to be written * @retvalue :None ******************************************************************************/ void LCD_WR_REG(uint8_t data) { LCD_CS_CLR; LCD_RS_CLR; LCD_SPI_WriteByte(data); LCD_CS_SET; } /***************************************************************************** * @name :void LCD_WR_DATA(uint8_t data) * @date :2018-08-09 * @function :Write an 8-bit data to the LCD screen * @parameters :data:data value to be written * @retvalue :None ******************************************************************************/ void LCD_WR_DATA(uint8_t data) { LCD_CS_CLR; LCD_RS_SET; LCD_SPI_WriteByte(data); LCD_CS_SET; } /***************************************************************************** * @name :void LCD_WriteReg(uint8_t LCD_Reg, uint16_t LCD_RegValue) * @date :2018-08-09 * @function :Write data into registers * @parameters :LCD_Reg:Register address LCD_RegValue:Data to be written * @retvalue :None ******************************************************************************/ void LCD_WriteReg(uint8_t LCD_Reg, uint16_t LCD_RegValue) { LCD_WR_REG(LCD_Reg); LCD_WR_DATA(LCD_RegValue); } /***************************************************************************** * @name :void LCD_WriteRAM_Prepare(void) * @date :2018-08-09 * @function :Write GRAM * @parameters :None * @retvalue :None ******************************************************************************/ void LCD_WriteRAM_Prepare(void) { LCD_WR_REG(lcddev.wramcmd); } /***************************************************************************** * @name :void Lcd_WriteData_16Bit(uint16_t Data) * @date :2018-08-09 * @function :Write an 16-bit command to the LCD screen * @parameters :Data:Data to be written * @retvalue :None ******************************************************************************/ void Lcd_WriteData_16Bit(uint16_t Data) { LCD_CS_CLR; LCD_RS_SET; LCD_SPI_WriteByte(Data>>8); LCD_SPI_WriteByte(Data); LCD_CS_SET; } /***************************************************************************** * @name :void LCD_DrawPoint(uint16_t x,uint16_t y) * @date :2018-08-09 * @function :Write a pixel data at a specified location * @parameters :x:the x coordinate of the pixel y:the y coordinate of the pixel * @retvalue :None ******************************************************************************/ void LCD_DrawPoint(uint16_t x,uint16_t y) { LCD_SetCursor(x,y);//设置光标位置 Lcd_WriteData_16Bit(POINT_COLOR); } /***************************************************************************** * @name :void LCD_Clear(uint16_t Color) * @date :2018-08-09 * @function :Full screen filled LCD screen * @parameters :color:Filled color * @retvalue :None ******************************************************************************/ void LCD_Clear(uint16_t Color) { unsigned int i,m; LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1); LCD_CS_CLR; LCD_RS_SET; for(i=0;i<lcddev.height;i++) { for(m=0;m<lcddev.width;m++) { Lcd_WriteData_16Bit(Color); } } LCD_CS_SET; } /***************************************************************************** * @name :void LCD_RESET(void) * @date :2018-08-09 * @function :Reset LCD screen * @parameters :None * @retvalue :None ******************************************************************************/ void LCD_RESET(void) { LCD_RST_CLR; HAL_Delay(100); LCD_RST_SET; HAL_Delay(50); } /***************************************************************************** * @name :void LCD_RESET(void) * @date :2018-08-09 * @function :Initialization LCD screen * @parameters :None * @retvalue :None ******************************************************************************/ void LCD_Init(void) { LCD_RESET(); //LCD 复位 //*************3.2inch ILI9341初始化**********// LCD_WR_REG(0xCF); LCD_WR_DATA(0x00); LCD_WR_DATA(0xD9); //C1 LCD_WR_DATA(0X30); LCD_WR_REG(0xED); LCD_WR_DATA(0x64); LCD_WR_DATA(0x03); LCD_WR_DATA(0X12); LCD_WR_DATA(0X81); LCD_WR_REG(0xE8); LCD_WR_DATA(0x85); LCD_WR_DATA(0x10); LCD_WR_DATA(0x7A); LCD_WR_REG(0xCB); LCD_WR_DATA(0x39); LCD_WR_DATA(0x2C); LCD_WR_DATA(0x00); LCD_WR_DATA(0x34); LCD_WR_DATA(0x02); LCD_WR_REG(0xF7); LCD_WR_DATA(0x20); LCD_WR_REG(0xEA); LCD_WR_DATA(0x00); LCD_WR_DATA(0x00); LCD_WR_REG(0xC0); //Power control LCD_WR_DATA(0x1B); //VRH[5:0] LCD_WR_REG(0xC1); //P0 LCD_WR_DATA(0x12); //SAP[2:0];BT[3:0] //0x01 LCD_WR_REG(0xC5); //VCM control LCD_WR_DATA(0x26); //3F LCD_WR_DATA(0x26); //3C LCD_WR_REG(0xC7); //VCM control2 LCD_WR_DATA(0XB0); LCD_WR_REG(0x36); // Memory Access Control LCD_WR_DATA(0x08); LCD_WR_REG(0x3A); LCD_WR_DATA(0x55); LCD_WR_REG(0xB1); LCD_WR_DATA(0x00); LCD_WR_DATA(0x1A); LCD_WR_REG(0xB6); // Display Function Control LCD_WR_DATA(0x0A); LCD_WR_DATA(0xA2); LCD_WR_REG(0xF2); // 3Gamma Function Disable LCD_WR_DATA(0x00); LCD_WR_REG(0x26); //Gamma curve selected LCD_WR_DATA(0x01); LCD_WR_REG(0xE0); //Set Gamma LCD_WR_DATA(0x1F); LCD_WR_DATA(0x24); LCD_WR_DATA(0x24); LCD_WR_DATA(0x0D); LCD_WR_DATA(0x12); LCD_WR_DATA(0x09); LCD_WR_DATA(0x52); LCD_WR_DATA(0xB7); LCD_WR_DATA(0x3F); LCD_WR_DATA(0x0C); LCD_WR_DATA(0x15); LCD_WR_DATA(0x06); LCD_WR_DATA(0x0E); LCD_WR_DATA(0x08); LCD_WR_DATA(0x00); LCD_WR_REG(0XE1); //Set Gamma LCD_WR_DATA(0x00); LCD_WR_DATA(0x1B); LCD_WR_DATA(0x1B); LCD_WR_DATA(0x02); LCD_WR_DATA(0x0E); LCD_WR_DATA(0x06); LCD_WR_DATA(0x2E); LCD_WR_DATA(0x48); LCD_WR_DATA(0x3F); LCD_WR_DATA(0x03); LCD_WR_DATA(0x0A); LCD_WR_DATA(0x09); LCD_WR_DATA(0x31); LCD_WR_DATA(0x37); LCD_WR_DATA(0x1F); LCD_WR_REG(0x2B); LCD_WR_DATA(0x00); LCD_WR_DATA(0x00); LCD_WR_DATA(0x01); LCD_WR_DATA(0x3f); LCD_WR_REG(0x2A); LCD_WR_DATA(0x00); LCD_WR_DATA(0x00); LCD_WR_DATA(0x00); LCD_WR_DATA(0xef); LCD_WR_REG(0x11); //Exit Sleep HAL_Delay(120); LCD_WR_REG(0x29); //display on LCD_direction(USE_HORIZONTAL);//设置LCD显示方向 LCD_BL_ON;//点亮背光 LCD_Clear(GREEN);//清全屏白色 } /***************************************************************************** * @name :void LCD_SetWindows(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd) * @date :2018-08-09 * @function :Setting LCD display window * @parameters :xStar:the bebinning x coordinate of the LCD display window yStar:the bebinning y coordinate of the LCD display window xEnd:the endning x coordinate of the LCD display window yEnd:the endning y coordinate of the LCD display window * @retvalue :None ******************************************************************************/ void LCD_SetWindows(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd) { LCD_WR_REG(lcddev.setxcmd); LCD_WR_DATA(xStar>>8); LCD_WR_DATA(0x00FF&xStar); LCD_WR_DATA(xEnd>>8); LCD_WR_DATA(0x00FF&xEnd); LCD_WR_REG(lcddev.setycmd); LCD_WR_DATA(yStar>>8); LCD_WR_DATA(0x00FF&yStar); LCD_WR_DATA(yEnd>>8); LCD_WR_DATA(0x00FF&yEnd); LCD_WriteRAM_Prepare(); //开始写入GRAM } /***************************************************************************** * @name :void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos) * @date :2018-08-09 * @function :Set coordinate value * @parameters :Xpos:the x coordinate of the pixel Ypos:the y coordinate of the pixel * @retvalue :None ******************************************************************************/ void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos) { LCD_SetWindows(Xpos,Ypos,Xpos,Ypos); } /***************************************************************************** * @name :void LCD_direction(uint8_t direction) * @date :2018-08-09 * @function :Setting the display direction of LCD screen * @parameters :direction:0-0 degree 1-90 degree 2-180 degree 3-270 degree * @retvalue :None ******************************************************************************/ void LCD_direction(uint8_t direction) { lcddev.setxcmd=0x2A; lcddev.setycmd=0x2B; lcddev.wramcmd=0x2C; switch(direction){ case 0: lcddev.width=LCD_W; lcddev.height=LCD_H; LCD_WriteReg(0x36,(1<<3)|(0<<6)|(0<<7));//BGR==1,MY==0,MX==0,MV==0 break; case 1: lcddev.width=LCD_H; lcddev.height=LCD_W; LCD_WriteReg(0x36,(1<<3)|(0<<7)|(1<<6)|(1<<5));//BGR==1,MY==1,MX==0,MV==1 break; case 2: lcddev.width=LCD_W; lcddev.height=LCD_H; LCD_WriteReg(0x36,(1<<3)|(1<<6)|(1<<7));//BGR==1,MY==0,MX==0,MV==0 break; case 3: lcddev.width=LCD_H; lcddev.height=LCD_W; LCD_WriteReg(0x36,(1<<3)|(1<<7)|(1<<5));//BGR==1,MY==1,MX==0,MV==1 break; default:break; } } 2、测试代码 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_ICACHE_Init(); MX_SPI2_Init(); MX_USART2_UART_Init(); /* USER CODE BEGIN 2 */ LCD_Init(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ main_test(); // Test_Color(); // Pic_test(); // HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5); } /* USER CODE END 3 */ } 四、下载验证 现象: [localvideo]f77b3f284813645dc313fad9e84ad3ae[/localvideo] 显示文字、颜色、STM32LOGO图片; 可以看出基本上刷颜色不到1s就刷满一屏了。STM32LOGO (240*240*2字节)刷一屏,也花了不到1s时间,相比之前使用STM32L4R5的颜色和图片测试,大夫提高刷新率。 工程:     

  • 2024-08-14
  • 回复了主题帖: 【NUCLEO-H533RE开发板测评】06 AES-GCM/CBC测试

    秦天qintian0303 发表于 2024-8-14 09:29 这几次的测试都很注重安全啊,基本上都要求做加解密的测试 应该是ST看中安全方面的应用

最近访客

< 1/6 >

统计信息

已有229人来访过

  • 芯积分:953
  • 好友:4
  • 主题:62
  • 回复:208

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言