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.阵列键盘测试程序

按下时:红线蓝线短接 

 

 阵列键盘

新建文件夹文章来源地址https://uudwc.com/A/xkVMm

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();//初始化IO
	GPIO_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;//将第二次取得值放入寄存器b
		a = 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;  //抢占优先级 2
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;     //子优先级  2
	NVIC_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;  //抢占优先级 2
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;     //子优先级  2
	NVIC_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;  //抢占优先级 2
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;     //子优先级  2
	NVIC_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;  //抢占优先级 2
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;     //子优先级  2
	NVIC_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;//标志位清0

	NVIC_Configuration();//设置中断优先级
	KEYPAD4x4_Init();//阵列键盘初始化
	KEYPAD4x4_INT_INIT();//阵列键盘的中断初始化

	while(1){

		//其他程序内容

		if(INT_MARK){ //中断标志位为1表示有按键中断
			INT_MARK=0;//标志位清0
			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);//
			}
		}
	}
}

二:舵机控制

第一步:将舵机连接到开发板上(舵机接口)

第二步:将触摸按键的四个跳线帽短接

注意事项
    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)); //接口输出高电平1
	delay_us(500+a*10+b); //延时
	GPIO_WriteBit(SE_PORT,SE_OUT,(BitAction)(0)); //接口输出高电平1
	delay_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_CH3
    GPIO_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_DIV1
    TIM_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,预分频系数24

	while(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~80us
        retry++;
        delay_us(1);
    }	 
    if(retry>=100)return 1; else retry=0;
    while (!GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO)&&retry<100){//DHT11拉低后会再次拉高40~80us
        retry++;
        delay_us(1);
    }
    if(retry>=100)return 1;	    
    return 0;
}

u8 Dht11_ReadBit(void){ //从DHT11读取一个位 返回值:1/0
    u8 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或0
    if(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]; //将湿度值放入指针1
			h++;
            *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){  //初始化MPU6050
	I2C_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]是陀螺仪GYRO
		OLED_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); //延时(决定刷新速度)
	}
}

原文地址:https://blog.csdn.net/liu17234050/article/details/132125764

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

h
上一篇 2023年08月08日 04:27
opencv基础-38 形态学操作-闭运算(先膨胀,后腐蚀)cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
下一篇 2023年08月08日 04:27