STC12C5A60S2最小系统板/51单片机温度显示和温度控制风扇

news2024/11/22 17:34:25

STC12C5A60S2最小系统板/51单片机温度显示和温度控制风扇,板载有DS18B20和TM1650+4位数码管。

项目简介

单片机课课程设计,要做一个智能温控风扇,达到设定的下限温度值就开启风扇,温度在上限和下限之间就按比例输出PWM占空比控制风扇,超过上限值就风扇全速。
使用STC12C5A60S2单片机,温度传感器用的DS18B20,数码管用TM1650芯片驱动,通过I2C与TM1650通信。
这个开源项目也可以直接当STC12C5A60S2最小系统,所有IO口都引出了。

STC12C5A60S2简介

STC12C5A60S2系列单片机是宏晶科技生产的单时钟/机器周期(1T)的单片机。它是高速/低功耗/超强抗干扰的新一代8051单片机,指令代码完全兼容传统8051,但速度快8-12倍。内部集成MAX810专用复位电路,2路PWM,8路高速10位A/D转换(250K/S),针对电机控制,强干扰场合。

TM1650

TM1650 是一种带键盘扫描接口的LED(发光二极管显示器)驱动控制专用电路。内部集成有MCU输入输出控制数字接口、数据锁存器、LED 驱动、键盘扫描、辉度调节等电路。TM1650 性能稳定、质量可靠、抗干扰能力强,可适用于24 小时长期连续工作的应用场合。

  • 两种显示模式:8段×4位和7段×4位
  • 支持单个按键7x4bit(28个按键)和组合按键(4个)
  • 8级亮度可调
  • 段驱动电流大于25mA,位驱动电流大于150mA
  • 高速2线串行接口(CLK,DAT)
  • 振荡方式:内置RC振荡
  • 内置上电复位电路
  • 内置数据锁存电路
  • 支持3-5.5V电源电压
  • 抗干扰能力强
  • 提供DIP16及SOP16封装

实物图


原理图

PCB

顶层:

底层:

元件购买地址

  • 0805电阻样品本:https://s.click.taobao.com/oWjIgGu
  • 0805电容样品本:https://s.click.taobao.com/r9ea1Hu
  • 共阴数码管:https://u.jd.com/1ir7YWC
  • TM1650芯片:https://s.click.taobao.com/pYveTFu
  • DS18B20芯片:https://s.click.taobao.com/zaNQqFu

元器件购买推荐立创商城,优惠注册链接:https://activity.szlcsc.com/invite/D03E5B9CEAAE70A4.html

代码和资料

完整工程和各芯片数据手册的下载地址:https://url.zeruns.tech/AkHGU 提取码:6gzf

立创开源平台开源链接:https://url.zeruns.tech/46y43

main.c

#include <STC12C5A60S2.H>
#include <intrins.h>
#include "TM1650.h"
#include "DS18B20.h"
#include "Key.h"

sbit LED2 = P2 ^ 3;
sbit LED3 = P2 ^ 4;
sbit LED4 = P2 ^ 5;
sbit FAN = P4 ^ 2;

// 定义TM1650的显示数组
unsigned char code dig1[11] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40}; // 0、1、2、3、4、5、6、7、8、9、-//不带小数点
unsigned char code dig2[11] = {0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd, 0x87, 0xff, 0xef, 0x40}; // 0、1、2、3、4、5、6、7、8、9、-//带小数点
unsigned char code dig3[3] = {0x76, 0x38, 0x40};                                                  // H、L、-

// 定义计数变量
unsigned int count = 0, count1 = 0; // 计数值

// 温度上下限值
uint8_t H_Set = 50;
uint8_t L_Set = 25;

// 定义显示模式的枚举变量类型
typedef enum
{
    H_mode = 0, // 上限温度设置
    L_mode,     // 下限温度设置
    T_mode,     // 温度显示
} Display_MODE;

Display_MODE Display_mode = T_mode;

uint16_t temp;

// 定时器/计数器初始化
void Timer_Init()
{
    EA = 1;       // 使能总中断
    AUXR |= 0x80; // 定时器0时钟1T模式
    TMOD &= 0xF0; // 清零低四位,设置为16位计数器模式
    TMOD |= 0x01; // 设置高四位为定时器模式0
    TL0 = 0xCD;   // 设置定时初始值
    TH0 = 0xD4;   // 设置定时初始值
    TF0 = 0;      // 清除TF0标志
    TR0 = 1;      // 定时器0开始计时
    ET0 = 1;      // 使能定时器0中断

    AUXR &= 0xBF; // 定时器1时钟12T模式
    TMOD &= 0x0F; // 设置定时器模式
    TMOD |= 0x10; // 设置定时器模式
    TL1 = 0x00;   // 设置定时初始值
    TH1 = 0xB8;   // 设置定时初始值
    TF1 = 0;      // 清除TF1标志
    TR1 = 1;      // 定时器1开始计时
    ET1 = 1;      // 使能定时器1中断
}

// 定时器/计数器0中断服务函数
void Timer0_Isr(void) interrupt 1
{
    TL0 = 0xCD; // 设置定时初始值
    TH0 = 0xD4; // 设置定时初始值
    count++;    // 每隔1毫秒,计数值加1
    count1++;
}

void Timer1_Isr(void) interrupt 3
{
    TL1 = 0x00; // 设置定时初始值
    TH1 = 0xB8; // 设置定时初始值
    key_status_check(0, KEY1);
    key_status_check(1, KEY2);
    key_status_check(2, KEY3);
    key_status_check(3, KEY4);
}

void PWMInit()
{
    // 配置PWM
    CCON = 0; // Initial PCA control register
              // PCA timer stop running
              // Clear CF flag
              // Clear all module interrupt flag
    CL = 0;   // Reset PCA base timer
    CH = 0;
    CMOD = 0x00;            // 设置PCA定时器时钟为晶振频率/12,禁用PCA计数器溢出中断
    CCAP0H = CCAP0L = 0x80; // PWM0 port output 50% duty cycle square wave
    CCAPM0 = 0x42;          // 开启比较器功能,开启PWM0
    AUXR1 |= 0x40;          // 切换PWM输出IO到P4

    CR = 1; // PCA timer start run
}
// https://blog.zeruns.tech
void SetPwmDutyCycle(unsigned char dutyCycle)
{
    // dutyCycle的范围可以是0到100,表示0%至100%的占空比。
    unsigned char newValue = ((100 - dutyCycle) * 255) / 100;
    CCAP0H = CCAP0L = newValue; // 更新CCAP0L,从而改变PWM信号占空比
}

// 主函数
void main()
{
    TM_WrCmd(0x21); // 设置TM1650为8段×4位模式,并打开显示,亮度为2级
    Timer_Init();   // 初始化定时器
    Key_Init();     // 初始化按键状态机
    P4M0 = 0x04;    // 设置P4.2为推挽输出
    P4M1 = 0x00;
    PWMInit();          // 初始化PWM
    SetPwmDutyCycle(0); // 设置PWM占空比为0
    temp = GetTemp();
// https://blog.zeruns.tech
    while (1) // 死循环,反复执行以下操作
    {
        if (count >= 100) // 每隔100毫秒执行一次
        {
            count = 0;
            temp = GetTemp();           // 读取温度
            if (Display_mode == T_mode) // 温度显示模式
            {
                TM_WrDat(0x68, dig1[temp / 1000]);     // 写入第1位的显示数据
                TM_WrDat(0x6a, dig2[temp / 100 % 10]); // 写入第2位的显示数据
                TM_WrDat(0x6c, dig1[temp / 10 % 10]);  // 写入第3位的显示数据
                TM_WrDat(0x6e, dig1[temp % 10]);       // 写入第4位的显示数据
            }
            if (Display_mode == H_mode) // 上限温度设置
            {
                TM_WrDat(0x68, dig3[0]);          // 数码管第1位显示 H
                TM_WrDat(0x6a, dig3[2]);          // 数码管第2位显示 -
                TM_WrDat(0x6c, dig1[H_Set / 10]); // 写入第3位的显示数据
                TM_WrDat(0x6e, dig1[H_Set % 10]); // 写入第4位的显示数据
            }
            else if (Display_mode == L_mode) // 下限温度设置
            {
                TM_WrDat(0x68, dig3[1]);          // 数码管第1位显示 L
                TM_WrDat(0x6a, dig3[2]);          // 数码管第2位显示 -
                TM_WrDat(0x6c, dig1[L_Set / 10]); // 写入第3位的显示数据
                TM_WrDat(0x6e, dig1[L_Set % 10]); // 写入第4位的显示数据
            }

            if (temp / 100 >= L_Set && temp / 100 < H_Set) // 当温度在下限和上限之间,根据温度设置风扇PWM占空比
            {
                uint8_t pwm_set = (uint8_t)((temp / 100.0 - (float)L_Set) / ((H_Set - L_Set) / 55.0) + 45.0 + 0.5);
                SetPwmDutyCycle(pwm_set);
            }
            else if (temp / 100 >= H_Set) // 当温度大于上限时风扇全速
            {
                SetPwmDutyCycle(100); // 设置占空比100%
            }
            else if (temp / 100 < L_Set) // 当温度小于下限时风扇关闭
            {
                SetPwmDutyCycle(0);
            }

            LED2 = ~LED2;
        }
        if (count1 >= 500) // 每隔500毫秒执行一次
        {
            count1 = 0;
            LED3 = ~LED3;
        }
        if (key[0] == 1) // SW3模式切换
        {
            if (Display_mode != 2)
            {
                Display_mode++;
            }
            else
            {
                Display_mode = 0;
            }
            key[0] = 0;
        }
        if (key[1] == 1) // SW4上键
        {
            if (Display_mode == H_mode)
            {
                if (H_Set < 99)
                {
                    H_Set++;
                }
            }
            else if (Display_mode == L_mode)
            {
                if (L_Set < 99)
                {
                    L_Set++;
                }
            }
            key[1] = 0;
        }
        if (key[2] == 1) // SW5下键
        {
            if (Display_mode == H_mode)
            {
                if (H_Set > 0)
                {
                    H_Set--;
                }
            }
            else if (Display_mode == L_mode)
            {
                if (L_Set > 0)
                {
                    L_Set--;
                }
            }
            key[2] = 0;
        }
        LED4 = ~LED4;
    }
}

TM1650.c

#include "TM1650.h"
#include <STC12C5A60S2.H>
#include <intrins.h>

// https://blog.zeruns.tech

// 定义TM1650的引脚
sbit SCL_T = P2 ^ 0; // 串行时钟
sbit SDA_T = P2 ^ 1; // 串行数据

// 定义延时函数
void Delay5us_TM() //@11.0592MHz
{
    unsigned char i;

    _nop_();
    _nop_();
    _nop_();
    i = 10;
    while (--i)
        ;
}
void Delay1us_TM() //@11.0592MHz
{
    _nop_();
}

// TM1650起始位
void TM_Start()
{
    SCL_T = 1;
    SDA_T = 1;
    Delay5us_TM();
    SDA_T = 0;
}

// TM1650结束位
void TM_Stop()
{
    SCL_T = 1;
    SDA_T = 0;
    Delay5us_TM();
    SDA_T = 1;
}

// TM1650应答信号
void TM_Ack()
{
    unsigned char timeout = 1;
    SCL_T = 1;
    Delay5us_TM();
    SCL_T = 0;
    while ((SDA_T) && (timeout <= 100))
    {
        timeout++;
    }
    Delay5us_TM();
    SCL_T = 0;
}

// 通过总线写一个字节
void Write_TM_Byte(unsigned char TM_Byte)
{
    unsigned char i;
    SCL_T = 0;
    Delay1us_TM();
    for (i = 0; i < 8; i++)
    {
        if (TM_Byte & 0x80)
            SDA_T = 1;
        else
            SDA_T = 0;
        SCL_T = 0;
        Delay5us_TM();
        SCL_T = 1;
        Delay5us_TM();
        SCL_T = 0;
        TM_Byte <<= 1;
    }
}

// TM1650写数据
void TM_WrDat(unsigned char add, unsigned char dat)
{
    TM_Start();
    Write_TM_Byte(add); // 显存地址
    TM_Ack();
    Write_TM_Byte(dat); // 显示数据
    TM_Ack();
    TM_Stop();
}

// TM1650写命令
void TM_WrCmd(unsigned char Bri)
{
    TM_Start();
    Write_TM_Byte(0x48); // 显示模式
    TM_Ack();
    Write_TM_Byte(Bri); // 亮度控制
    TM_Ack();
    TM_Stop();
}

TM1650.h

#ifndef __TM1650_H_
#define __TM1650_H_

void TM_WrDat(unsigned char add, unsigned char dat);
void TM_WrCmd(unsigned char Bri);

#endif

DS18B20.c

#include "DS18B20.h"
#include <STC12C5A60S2.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

// DS18B20的数据引脚
sbit DS = P2 ^ 2;

// 延时函数,单位为微秒
void delay_us(uchar us)
{
    while (us--)
    {
        _nop_();
    }
}

// https://blog.zeruns.tech

// 初始化DS18B20,返回0表示成功,返回1表示失败
bit DS18B20_Init()
{
    bit i;
    DS = 1; // 释放总线
    _nop_();
    DS = 0; // 拉低总线至少480us,复位DS18B20
    delay_us(480);
    DS = 1;       // 释放总线
    delay_us(20); // 等待15~60us
    i = DS;       // 读取DS18B20的存在信号,0表示存在,1表示不存在
    delay_us(70); // 等待60~240us
    DS = 1;       // 释放总线
    _nop_();
    _nop_();
    return (i);
}

// 向DS18B20写入一个字节
void DSWriteByte(uchar dat)
{
    uchar i;
    for (i = 0; i < 8; i++)
    {
        DS = 0; // 拉低总线产生写时序
        _nop_();
        _nop_();
        DS = dat & 0x01; // 写入最低位
        delay_us(60);    // 维持写时序至少60us
        DS = 1;          // 释放总线
        _nop_();
        _nop_();
        dat >>= 1; // 右移一位,准备写入下一位
    }
}

// 从DS18B20读取一个字节
uchar DSReadByte()
{
    uchar i, dat, j;
    for (i = 0; i < 8; i++)
    {
        DS = 0; // 拉低总线产生读时序
        _nop_();
        _nop_();
        DS = 1; // 释放总线
        _nop_();
        _nop_();
        j = DS;       // 读取最低位
        delay_us(60); // 维持读时序至少60us
        DS = 1;       // 释放总线
        _nop_();
        _nop_();
        dat = (j << 7) | (dat >> 1); // 左移一位,将读取的位存入dat的最高位
    }
    return (dat);
}

// 获取DS18B20的温度数据,返回值为温度乘以100的结果,单位为摄氏度
int GetTemp()
{
    uchar L, H;
    int temp;
    DS18B20_Init();    // 初始化DS18B20
    DSWriteByte(0xcc); // 发送跳过ROM指令,忽略地址匹配过程
    DSWriteByte(0x44); // 发送温度转换指令,开始测量温度并将结果存入暂存器中
    DS18B20_Init();    // 初始化DS18B20
    DSWriteByte(0xcc); // 发送跳过ROM指令,忽略地址匹配过程
    DSWriteByte(0xbe); // 发送读取暂存器指令,准备读取温度数据
    L = DSReadByte();  // 先读取低字节数据
    H = DSReadByte();  // 再读取高字节数据
    temp = H;
    temp <<= 8;
    temp |= L;                        // 合并高低字节数据,得到16位二进制数,每4位对应一个十六进制数,如0000010110100000对应01A0H
    temp = temp * 0.0625 * 100 + 0.5; // 将二进制数转换为十进制数,并乘以分辨率(默认为0.0625摄氏度),再乘以10以便保留一位小数,并四舍五入
    return (temp);                    // 返回温度数据,如25.6摄氏度对应256
}

DS18B20.h

#ifndef __DS18B20_H_
#define __DS18B20_H_

bit DS18B20_Init();
int GetTemp();

#endif

Key.c

#include "Key.h"

// 定义按键状态的枚举变量类型
typedef enum
{
	KS_RELEASE = 0, // 按键松开
	KS_SHAKE,		// 按键抖动
	KS_PRESS,		// 稳定按下
} KEY_STATUS;

// 当前循环结束的(状态机的)状态
#define g_keyStatus 0
// 当前状态(每次循环后与g_keyStatus保持一致)
#define g_nowKeyStatus 1
// 上次状态(用于记录前一状态以区分状态的来源)
#define g_lastKeyStatus 2

uint8_t KEY_Status[4][3]; // 记录各按键状态
uint8_t key[4];			  // 记录各按键是否稳定按下,1表示按键已按下,0表示按键没被按下

// https://blog.zeruns.tech

void Key_Init(void)
{
	uint8_t i;
	for (i = 0; i < 4; i++)
	{
		KEY_Status[i][g_keyStatus] = KS_RELEASE;
		KEY_Status[i][g_nowKeyStatus] = KS_RELEASE;
		KEY_Status[i][g_lastKeyStatus] = KS_RELEASE;
		key[i] = 0;
	} // 按键状态机全部初始化为按键松开状态
	KEY1 = KEY2 = KEY3 = KEY4 = 1;
}

// 按键状态机程序
void key_status_check(uint8_t key_num, uint8_t KEY)
{
	switch (KEY_Status[key_num][g_keyStatus])
	{
	// 按键释放(初始状态)
	case KS_RELEASE:
	{
		// 检测到低电平,先进行消抖
		if (KEY == 0)
		{
			KEY_Status[key_num][g_keyStatus] = KS_SHAKE;
		}
	}
	break;

	// 抖动
	case KS_SHAKE:
	{
		if (KEY == 1)
		{
			KEY_Status[key_num][g_keyStatus] = KS_RELEASE;
		}
		else
		{
			KEY_Status[key_num][g_keyStatus] = KS_PRESS;
		}
	}
	break;

	// 稳定短按
	case KS_PRESS:
	{
		// 检测到高电平,先进行消抖
		if (KEY == 1)
		{
			KEY_Status[key_num][g_keyStatus] = KS_SHAKE;
		}
	}
	break;

	default:
		break;
	}

	if (KEY_Status[key_num][g_keyStatus] != KEY_Status[key_num][g_nowKeyStatus])
	{
		// 当前状态为松开 并且 前一次状态为按下
		if ((KEY_Status[key_num][g_keyStatus] == KS_RELEASE) && (KEY_Status[key_num][g_lastKeyStatus] == KS_PRESS))
		{
			key[key_num] = 1;
		}
		KEY_Status[key_num][g_lastKeyStatus] = KEY_Status[key_num][g_nowKeyStatus];
		KEY_Status[key_num][g_nowKeyStatus] = KEY_Status[key_num][g_keyStatus];
	}
}

Key.h

#ifndef __KEY_H
#define __KEY_H

#include <STC12C5A60S2.H>

/*定义按键IO*/
sbit KEY1 = P3 ^ 2;
sbit KEY2 = P3 ^ 3;
sbit KEY3 = P3 ^ 4;
sbit KEY4 = P3 ^ 5;

typedef unsigned char uint8_t;
typedef unsigned int uint16_t;
typedef unsigned long uint32_t;

extern uint8_t KEY_Status[4][3]; // 记录各按键状态
extern uint8_t key[4];           // 记录各按键是否稳定按下,1表示按键已按下,0表示按键没被按下

void Key_Init(void);
void key_status_check(uint8_t key_num, uint8_t KEY);

#endif

其他开源项目推荐

  • 画了个 MSP430F149的最小系统板 开源出来了:https://blog.zeruns.tech/archives/713.html
  • STM32F030C8T6最小系统板和流水灯(原理图和PCB):https://blog.zeruns.tech/archives/715.html
  • SY8205同步降压可调DCDC电源模块(原理图和PCB):https://blog.zeruns.tech/archives/717.html
  • 2011年全国电赛题-开关电源模块并联供电系统:https://blog.zeruns.tech/archives/718.html
  • 2007年电赛电源题:30到36V可调升压DCDC模块(UC3843):https://oshwhub.com/zeruns/36v-sheng-ya-dcdc-mo-kuai-uc3842

推荐阅读

  • 高性价比和便宜的VPS/云服务器推荐: https://blog.vpszj.cn/archives/41.html
  • 怎样搭建个人博客:https://blog.zeruns.tech/archives/218.html
  • 我的世界服务器搭建教程:https://blog.zeruns.tech/tag/mc/
  • STM32读取SHT3x系列温湿度传感器:https://blog.zeruns.tech/archives/700.html
  • 使用VSCode代替Keil实现STM32和51单片机的开发:https://blog.zeruns.tech/archives/690.html
  • 指点云 日本VPS 性能评测,1核1G 10兆 5G防御 仅需29.4元/月:https://blog.vpszj.cn/archives/1749.html
  • 雨云 宿迁 Gold 6146 高防云服务器性能测评:https://blog.vpszj.cn/archives/1725.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/628591.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于jsp+mysql+Spring+mybatis的Springboot旅游网站管理系统

运行环境: 最好是java jdk 1.8&#xff0c;我在这个平台上运行的。其他版本理论上也可以。 IDE环境&#xff1a; Eclipse,Myeclipse,IDEA或者Spring Tool Suite都可以&#xff0c;如果编译器的版本太低&#xff0c;需要升级下编译器&#xff0c;不要弄太低的版本 tomcat服务器环…

AI回答:绩效考核有哪些方法,基本靠谱

AI回答&#xff1a;绩效考核有哪些方法&#xff0c;基本靠谱 建立有效的绩效考核机制&#xff0c;比较难 但没有考核机制&#xff0c;就无法评价优劣 趣讲大白话&#xff1a;赏罚两字&#xff0c;千古大事 【趣讲信息科技191期】 **************************** 互联网企业现在流…

11 GMM——高斯混合模型

文章目录 11 GMM——高斯混合模型11.1 模型介绍11.2 通过MLE估计参数11.3 EM求解 11 GMM——高斯混合模型 11.1 模型介绍 从几何角度来说&#xff1a; 高斯混合模型表示&#xff1a;加权平均——由多个高斯分布混合叠加而成&#xff0c;如图 公式可以表达为&#xff1a; p…

【Jmeter】提取和引用Token

1.执行获取token接口 在结果树这里&#xff0c;使用$符号提取token值。 $根节点&#xff0c;$.data.token表示提取根节点下的data节点下的token节点的值。 2.使用json提取器&#xff0c;提取token 变量路径就是把在结果树提取的路径写上。 3.使用BeanShell取样器或者BeanShell后…

(数组) 941. 有效的山脉数组 ——【Leetcode每日一题】

❓941. 有效的山脉数组 难度&#xff1a;简单 给定一个整数数组 arr&#xff0c;如果它是有效的山脉数组就返回 true&#xff0c;否则返回 false。 让我们回顾一下&#xff0c;如果 arr 满足下述条件&#xff0c;那么它是一个山脉数组&#xff1a; arr.length > 3在 0 &…

Redis指令-认识NoSQl和Redis常见的通用命令

1. 认识NoSQL 非关系型数据库 NoSQL是指一类非关系型数据库&#xff0c;它们采用的数据模型不同于传统的关系模型&#xff0c;它通常使用键值对、文档、图形等非传统的数据结构进行数据存储&#xff0c;不遵循预定义的模式和模型。NoSQL数据库通常分布式、高可扩展性&#xff0…

4.多线程之JUC并发编程1

1.List集合类不安全(以前单线程永远是安全的,多线程集合就不安全了) 都是ConcurrentModificationException并发修改异常,在有sout输出的情况下出来的,因为多线程边读边写 //并发情况下ArrayList是不安全的 可以用Vector在jdk1.0出来的,List1.2出来的加了同步锁 List listnew Ve…

瑞吉外卖业务开发

数据库 我电脑上的数据库登录指令&#xff1a;mysql -uroot -p123456常用指令&#xff1a;show databases、user 数据库名、show tables。 创建项目 创建完项目后&#xff0c;要及时检查maven仓库的配置&#xff0c;jdk的配置&#xff0c;项目的编码&#xff0c;如下图。 配…

数据同步智能化!利用ETLCloud自动化流程实现钉钉OA系统数据自动同步至数仓

钉钉数据同步需求 钉钉是一款企业级通讯和协同办公应用软件&#xff0c;钉钉为企业提供包括聊天、通讯录、日程安排、考勤打卡、审批、通知公告、文件共享、会议等功能&#xff0c;很多企业都在使用钉钉。 很多情况下我们需要把钉钉的数据拉取到数据库中&#xff0c;然后再通…

案例分享 | 汽车连接器焊锡质量检测

连接器是电脑、电视、汽车等常见产品中不可缺少的部件&#xff0c;主要由接触件、绝缘体与金属壳体组成&#xff0c;用于传输电流或信号。 汽车连接器约占全球连接器市场四分之一的份额&#xff0c;随着未来汽车产业的持续膨胀&#xff0c;市场前景广阔。连接器产品的微型化、…

RPC通用爬虫

文章目录 RPC通用爬虫一、项目案例二、Rpc原理解析三、Rpc代码分享四、自我总结 RPC通用爬虫 一、项目案例 测试网址: aHR0cDovL3d3dy5mYW5nZGkuY29tLmNuL3NlcnZpY2UvYnVsbGV0aW5fbGlzdC5odG1sP3R5cGVhPWI2N2MzYjhhZGJkY2U3NGQ 二、Rpc原理解析 图解关系: ​ 主要包括,爬虫程…

Dockerfile应用的容器化

文章目录 Dockerfile应用的容器化应用的容器化——简介应用的容器化——详解单体应用容器化获取应用代码分析Dockerfile容器化当前应用/构建具体的镜像推送镜像到仓库运行应用程序测试总结 最佳实践利用构建缓存合并镜像 命令总结 Dockerfile应用的容器化 Docker 的核心思想是…

为什么网络安全缺口大,招聘却很少?

2023 年我国网络空间安全人才数量缺口超过了 140 万&#xff0c;就业人数却只有 10 多万&#xff0c;缺口高达了 93%。这里就有人会问了&#xff1a; 1、网络安全行业为什么这么缺人&#xff1f; 2、明明人才那么稀缺&#xff0c;为什么招聘时招安全的人员却没有那么多呢&am…

头部大模型公司进京赶考,向量数据库成为应考神器

日前&#xff0c;由品玩主办的「模型思辨」国内大模型产业生态研讨会在北京举办&#xff0c;Zilliz 与 360 集团、阿里巴巴、昆仑万维等来自大模型产业链的头部公司及投资机构参会&#xff0c;会上 Zilliz 创始人兼首席执行官星爵、360 集团创始人周鸿祎、昆仑万维创始人方汉等…

C++ 类设计的实践与理解

前言 C代码提供了足够的灵活性&#xff0c;因此对于大部分工程师来说都很难把握。本文介绍了写好C代码需要遵循的最佳实践方法&#xff0c;并在最后提供了一个工具可以帮助我们分析C代码的健壮度。 1. 尽可能尝试使用新的C标准 到2023年&#xff0c;C已经走过了40多个年头。新…

如何进行微服务测试?

微服务测试是一种特殊的测试类型&#xff0c;因为它涉及到多个独立的服务。以下是进行微服务测试的一般性步骤&#xff1a; 1. 确定系统架构 了解微服务架构对成功测试至关重要。确定每个微服务的职责、接口、依赖项和通信方式。了解这些信息可以帮助您更好地规划测试用例和测…

day09——线性回归

线性回归 一、什么是线性回归1&#xff0c;定义与公式2&#xff0c;线性回归的特征与目标的关系 二、线性回归的损失和优化原理1&#xff0c;损失函数2&#xff0c;优化算法 三、API四、实操&#xff1a;波士顿房价预测1&#xff0c;数据来源&#xff1a;scikit-learn2&#xf…

Acgis中实现栅格经纬度和行政区关联

写在前面 我是一个Acgis小白&#xff0c;写这篇博客是为了记录完成过程&#xff0c;如果有更高效的办法欢迎分享~ 我用的是Arcgis10.2。 需求描述 目前已有意大利的shp文件&#xff0c;希望将意大利划分成0.1*0.1经纬度的栅格&#xff0c;并且关联每个栅格中心点所属的省份信…

DBeaver复制数据库(数据库表结构以及内容)

一、 首先先建立一个数据库 &#xff08;已有请忽略此步骤&#xff09; &#xff08;名字 字符集等按需要自己填写&#xff09; 二、选择要复制的数据库 2.1右键选择 工具->转储数据库 2.2选择要导出的数据 2.3 选择要导出的路径 2.4 点击开始&#xff0c;等待导出完…

Revit中绘制弯曲的靠背栏杆和生成过梁

一、Revit中怎么绘制弯曲的靠背栏杆 栏杆通常我们见过位于在阳台处&#xff0c;但是在我们的古建筑中很常见到一种靠背栏杆&#xff0c;例如凉亭里面就很常见这种栏杆。那么如何绘制呢? 利用公制栏杆——支柱进行绘制 要运用放样工具进行绘制&#xff0c;设置一个工作平面&…