STM32基础入门学习笔记:面包板 配件包扩展模块与编程

文章目录:

一:阵列键盘

1.阵列键盘测试程序

KEYPAD4x4.h

KEYPAD4x4.c

main.c

2.键盘中断测试程序

NVIC.h

NVIC.c

main.c

二:舵机控制

1.延时函数驱动舵机程序 

SG90.h

SG90.c

main.c

2.PWM(脉冲宽度调制 脉宽调制/占空比)驱动舵机程序

pwm.h

pwm.c

main.c

三:DHT11芯片(DHT11温湿度显示程序)

dht11.h

dht11.c

main.c

四:MPU6050(六轴加速度和陀螺仪传感器芯片)

MPU6050.h

MPU6050.c 

main.c


一:阵列键盘

 

 对跳线进行设置

第一步:把ADC输入的两个跳线断开第二步:将模拟摇杆的三个跳线断开第三步:将触摸按键的四个跳线断开第四步:将旋转编码器的三个跳线断开

1.阵列键盘测试程序

按下时:红线蓝线短接 

 

 阵列键盘

新建文件夹

Hardware文件夹——>KEYPAD4x4文件夹——>KEYPAD4x4.c  KEYPAD4x4.h

KEYPAD4x4.h

#ifndef __KEYPAD4x4_H
#define __KEYPAD4x4_H	 
#include "sys.h"
#include "delay.h"#define KEYPAD4x4PORT	GPIOA	//定义IO接口组
#define KEY1	GPIO_Pin_0	//定义IO接口
#define KEY2	GPIO_Pin_1	//定义IO接口
#define KEY3	GPIO_Pin_2	//定义IO接口
#define KEY4	GPIO_Pin_3	//定义IO接口
#define KEYa	GPIO_Pin_4	//定义IO接口
#define KEYb	GPIO_Pin_5	//定义IO接口
#define KEYc	GPIO_Pin_6	//定义IO接口
#define KEYd	GPIO_Pin_7	//定义IO接口void KEYPAD4x4_Init(void);//初始化
void KEYPAD4x4_Init2(void);//初始化2(用于IO工作方式反转)
u8 KEYPAD4x4_Read (void);//读阵列键盘#endif

KEYPAD4x4.c

#include "KEYPAD4x4.h"void KEYPAD4x4_Init(void){ //微动开关的接口初始化GPIO_InitTypeDef  GPIO_InitStructure; //定义GPIO的初始化枚举结构	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);       GPIO_InitStructure.GPIO_Pin = KEYa | KEYb | KEYc | KEYd; //选择端口号(0~15或all)                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //选择IO接口工作方式 //上拉电阻       GPIO_Init(KEYPAD4x4PORT,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = KEY1 | KEY2 | KEY3 | KEY4; //选择端口号(0~15或all)                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //选择IO接口工作方式 //上拉电阻  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz)     GPIO_Init(KEYPAD4x4PORT,&GPIO_InitStructure);}
void KEYPAD4x4_Init2(void){ //微动开关的接口初始化2(用于IO工作方式反转)GPIO_InitTypeDef  GPIO_InitStructure; //定义GPIO的初始化枚举结构	GPIO_InitStructure.GPIO_Pin = KEY1 | KEY2 | KEY3 | KEY4; //选择端口号(0~15或all)                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //选择IO接口工作方式 //上拉电阻       GPIO_Init(KEYPAD4x4PORT,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = KEYa | KEYb | KEYc | KEYd; //选择端口号(0~15或all)                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //选择IO接口工作方式 //上拉电阻  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz)     GPIO_Init(KEYPAD4x4PORT,&GPIO_InitStructure);}
u8 KEYPAD4x4_Read (void){//键盘处理函数u8 a=0,b=0;//定义变量KEYPAD4x4_Init();//初始化IOGPIO_ResetBits(KEYPAD4x4PORT,KEY1|KEY2|KEY3|KEY4);GPIO_SetBits(KEYPAD4x4PORT,KEYa|KEYb|KEYc|KEYd);if(!GPIO_ReadInputDataBit(KEYPAD4x4PORT,KEYa) ||  	//查寻键盘口的值是否变化!GPIO_ReadInputDataBit(KEYPAD4x4PORT,KEYb) || !GPIO_ReadInputDataBit(KEYPAD4x4PORT,KEYc) || !GPIO_ReadInputDataBit(KEYPAD4x4PORT,KEYd)){delay_ms (20);//延时20毫秒if(!GPIO_ReadInputDataBit(KEYPAD4x4PORT,KEYa) ||  	//查寻键盘口的值是否变化!GPIO_ReadInputDataBit(KEYPAD4x4PORT,KEYb) || !GPIO_ReadInputDataBit(KEYPAD4x4PORT,KEYc) || !GPIO_ReadInputDataBit(KEYPAD4x4PORT,KEYd)){a = GPIO_ReadInputData(KEYPAD4x4PORT)&0xff;//键值放入寄存器a}KEYPAD4x4_Init2();//IO工作方式反转GPIO_SetBits(KEYPAD4x4PORT,KEY1|KEY2|KEY3|KEY4);GPIO_ResetBits(KEYPAD4x4PORT,KEYa|KEYb|KEYc|KEYd);b = GPIO_ReadInputData(KEYPAD4x4PORT)&0xff;//将第二次取得值放入寄存器ba = a|b;//将两个数据相或switch(a){//对比数据值case 0xee: b = 16; break;//对比得到的键值给b一个应用数据case 0xed: b = 15; break;case 0xeb: b = 14; break;case 0xe7: b = 13; break;case 0xde: b = 12; break;case 0xdd: b = 11; break;case 0xdb: b = 10; break;case 0xd7: b = 9; break;case 0xbe: b = 8; break;case 0xbd: b = 7; break;case 0xbb: b = 6; break;case 0xb7: b = 5; break;case 0x7e: b = 4; break;case 0x7d: b = 3; break;case 0x7b: b = 2; break;case 0x77: b = 1; break;default: b = 0; break;//键值错误处理}while(!GPIO_ReadInputDataBit(KEYPAD4x4PORT,KEY1) ||  	//等待按键放开!GPIO_ReadInputDataBit(KEYPAD4x4PORT,KEY2) || !GPIO_ReadInputDataBit(KEYPAD4x4PORT,KEY3) || !GPIO_ReadInputDataBit(KEYPAD4x4PORT,KEY4));delay_ms (20);//延时20毫秒}
return (b);//将b作为返回值
}

main.c

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"#include "KEYPAD4x4.h"int main (void){//主程序u8 s;delay_ms(500); //上电时等待其他器件就绪RCC_Configuration(); //系统时钟初始化 RELAY_Init();//继电器初始化I2C_Configuration();//I2C初始化OLED0561_Init(); //OLED初始化OLED_DISPLAY_8x16_BUFFER(0,"   YoungTalk    "); //显示字符串OLED_DISPLAY_8x16_BUFFER(3," KEYPAD4x4 TEST "); //显示字符串KEYPAD4x4_Init();//阵列键盘初始化while(1){s=KEYPAD4x4_Read();//读出按键值//有按键被按下if(s!=0){ //如按键值不是0,也就是说有按键操作,则判断为真//-------------------------"----------------"OLED_DISPLAY_8x16_BUFFER(6," KEY NO.        "); //显示字符串OLED_DISPLAY_8x16(6,8*8,s/10+0x30);    //显示十位    偏移量OLED_DISPLAY_8x16(6,9*8,s%10+0x30);    //显示个位}}
}

2.键盘中断测试程序

嵌套:即是在进入一个中断处理程序之后,还能在中断之内再次产生中断NVIC嵌套向量中断控制器cortex-m3支持256个中断,其中包含了16个内核中断,240个外部中断stm32只有84个中断,包括16个内核中断和68个可屏蔽中断stm32f103上只有60个可屏蔽中断优先级的设置(设置值越小,优先级越高)NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;    //抢占优先级        NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;           //子优先级抢占优先级    又称:主优先级在嵌套时,抢占优先级较高的可以在较低的中断内嵌套中断同一抢占优先级不能嵌套,必须前一个中断处理完成才能进入下一个不同抢占优先级下,响应优先级没有意义响应优先级    又称:子优先级/亚优先级/次优先级/副优先级同一抢占优先级的中断同时产生时,响应优先级较高的先处理同一抢占优先级不能嵌套

新建文件夹

Basic文件夹——>nvic文件夹——>NVIC.c  NVIC.h

NVIC.h

#ifndef __NVIC_H
#define __NVIC_H	 
#include "sys.h"extern u8 INT_MARK;                //中断标志位void KEYPAD4x4_INT_INIT (void);    //中断初始化函数#endif

NVIC.c

#include "NVIC.h"u8 INT_MARK;//中断标志位void KEYPAD4x4_INT_INIT (void){	 //按键中断初始化NVIC_InitTypeDef  NVIC_InitStruct;	//定义结构体变量EXTI_InitTypeDef  EXTI_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //启动GPIO时钟 (需要与复用时钟一同启动)     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);//配置端口中断需要启用复用时钟//第1个中断	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);  //定义 GPIO  中断EXTI_InitStruct.EXTI_Line=EXTI_Line4;  //定义中断线EXTI_InitStruct.EXTI_LineCmd=ENABLE;              //中断使能EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;     //中断模式为 中断EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;   //下降沿触发EXTI_Init(& EXTI_InitStruct);NVIC_InitStruct.NVIC_IRQChannel=EXTI4_IRQn;   //中断线     NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;  //使能中断NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;  //抢占优先级 2NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;     //子优先级  2NVIC_Init(& NVIC_InitStruct);//第2个中断	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5);  //定义  GPIO 中断EXTI_InitStruct.EXTI_Line=EXTI_Line5;  //定义中断线EXTI_InitStruct.EXTI_LineCmd=ENABLE;              //中断使能EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;     //中断模式为 中断EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;   //下降沿触发EXTI_Init(& EXTI_InitStruct);NVIC_InitStruct.NVIC_IRQChannel=EXTI9_5_IRQn;   //中断线NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;  //使能中断NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;  //抢占优先级 2NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;     //子优先级  2NVIC_Init(& NVIC_InitStruct);//第3个中断	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6);  //定义  GPIO 中断EXTI_InitStruct.EXTI_Line=EXTI_Line6;  //定义中断线EXTI_InitStruct.EXTI_LineCmd=ENABLE;              //中断使能EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;     //中断模式为 中断EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;   //下降沿触发EXTI_Init(& EXTI_InitStruct);NVIC_InitStruct.NVIC_IRQChannel=EXTI9_5_IRQn;   //中断线NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;  //使能中断NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;  //抢占优先级 2NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;     //子优先级  2NVIC_Init(& NVIC_InitStruct);//第4个中断	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource7);  //定义  GPIO 中断EXTI_InitStruct.EXTI_Line=EXTI_Line7;  //定义中断线EXTI_InitStruct.EXTI_LineCmd=ENABLE;              //中断使能EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;     //中断模式为 中断EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;   //下降沿触发EXTI_Init(& EXTI_InitStruct);NVIC_InitStruct.NVIC_IRQChannel=EXTI9_5_IRQn;   //中断线NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;  //使能中断NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;  //抢占优先级 2NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;     //子优先级  2NVIC_Init(& NVIC_InitStruct);}void  EXTI4_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line4)!=RESET){//判断某个线上的中断是否发生 INT_MARK=1;//标志位置1,表示有按键中断EXTI_ClearITPendingBit(EXTI_Line4);   //清除 LINE 上的中断标志位}     
}
void  EXTI9_5_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line5)!=RESET){//判断某个线上的中断是否发生 INT_MARK=2;//标志位置1,表示有按键中断EXTI_ClearITPendingBit(EXTI_Line5);   //清除 LINE 上的中断标志位}     if(EXTI_GetITStatus(EXTI_Line6)!=RESET){//判断某个线上的中断是否发生 INT_MARK=3;//标志位置1,表示有按键中断EXTI_ClearITPendingBit(EXTI_Line6);   //清除 LINE 上的中断标志位}     if(EXTI_GetITStatus(EXTI_Line7)!=RESET){//判断某个线上的中断是否发生 INT_MARK=4;//标志位置1,表示有按键中断EXTI_ClearITPendingBit(EXTI_Line7);   //清除 LINE 上的中断标志位}     
}

main.c

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"#include "KEYPAD4x4.h"
#include "NVIC.h"int main (void){//主程序u8 s;delay_ms(500); //上电时等待其他器件就绪RCC_Configuration(); //系统时钟初始化 RELAY_Init();//继电器初始化I2C_Configuration();//I2C初始化OLED0561_Init(); //OLED初始化OLED_DISPLAY_8x16_BUFFER(0,"   YoungTalk    "); //显示字符串OLED_DISPLAY_8x16_BUFFER(3," KEYPAD4x4 TEST "); //显示字符串INT_MARK=0;//标志位清0NVIC_Configuration();//设置中断优先级KEYPAD4x4_Init();//阵列键盘初始化KEYPAD4x4_INT_INIT();//阵列键盘的中断初始化while(1){//其他程序内容if(INT_MARK){ //中断标志位为1表示有按键中断INT_MARK=0;//标志位清0s=KEYPAD4x4_Read();//读出按键值if(s!=0){ //如按键值不是0,也就是说有按键操作,则判断为真//-------------------------"----------------"OLED_DISPLAY_8x16_BUFFER(6," KEY NO.        "); //显示字符串OLED_DISPLAY_8x16(6,8*8,s/10+0x30);//OLED_DISPLAY_8x16(6,9*8,s%10+0x30);//}}}
}

二:舵机控制

第一步:将舵机连接到开发板上(舵机接口)第二步:将触摸按键的四个跳线帽短接

注意事项1.舵机上如果有负载需要更大的驱动电流2.必须连续不断地向PWM线发出角度波形,直到达到对应角度3.一般情况下,180度舵机的最大角度可达190度,甚至200度4.要按指定型号舵机的波形与角度对应关系做调试,不盲信理论值

新建文件夹 

Hardware文件夹——>SG90文件夹——>SG90.c  SG90.h

1.延时函数驱动舵机程序 

延时函数利用滴答计时器,虽然可以事项该功能,但实际开发中,这种效率很低 

SG90.h

#ifndef __SG90_H
#define __SG90_H	 
#include "sys.h"
#include "delay.h"#define SE_PORT	GPIOA	//定义IO接口
#define SE_OUT	GPIO_Pin_15	//定义IO接口void SG90_Init(void);//SG90舵机初始化
void SG90_angle(u8 a);//舵机角度设置#endif

SG90.c

#include "SG90.h"void SG90_Init(void){ //舵机接口初始化GPIO_InitTypeDef  GPIO_InitStructure; 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);       GPIO_InitStructure.GPIO_Pin = SE_OUT; //选择端口号(0~15或all)                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //选择IO接口工作方式       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz)    GPIO_Init(SE_PORT, &GPIO_InitStructure);GPIO_WriteBit(SE_PORT,SE_OUT,(BitAction)(0)); //接口输出高电平1
}void SG90_angle(u8 a){ //舵机角度控制设置(参数值0~180)对应角度0~180度u8 b=100;//角度校正偏移量GPIO_WriteBit(SE_PORT,SE_OUT,(BitAction)(1)); //接口输出高电平1delay_us(500+a*10+b); //延时GPIO_WriteBit(SE_PORT,SE_OUT,(BitAction)(0)); //接口输出高电平1delay_us(19500-a*10-b); //延时
} 

main.c

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"
#include "SG90.h"
#include "touch_key.h"int main (void){//主程序delay_ms(500); //上电时等待其他器件就绪RCC_Configuration(); //系统时钟初始化 RELAY_Init();//继电器初始化I2C_Configuration();//I2C初始化OLED0561_Init(); //OLED初始化OLED_DISPLAY_8x16_BUFFER(0,"   YoungTalk    "); //显示字符串OLED_DISPLAY_8x16_BUFFER(3,"   SG90 TEST    "); //显示字符串TOUCH_KEY_Init();//按键初始化SG90_Init();//SG90舵机初始化SG90_angle(0);//舵机初步为0(最小值)while(1){if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_A)){ //读触摸按键的电平OLED_DISPLAY_8x16_BUFFER(6,"  Angle 0       "); //显示字符串SG90_angle(0);//舵机初步为0(最小值)}if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_B)){ //读触摸按键的电平OLED_DISPLAY_8x16_BUFFER(6,"  Angle 45      "); //显示字符串SG90_angle(45);//舵机初步为0(最小值)}if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_C)){ //读触摸按键的电平OLED_DISPLAY_8x16_BUFFER(6,"  Angle 90     "); //显示字符串SG90_angle(90);//舵机初步为0(最小值)}if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_D)){ //读触摸按键的电平OLED_DISPLAY_8x16_BUFFER(6,"  Angle 180     "); //显示字符串SG90_angle(180);//舵机初步为0(最小值)}}
}

2.PWM(脉冲宽度调制 脉宽调制/占空比)驱动舵机程序

使用定时器产生PWM(定时器是独立工作的) 不管用户是否按键,PWM都会处在工作状态,一直输出脉冲来控制舵机(舵机会有抖动)

PWM:是利用微处理器的数字输出 来对模拟电路进行控制的一种非常有效的技术应用:在从测量、通信到功率控制与变换的许多领域中必须有一个完整周期(高低电平    高电平决定亮度)
改变高低电平的长度比例,从而达到调节亮度的效果PWM的产生:可由STM32中的定时器产生,包括1个高级定时器TIM1和3个普通定时器TIM2、TIM3、TIM4

          

为了连接定时器的相关输出:在核心版上通过一条导线连接P415和PB0舵机连接:接P415端口定时器的输出:PB0端口

按A键亮度最暗....按D键亮度最亮(使LED显示占空比使亮度发生变化) 

新建文件夹

Basic文件夹——>pwm文件夹——>pwm.c  pwm.h

pwm.h

#ifndef  __PWM_H
#define  __PWM_H
#include "sys.h"void TIM3_PWM_Init(u16 arr,u16 psc);#endif

pwm.c

#include "pwm.h"void TIM3_PWM_Init(u16 arr,u16 psc){  //TIM3 PWM初始化 arr重装载值 psc预分频系数GPIO_InitTypeDef     GPIO_InitStrue;TIM_OCInitTypeDef     TIM_OCInitStrue;TIM_TimeBaseInitTypeDef     TIM_TimeBaseInitStrue;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3和相关GPIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB时钟(LED在PB0引脚)RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//使能AFIO时钟(定时器3通道3需要重映射到BP5引脚)GPIO_InitStrue.GPIO_Pin=GPIO_Pin_0;     // TIM_CH3GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;    // 复用推挽GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;    //设置最大输出速度GPIO_Init(GPIOB,&GPIO_InitStrue);                //GPIO端口初始化设置//    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE); //映射,重映射只用于64、100、144脚单片机//当没有重映射时,TIM3的四个通道CH1,CH2,CH3,CH4分别对应PA6,PA7,PB0,PB1//当部分重映射时,TIM3的四个通道CH1,CH2,CH3,CH4分别对应PB4,PB5,PB0,PB1 (GPIO_PartialRemap_TIM3)//当完全重映射时,TIM3的四个通道CH1,CH2,CH3,CH4分别对应PC6,PC7,PC8,PC9 (GPIO_FullRemap_TIM3) TIM_TimeBaseInitStrue.TIM_Period=arr;    //设置自动重装载值TIM_TimeBaseInitStrue.TIM_Prescaler=psc;        //预分频系数TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up;    //计数器向上溢出TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV1;        //时钟的分频因子,起到了一点点的延时作用,一般设为TIM_CKD_DIV1TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStrue);        //TIM3初始化设置(设置PWM的周期)TIM_OCInitStrue.TIM_OCMode=TIM_OCMode_PWM1;        // PWM模式1:CNT < CCR时输出有效电平TIM_OCInitStrue.TIM_OCPolarity=TIM_OCPolarity_High;// 设置极性-有效电平为:高电平TIM_OCInitStrue.TIM_OutputState=TIM_OutputState_Enable;// 输出使能TIM_OC3Init(TIM3,&TIM_OCInitStrue);        //TIM3的通道3 PWM 模式设置TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable);        //使能预装载寄存器TIM_Cmd(TIM3,ENABLE);        //使能TIM3}

main.c

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"
#include "SG90.h"
#include "touch_key.h"#include "pwm.h"int main (void){//主程序delay_ms(500); //上电时等待其他器件就绪RCC_Configuration(); //系统时钟初始化 RELAY_Init();//继电器初始化I2C_Configuration();//I2C初始化OLED0561_Init(); //OLED初始化OLED_DISPLAY_8x16_BUFFER(0,"   YoungTalk    "); //显示字符串OLED_DISPLAY_8x16_BUFFER(3,"   SG90 TEST2   "); //显示字符串TOUCH_KEY_Init();//按键初始化TIM3_PWM_Init(59999,23); //设置频率为50Hz,公式为:溢出时间Tout(单位秒)=(arr+1)(psc+1)/Tclk	 20MS = (59999+1)*(23+1)/72000000//Tclk为通用定时器的时钟,如果APB1没有分频,则就为系统时钟,72MHZ//PWM时钟频率=72000000/(59999+1)*(23+1) = 50HZ (20ms),设置自动装载值60000,预分频系数24while(1){if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_A)){ //读触摸按键的电平OLED_DISPLAY_8x16_BUFFER(6,"  Angle 0       "); //显示字符串TIM_SetCompare3(TIM3,1500);        //改变比较值TIM3->CCR2达到调节占空比的效果(1500为0度)}if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_B)){ //读触摸按键的电平OLED_DISPLAY_8x16_BUFFER(6,"  Angle 45      "); //显示字符串TIM_SetCompare3(TIM3,3000);        //改变比较值TIM3->CCR2达到调节占空比的效果}if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_C)){ //读触摸按键的电平OLED_DISPLAY_8x16_BUFFER(6,"  Angle 90     "); //显示字符串TIM_SetCompare3(TIM3,4500);        //改变比较值TIM3->CCR2达到调节占空比的效果}if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_D)){ //读触摸按键的电平OLED_DISPLAY_8x16_BUFFER(6,"  Angle 180     "); //显示字符串TIM_SetCompare3(TIM3,7500);        //改变比较值TIM3->CCR2达到调节占空比的效果}}
}

三:DHT11芯片(DHT11温湿度显示程序)

温湿度传感器         

 

引脚说明

串行接口

 通信过程

每一个波形的事件长度

 

数字0 1信号表示方法

 

 新建文件夹

Hardware文件夹——>DHT11文件夹——>dht11.c  dht11.h

通过程序对波形图的高低电平进行采样判断:有些部分需要输出,有些部分需要输入,通过while循环不断判断高低电平的开始位置,再通过延时函数判断数据位是"1"还是"0"

最终将5个字节数据读取进来进行数据校验,校验好后再放入到对应的变量当中,在主函数当中将读到的温度湿度数据以十进制数的方式进行显示,最终就达到了程序效果         

dht11.h

#ifndef __DHT11_H
#define __DHT11_H	 
#include "sys.h"
#include "delay.h"#define DHT11PORT	GPIOA	//定义IO接口
#define DHT11_IO	GPIO_Pin_15	//定义IO接口void DHT11_IO_OUT (void);
void DHT11_IO_IN (void);
void DHT11_RST (void);
u8 Dht11_Check(void); 	   
u8 Dht11_ReadBit(void); 
u8 Dht11_ReadByte(void); 
u8 DHT11_Init (void);
u8 DHT11_ReadData(u8 *h);#endif

dht11.c

#include "dht11.h"//切换端口的工作状态(因为有输出也有输入)
void DHT11_IO_OUT (void){ //端口变为输出GPIO_InitTypeDef  GPIO_InitStructure; 	GPIO_InitStructure.GPIO_Pin = DHT11_IO; //选择端口号(0~15或all)                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //选择IO接口工作方式       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz)    GPIO_Init(DHT11PORT, &GPIO_InitStructure);
}void DHT11_IO_IN (void){ //端口变为输入GPIO_InitTypeDef  GPIO_InitStructure; 	GPIO_InitStructure.GPIO_Pin = DHT11_IO; //选择端口号(0~15或all)                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //选择IO接口工作方式       GPIO_Init(DHT11PORT, &GPIO_InitStructure);
}void DHT11_RST (void){ //DHT11端口复位,发出起始信号(IO发送)DHT11_IO_OUT();GPIO_ResetBits(DHT11PORT,DHT11_IO); //	delay_ms(20); //拉低至少18ms						GPIO_SetBits(DHT11PORT,DHT11_IO); //							delay_us(30); //主机拉高20~40us
}u8 Dht11_Check(void){ //等待DHT11回应,返回1:未检测到DHT11,返回0:成功(IO接收)	   u8 retry=0;DHT11_IO_IN();//IO到输入状态	 while (GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO)&&retry<100){//DHT11会拉低40~80usretry++;delay_us(1);}	 if(retry>=100)return 1; else retry=0;while (!GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO)&&retry<100){//DHT11拉低后会再次拉高40~80usretry++;delay_us(1);}if(retry>=100)return 1;	    return 0;
}u8 Dht11_ReadBit(void){ //从DHT11读取一个位 返回值:1/0u8 retry=0;while(GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO)&&retry<100){//等待变为低电平retry++;delay_us(1);}retry=0;while(!GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO)&&retry<100){//等待变高电平retry++;delay_us(1);}delay_us(40);//等待40us	//用于判断高低电平,即数据1或0if(GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO))return 1; else return 0;		   
}u8 Dht11_ReadByte(void){  //从DHT11读取一个字节  返回值:读到的数据u8 i,dat;dat=0;for (i=0;i<8;i++){ dat<<=1; dat|=Dht11_ReadBit();}						    return dat;
}u8 DHT11_Init (void){	//DHT11初始化RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE, ENABLE); //APB2外设时钟使能      DHT11_RST();//DHT11端口复位,发出起始信号return Dht11_Check(); //等待DHT11回应
}u8 DHT11_ReadData(u8 *h){ //读取一次数据//湿度值(十进制,范围:20%~90%) ,温度值(十进制,范围:0~50°),返回值:0,正常;1,失败 u8 buf[5];u8 i;DHT11_RST();//DHT11端口复位,发出起始信号if(Dht11_Check()==0){ //等待DHT11回应for(i=0;i<5;i++){//读取5位数据buf[i]=Dht11_ReadByte(); //读出数据}if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){	//数据校验*h=buf[0]; //将湿度值放入指针1h++;*h=buf[2]; //将温度值放入指针2}}else return 1;return 0;	    
}

main.c

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"#include "dht11.h"int main (void){//主程序u8 b[2];delay_ms(1000); //上电时等待其他器件就绪RCC_Configuration(); //系统时钟初始化 RELAY_Init();//继电器初始化I2C_Configuration();//I2C初始化OLED0561_Init(); //OLED初始化OLED_DISPLAY_8x16_BUFFER(0,"   YoungTalk    "); //显示字符串OLED_DISPLAY_8x16_BUFFER(2,"   DHT11 TEST   "); //显示字符串if(DHT11_Init()==0){ //DHT11初始化	返回0成功,1失败OLED_DISPLAY_8x16_BUFFER(4,"Humidity:   %   "); //显示字符串OLED_DISPLAY_8x16_BUFFER(6,"Temperature:   C"); //显示字符串}else{OLED_DISPLAY_8x16_BUFFER(4,"DHT11INIT ERROR!"); //显示字符串}delay_ms(1000);//DHT11初始化后必要的延时(不得小于1秒)while(1){if(DHT11_ReadData(b)==0){//读出温湿度值  指针1是湿度 20~90%,指针2是温度 0~50C,数据为十进制OLED_DISPLAY_8x16(4,9*8,b[0]/10 +0x30);//显示湿度值OLED_DISPLAY_8x16(4,10*8,b[0]%10 +0x30);//OLED_DISPLAY_8x16(6,12*8,b[1]/10 +0x30);//显示温度值OLED_DISPLAY_8x16(6,13*8,b[1]%10 +0x30);//}else{OLED_DISPLAY_8x16_BUFFER(6,"DHT11READ ERROR!"); //显示字符串}delay_ms(1000); //延时,刷新数据的频率(不得小于1秒)}
}

四:MPU6050(六轴加速度和陀螺仪传感器芯片

可以实现对自身位移和旋转角度的感知 

加速度传感器:检测位移

陀螺仪传感器:检测方向和旋转的运动

MPU6050原始数据显示程序

 

 

新建文件夹

Hardware文件夹——>MPU6050文件夹——>MPU6050.c  MPU6050.h

MPU6050.h

#ifndef __MPU6050_H
#define __MPU6050_H	 
#include "sys.h"
#include "i2c.h"    //i2c总线通信
#include "delay.h"#define MPU6050_ADD	0xD0	//器件地址(AD0悬空或低电平时地址是0xD0,为高电平时为0xD2,7位地址:1101 000x)#define MPU6050_RA_XG_OFFS_TC       0x00 
#define MPU6050_RA_YG_OFFS_TC       0x01 
#define MPU6050_RA_ZG_OFFS_TC       0x02 
#define MPU6050_RA_X_FINE_GAIN      0x03 
#define MPU6050_RA_Y_FINE_GAIN      0x04 
#define MPU6050_RA_Z_FINE_GAIN      0x05 
#define MPU6050_RA_XA_OFFS_H        0x06 
#define MPU6050_RA_XA_OFFS_L_TC     0x07
#define MPU6050_RA_YA_OFFS_H        0x08 
#define MPU6050_RA_YA_OFFS_L_TC     0x09
#define MPU6050_RA_ZA_OFFS_H        0x0A 
#define MPU6050_RA_ZA_OFFS_L_TC     0x0B
#define MPU6050_RA_XG_OFFS_USRH     0x13 
#define MPU6050_RA_XG_OFFS_USRL     0x14
#define MPU6050_RA_YG_OFFS_USRH     0x15 
#define MPU6050_RA_YG_OFFS_USRL     0x16
#define MPU6050_RA_ZG_OFFS_USRH     0x17 
#define MPU6050_RA_ZG_OFFS_USRL     0x18
#define MPU6050_RA_SMPLRT_DIV       0x19 
#define MPU6050_RA_CONFIG           0x1A 
#define MPU6050_RA_GYRO_CONFIG      0x1B 
#define MPU6050_RA_ACCEL_CONFIG     0x1C 
#define MPU6050_RA_FF_THR           0x1D 
#define MPU6050_RA_FF_DUR           0x1E
#define MPU6050_RA_MOT_THR          0x1F
#define MPU6050_RA_MOT_DUR          0x20
#define MPU6050_RA_ZRMOT_THR        0x21
#define MPU6050_RA_ZRMOT_DUR        0x22
#define MPU6050_RA_FIFO_EN          0x23
#define MPU6050_RA_I2C_MST_CTRL     0x24
#define MPU6050_RA_I2C_SLV0_ADDR    0x25
#define MPU6050_RA_I2C_SLV0_REG     0x26
#define MPU6050_RA_I2C_SLV0_CTRL    0x27
#define MPU6050_RA_I2C_SLV1_ADDR    0x28
#define MPU6050_RA_I2C_SLV1_REG     0x29
#define MPU6050_RA_I2C_SLV1_CTRL    0x2A
#define MPU6050_RA_I2C_SLV2_ADDR    0x2B
#define MPU6050_RA_I2C_SLV2_REG     0x2C
#define MPU6050_RA_I2C_SLV2_CTRL    0x2D
#define MPU6050_RA_I2C_SLV3_ADDR    0x2E
#define MPU6050_RA_I2C_SLV3_REG     0x2F
#define MPU6050_RA_I2C_SLV3_CTRL    0x30
#define MPU6050_RA_I2C_SLV4_ADDR    0x31
#define MPU6050_RA_I2C_SLV4_REG     0x32
#define MPU6050_RA_I2C_SLV4_DO      0x33
#define MPU6050_RA_I2C_SLV4_CTRL    0x34
#define MPU6050_RA_I2C_SLV4_DI      0x35
#define MPU6050_RA_I2C_MST_STATUS   0x36
#define MPU6050_RA_INT_PIN_CFG      0x37
#define MPU6050_RA_INT_ENABLE       0x38
#define MPU6050_RA_DMP_INT_STATUS   0x39
#define MPU6050_RA_INT_STATUS       0x3A
#define MPU6050_RA_ACCEL_XOUT_H     0x3B
#define MPU6050_RA_ACCEL_XOUT_L     0x3C
#define MPU6050_RA_ACCEL_YOUT_H     0x3D
#define MPU6050_RA_ACCEL_YOUT_L     0x3E
#define MPU6050_RA_ACCEL_ZOUT_H     0x3F
#define MPU6050_RA_ACCEL_ZOUT_L     0x40
#define MPU6050_RA_TEMP_OUT_H       0x41
#define MPU6050_RA_TEMP_OUT_L       0x42
#define MPU6050_RA_GYRO_XOUT_H      0x43
#define MPU6050_RA_GYRO_XOUT_L      0x44
#define MPU6050_RA_GYRO_YOUT_H      0x45
#define MPU6050_RA_GYRO_YOUT_L      0x46
#define MPU6050_RA_GYRO_ZOUT_H      0x47
#define MPU6050_RA_GYRO_ZOUT_L      0x48
#define MPU6050_RA_EXT_SENS_DATA_00 0x49
#define MPU6050_RA_EXT_SENS_DATA_01 0x4A
#define MPU6050_RA_EXT_SENS_DATA_02 0x4B
#define MPU6050_RA_EXT_SENS_DATA_03 0x4C
#define MPU6050_RA_EXT_SENS_DATA_04 0x4D
#define MPU6050_RA_EXT_SENS_DATA_05 0x4E
#define MPU6050_RA_EXT_SENS_DATA_06 0x4F
#define MPU6050_RA_EXT_SENS_DATA_07 0x50
#define MPU6050_RA_EXT_SENS_DATA_08 0x51
#define MPU6050_RA_EXT_SENS_DATA_09 0x52
#define MPU6050_RA_EXT_SENS_DATA_10 0x53
#define MPU6050_RA_EXT_SENS_DATA_11 0x54
#define MPU6050_RA_EXT_SENS_DATA_12 0x55
#define MPU6050_RA_EXT_SENS_DATA_13 0x56
#define MPU6050_RA_EXT_SENS_DATA_14 0x57
#define MPU6050_RA_EXT_SENS_DATA_15 0x58
#define MPU6050_RA_EXT_SENS_DATA_16 0x59
#define MPU6050_RA_EXT_SENS_DATA_17 0x5A
#define MPU6050_RA_EXT_SENS_DATA_18 0x5B
#define MPU6050_RA_EXT_SENS_DATA_19 0x5C
#define MPU6050_RA_EXT_SENS_DATA_20 0x5D
#define MPU6050_RA_EXT_SENS_DATA_21 0x5E
#define MPU6050_RA_EXT_SENS_DATA_22 0x5F
#define MPU6050_RA_EXT_SENS_DATA_23 0x60
#define MPU6050_RA_MOT_DETECT_STATUS    0x61
#define MPU6050_RA_I2C_SLV0_DO      0x63
#define MPU6050_RA_I2C_SLV1_DO      0x64
#define MPU6050_RA_I2C_SLV2_DO      0x65
#define MPU6050_RA_I2C_SLV3_DO      0x66
#define MPU6050_RA_I2C_MST_DELAY_CTRL   0x67
#define MPU6050_RA_SIGNAL_PATH_RESET    0x68
#define MPU6050_RA_MOT_DETECT_CTRL      0x69
#define MPU6050_RA_USER_CTRL        0x6A
#define MPU6050_RA_PWR_MGMT_1       0x6B	//电源管理专用寄存器
#define MPU6050_RA_PWR_MGMT_2       0x6C
#define MPU6050_RA_BANK_SEL         0x6D
#define MPU6050_RA_MEM_START_ADDR   0x6E
#define MPU6050_RA_MEM_R_W          0x6F
#define MPU6050_RA_DMP_CFG_1        0x70
#define MPU6050_RA_DMP_CFG_2        0x71
#define MPU6050_RA_FIFO_COUNTH      0x72
#define MPU6050_RA_FIFO_COUNTL      0x73
#define MPU6050_RA_FIFO_R_W         0x74
#define MPU6050_RA_WHO_AM_I         0x75   /void MPU6050_Init(void);
void MPU6050_READ(u16* n);   #endif

MPU6050.c 

#include "MPU6050.h"void MPU6050_Init(void){  //初始化MPU6050I2C_SAND_BYTE(MPU6050_ADD,MPU6050_RA_PWR_MGMT_1,0x80);//解除休眠状态    最高位的数据为1,从而进入复位状态delay_ms(1000); //等待器件就绪I2C_SAND_BYTE(MPU6050_ADD,MPU6050_RA_PWR_MGMT_1,0x00);//解除休眠状态I2C_SAND_BYTE(MPU6050_ADD,MPU6050_RA_SMPLRT_DIV,0x07);//陀螺仪采样率I2C_SAND_BYTE(MPU6050_ADD,MPU6050_RA_CONFIG,0x06);	 I2C_SAND_BYTE(MPU6050_ADD,MPU6050_RA_ACCEL_CONFIG,0x00);//配置加速度传感器工作在16G模式I2C_SAND_BYTE(MPU6050_ADD,MPU6050_RA_GYRO_CONFIG,0x18);//陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
}void MPU6050_READ(u16* n){ //读出X、Y、Z三轴加速度/陀螺仪原始数据 //n[0]是AX,n[1]是AY,n[2]是AZ,n[3]是GX,n[4]是GY,n[5]是GZ u8 i;u8 t[14]; I2C_READ_BUFFER(MPU6050_ADD, MPU6050_RA_ACCEL_XOUT_H, t, 14); //读出连续的数据地址,包括了加速度和陀螺仪共12字节for(i=0; i<3; i++) 	//整合加速度n[i]=((t[2*i] << 8) + t[2*i+1]);for(i=4; i<7; i++)	//整合陀螺仪n[i-1]=((t[2*i] << 8) + t[2*i+1]);        
}

main.c

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"#include "MPU6050.h"int main (void){//主程序u16 t[6]={0};delay_ms(500); //上电时等待其他器件就绪RCC_Configuration(); //系统时钟初始化 RELAY_Init();//继电器初始化I2C_Configuration();//I2C初始化OLED0561_Init(); //OLED初始化OLED_DISPLAY_8x16_BUFFER(0,"  MPU6050 TEST  "); //显示字符串OLED_DISPLAY_8x16_BUFFER(2,"X:       X:     "); //显示字符串OLED_DISPLAY_8x16_BUFFER(4,"Y:       Y:     "); //显示字符串OLED_DISPLAY_8x16_BUFFER(6,"Z:       Z:     "); //显示字符串MPU6050_Init(); //MPU6050初始化while(1){MPU6050_READ(t);	//加速度//其中t[0~2]是加速度ACCEL,t[3~5]是陀螺仪GYROOLED_DISPLAY_8x16(2,2*8,t[0]/10000 +0x30);//显示OLED_DISPLAY_8x16(2,3*8,t[0]%10000/1000 +0x30);//显示OLED_DISPLAY_8x16(2,4*8,t[0]%1000/100 +0x30);//OLED_DISPLAY_8x16(2,5*8,t[0]%100/10 +0x30);//OLED_DISPLAY_8x16(2,6*8,t[0]%10 +0x30);//OLED_DISPLAY_8x16(2,11*8,t[3]/10000 +0x30);//显示OLED_DISPLAY_8x16(2,12*8,t[3]%10000/1000 +0x30);//显示OLED_DISPLAY_8x16(2,13*8,t[3]%1000/100 +0x30);//OLED_DISPLAY_8x16(2,14*8,t[3]%100/10 +0x30);//OLED_DISPLAY_8x16(2,15*8,t[3]%10 +0x30);//OLED_DISPLAY_8x16(4,2*8,t[1]/10000 +0x30);//显示OLED_DISPLAY_8x16(4,3*8,t[1]%10000/1000 +0x30);//显示OLED_DISPLAY_8x16(4,4*8,t[1]%1000/100 +0x30);//OLED_DISPLAY_8x16(4,5*8,t[1]%100/10 +0x30);//OLED_DISPLAY_8x16(4,6*8,t[1]%10 +0x30);//OLED_DISPLAY_8x16(4,11*8,t[4]/10000 +0x30);//显示OLED_DISPLAY_8x16(4,12*8,t[4]%10000/1000 +0x30);//显示OLED_DISPLAY_8x16(4,13*8,t[4]%1000/100 +0x30);//OLED_DISPLAY_8x16(4,14*8,t[4]%100/10 +0x30);//OLED_DISPLAY_8x16(4,15*8,t[4]%10 +0x30);//OLED_DISPLAY_8x16(6,2*8,t[2]/10000 +0x30);//显示OLED_DISPLAY_8x16(6,3*8,t[2]%10000/1000 +0x30);//显示OLED_DISPLAY_8x16(6,4*8,t[2]%1000/100 +0x30);//OLED_DISPLAY_8x16(6,5*8,t[2]%100/10 +0x30);//OLED_DISPLAY_8x16(6,6*8,t[2]%10 +0x30);//OLED_DISPLAY_8x16(6,11*8,t[5]/10000 +0x30);//显示OLED_DISPLAY_8x16(6,12*8,t[5]%10000/1000 +0x30);//显示OLED_DISPLAY_8x16(6,13*8,t[5]%1000/100 +0x30);//OLED_DISPLAY_8x16(6,14*8,t[5]%100/10 +0x30);//OLED_DISPLAY_8x16(6,15*8,t[5]%10 +0x30);//delay_ms(200); //延时(决定刷新速度)}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode周赛 | 2023-8-6

2023-8-6 题1体会我的代码 题2我的超时代码题目体会我的代码 题3体会我的代码 题1 体会 这道题完全就是唬人&#xff0c;只要想明白了&#xff0c;只要有两个连续的数的和&#xff0c;大于target&#xff0c;那么一定可以&#xff0c;两边一次切一个就好了。 我的代码 题2 我…

应急响应-勒索病毒的处理思路

0x00 关于勒索病毒的描述 勒索病毒入侵方式&#xff1a;服务弱口令&#xff0c;未授权&#xff0c;邮件钓鱼&#xff0c;程序木马植入&#xff0c;系统漏洞等 勒索病毒的危害&#xff1a;主机文件被加密&#xff0c;且几乎难以解密&#xff0c;对主机上的文件信息以及重要资产…

NAT协议(网络地址转换协议)详解

NAT协议&#xff08;网络地址转换协议&#xff09;详解 为什么需要NATNAT的实现方式静态NAT动态NATNAPT NAT技术的优缺点优点缺点 NAT协议是将IP数据报头中的IP地址转换为另外一个IP地址的过程&#xff0c;主要用于实现私有网络访问公有网络的功能。这种通过使用少量的IP地址代…

【源码分析】Nacos自动注册源码分析

文章目录 服务注册&#xff08;AP协议&#xff09;服务发现&#xff08;CP协议&#xff09;Nacos是如何整合到SpringCloudAlibaba的&#xff1f; 服务注册&#xff08;AP协议&#xff09; Nacos提供了NamingService的registerInstance方法来提供服务注册的功能。 因此只要我们…

vue v-slot指令

目录 定义语法使用场景场景一场景二场景三tips只有一个默认插槽时 定义 在Vue中&#xff0c; v-slot 指令用于定义插槽的模板内容。它用于在父组件中传递内容到子组件中的插槽。 v-slot 指令可以用于 标签或组件标签上&#xff0c;以便在子组件中使用插槽。 语法 使用 v-slo…

16-1_Qt 5.9 C++开发指南_多语言界面

文章目录 1. 多语言界面设计概述2. tr()函数的使用3. 生成语言翻译文件4. 使用Qt Linguist 翻译 ts 文件5. 调用翻译文件改变界面语言5.1 生成qm文件5.2 项目启动时设置界面语言5.3 动态切换语言 1. 多语言界面设计概述 有些软件需要开发多语言界面版本&#xff0c;如中文版和…

自动化测试框架?数据驱动vs关键字驱动,该怎么做?

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 对于自动化测试框…

BI报表工具有哪些作用?奥威BI全面剖析数据

BI报表工具有哪些作用&#xff1f;主要的作用是通过整合多业务来源数据&#xff0c;全面分析挖掘数据&#xff0c;来帮助企业实现数据化运营、支持智能决策、实现数据资产沉淀和增值、进行数据挖掘和预测分析、提高数据可读性和数据可视化程度等&#xff0c;从而提高企业的竞争…

【C++学习】STL容器——list

目录 一、list的介绍及使用 1.1 list的介绍 1.2 list的使用 1.2.1 list的构造 1.2.2 list iterator的使用 1.2.3 list capacity 1.2.4 list element access 1.2.5 list modifiers 1.2.6 list 迭代器失效 二、list的模拟实现 2.1 模拟实现list 三、list和vector的对比…

Java版知识付费平台免费搭建 Spring Cloud+Spring Boot+Mybatis+uniapp+前后端分离实现知识付费平台qt

&#xfeff;Java版知识付费源码 Spring CloudSpring BootMybatisuniapp前后端分离实现知识付费平台 提供职业教育、企业培训、知识付费系统搭建服务。系统功能包含&#xff1a;录播课、直播课、题库、营销、公司组织架构、员工入职培训等。 提供私有化部署&#xff0c;免费售…

CNN成长路:从AlexNet到EfficientNet(01)

一、说明 在 10年的深度学习中&#xff0c;进步是多么迅速&#xff01;早在 2012 年&#xff0c;Alexnet 在 ImageNet 上的准确率就达到了 63.3% 的 Top-1。现在&#xff0c;我们超过90%的EfficientNet架构和师生训练&#xff08;teacher-student&#xff09;。 如果我们在 Ima…

【Kubernetes部署篇】基于Ubuntu20.04操作系统搭建K8S1.23版本集群

文章目录 一、集群架构规划信息二、系统初始化准备(所有节点同步操作)三、安装kubeadm(所有节点同步操作)四、初始化K8S集群(master节点操作)五、添加Node节点到K8S集群中六、安装Calico网络插件七、测试CoreDNS可用性 一、集群架构规划信息 pod网段&#xff1a;10.244.0.0/16…

HTTP——九、基于HTTP的功能追加协议

HTTP 一、基于HTTP的协议二、消除HTTP瓶颈的SPDY1、HTTP的瓶颈Ajax 的解决方法Comet 的解决方法SPDY的目标 2、SPDY的设计与功能3、SPDY消除 Web 瓶颈了吗 三、使用浏览器进行全双工通信的WebSocket1、WebSocket 的设计与功能2、WebSocket协议 四、期盼已久的 HTTP/2.01、HTTP/…

卡尔曼滤波 | Matlab实现无迹kalman滤波仿真

文章目录 效果一览文章概述研究内容程序设计参考资料效果一览 文章概述 卡尔曼滤波 | Matlab实现无迹kalman滤波仿真 研究内容 无迹kalman滤波(UKF)不是采用的将非线性函数线性化的做法。无迹kalman仍然采用的是线性kalman滤波的架构,对于一步预测方程,使用无迹变换(UT)来…

visio,word添加缺少字体,仿宋_GB2312、楷体_GB2312、方正小标宋简体等字体下载

一. 内容简介 visio,word添加缺少字体,仿宋_GB2312、楷体_GB2312、方正小标宋简体等字体下载 二. 软件环境 2.1 visio 三.主要流程 3.1 下载字体 http://www.downza.cn/ 微软官方给的链接好多字体没有&#xff0c;其他好多字体网站&#xff0c;就是给你看个样式&#xff…

vue3中CompositionApi理解与使用

CompositionApi&#xff0c;组合式API&#xff0c;相当于react中hooks&#xff0c;函数式。 优势&#xff1a;1&#xff0c;增加了代码的复用性&#xff08;类似mixin&#xff0c;slot&#xff0c;高阶组件功能&#xff09; 2&#xff0c;代码可读性更好。可以将处理逻辑和视图…

Elasticsearch:语义搜索 - Semantic Search in python

当 OpenAI 于 2022 年 11 月发布 ChatGPT 时&#xff0c;引发了人们对人工智能和机器学习的新一波兴趣。 尽管必要的技术创新已经出现了近十年&#xff0c;而且基本原理的历史甚至更早&#xff0c;但这种巨大的转变引发了各种发展的“寒武纪大爆炸”&#xff0c;特别是在大型语…

数字孪生的「三张皮」问题:数据隐私、安全与伦理挑战

引言 随着数字化时代的来临&#xff0c;数据成为了当今社会的宝贵资源。然而&#xff0c;数据的广泛使用也带来了一系列隐私、安全与伦理挑战。数字孪生作为一种虚拟的数字化实体&#xff0c;通过收集和分析大量数据&#xff0c;模拟和预测现实世界中的各种情境&#xff0c;为…

【云原生|Docker系列第3篇】Docker镜像的入门实践

欢迎来到Docker入门系列的第三篇博客&#xff01;在前两篇博客中&#xff0c;我们已经了解了什么是Docker以及如何安装和配置它。本篇博客将重点介绍Docker镜像的概念&#xff0c;以及它们之间的关系。我们还将学习如何拉取、创建、管理和分享Docker镜像&#xff0c;这是使用Do…

循环结构进阶

二重循环 import java.util.Scanner;public class Demo01 {public static void main(String[] args) {Scanner scanner new Scanner(System.in);// 二重循环 外循环班级 内循环学生for (int i1; i<3; i) { // 外循环班级System.out.println("请输入第" i "…