首页 > 其他分享 >基于STM32通过TM1637驱动4位数码管详细解析(可直接移植使用)

基于STM32通过TM1637驱动4位数码管详细解析(可直接移植使用)

时间:2024-11-16 09:16:39浏览次数:3  
标签:SCL void uint8 STM32 数码管 SDA TM1637

目录

1.  单位数码管概述

2.  对应编码

2.1  共阳数码管

2.2  共阴数码管

3.  TM1637驱动数码管

3.1  工作原理

3.1.1  读键扫数据

3.1.2  显示器寄存器地址和显示模式

3.2  时序

3.2.1  指令数据传输过程(读案件数据时序)

3.2.2  写SRAM数据地址自动加1模式

3.2.3  写SRAM数据固定地址模式

3.3  数据指令

3.3.1  数据命令设置

3.3.2  显示控制命令设置

3.3.3  地址命令设置

3.4  程序流程图

3.4.1  采用地址自动加一模式的程序流程图

3.4.2  采用固定地址的程序设计流程图

4.  代码编写

4.1  准备配置  

4.1.1  C语言调用文件

4.1.2  宏定义

4.1.3  段码表

4.1.4  数码管地址表

 4.1.5  引脚初始化

4.1.6  电平配置 

4.2  IIC相关配置

4.2.1  起始信号

4.2.2  终止信号

4.2.3  接收应答

4.2.4  发送一个字节

4.3  TM1637相关配置

4.3.1  发送写显存的数据命令

4.3.2  向指定地址写入数据

4.3.3  在四个数码管上显示数据

4.3.4  设置亮度

4.3.5  显示开关

4.3.6  初始化配置

4.3.7  显示配置

4.3.8  TM1637.h文件配置

4.4  主函数


1.  单位数码管概述

        数码管的内部基本单元是发光二极管,数码管是发光器件之一,内部由七个条形发光二极管(a、b、c、d、e、f、g)和一个圆点发光二极管(dp)构成。

        按照数码管的公共接线不同,数码管又可分类为共阴极数码管和共阳极数码管两种,共阴极数码管的公共端接地,而共阳极数码管的公共端接电源。

2.  对应编码

2.1  共阳数码管

        数码管中所有的正极连接在一起,这个端口被称之为位选端口,其余的数码管引脚a-h都为段选端口2、共阳极数码管的编码(CA):

u8 code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //0-F

2.2  共阴数码管

        是数码管所有的负极连接在一起,这个端口被称之为位选端口,其余的数码管引脚a-h都为段选端口4、共阴极数码管的编码(CC/CK):

u8 code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //0-F

3.  TM1637驱动数码管

        TM1637 是一种带键盘扫描接口的LED(发光二极管显示器)驱动控制专用电路,内部集成有MCU 数字接口、数据锁存器、LED 高压驱动、键盘扫描等电路。本产品性能优良,质量可靠。主要应用于电磁炉、 微波炉及小家电产品的显示屏驱动。采用DIP/SOP20的封装形式。

3.1  工作原理

        微处理器的数据通过两线总线接口和 TM1637 通信,在输入数据时当 CLK 是高电平时,DIO 上的信号必须保持不变;只有 CLK 上的时钟信号为低电平时,DIO 上的信号才能改变。数据输入的开始条件是 CLK 为高电平时,DIO 由高变低;结束条件是 CLK 为高时,DIO 由低电平变为高电平。 
        TM1637 的数据传输带有应答信号 ACK,当传输数据正确时,会在第八个时钟的下降沿,芯片内部会产生一个应答信号 ACK 将 DIO 管脚拉低,在第九个时钟结束之后释放 DIO 口线。

符号管脚名称管脚号说明
DIO数据输入/输出17串行数据输入/输出,输入数据在 SLCK 的低电平变化,在SCLK 的高电平被传输,每传输一个字节芯片内部都将在第八个时钟下降沿产生一个 ACK
CLK时钟输入18在上升沿输入/输出数据
K1~K2键扫数据输入19~20输入该脚的数据在显示周期结束后被锁存
SG1~SG8输出(段)2~9段输出(也用作键扫描),N 管开漏输出
GRID6~GRID1输出(位)10~15位输出,P 管开漏输出
VDD逻辑电源165V±10%
GND逻辑地1接地

3.1.1  读键扫数据

        在有按键按下时,读键数据如下:

SG1SG2SG3SG4SG5SG6SG7SG8
K11110_11110110_11111010_11110010_11111100_11110100_11111000_11110000_1111
K21111_01110111_01111011_01110011_01111101_01110101_01111001_01110001_0111

注意:在无按键按下时,读键数据为:1111_1111,低位在前,高位在后。

3.1.2  显示器寄存器地址和显示模式

        该寄存器存储通过串行接口从外部器件传送到TM1637 的数据,地址00H-05H共6个字节单元,分别与芯片SGE和GRID管脚所接的LED灯对应,分配如下图: 
        写LED显示数据的时候,按照从显示地址低位到高位,从数据字节低位到高位操作。

SEG1SEG2SEG3SEG4SEG5SEG6SEG7SEG8
xxHL(第四位)xxHU(高四位)
B0B1B2B3B4B5B6B7
00HL00HUGRID1
01HL01HUGRID2
02HL02HUGRID3
03HL03HUGRID4
04HL04HUGRID5
05HL05HUGRID6

3.2  时序

3.2.1  指令数据传输过程(读案件数据时序)

注意:先读低位在读高位

3.2.2  写SRAM数据地址自动加1模式

Command1:设置数据

Command2:设置地址

Data1~N:传输数据

Command3:控制显示

3.2.3  写SRAM数据固定地址模式

Command1:设置数据

Command2:设置地址

Data1~N:传输数据

Command3:控制显示

3.3  数据指令

        指令用来设置显示模式和LED 驱动器的状态。 
        在CLK下降沿后由DIO输入的第一个字节作为一条指令。经过译码,取最高B7、B6两位比特位以区别不同的指令。

B7B6指令
01数据命令设置
10显示控制命令设置
11地址命令设置

        如果在指令或数据传输时发送STOP命令,串行通讯被初始化,并且正在传送的指令或数据无效(之前传送的指令或数据保持有效)。

3.3.1  数据命令设置

3.3.2  显示控制命令设置

3.3.3  地址命令设置

3.4  程序流程图

3.4.1  采用地址自动加一模式的程序流程图

3.4.2  采用固定地址的程序设计流程图

4.  代码编写

        开始前可以先了解一下IIC的用法,以及相关时序:

STM32F1之I2C通信_stm32f1 i2c-CSDN博客

STM32F1之I2C通信·软件I2C代码编写-CSDN博客

        TM1637采用的是IIC通信,但是又不是标准的IIC通信,标准的IIC协议是从高位到低位传输的,即MSB方式,但是TM1637介绍也介绍到工作原理时曾介绍到,其是从低位到高位进行数据传输。

4.1  准备配置  

4.1.1  C语言调用文件

        STM32的编写,有些需要调用C语言的头文件才能正常使用:

#include <string.h>//提供了一些用于处理字符串和内存块的函数。
#include <stdint.h>//定义了具有确定大小的整数类型。
#include <stdbool.h>//提供布尔类型支持。

4.1.2  宏定义

        这个宏定义了一个名为 TUBE_DISPLAY_NULL 的常量,值为 26。通常情况下,这个值可能用于表示一个不显示的状态或占位符,在显示器的控制代码中用来指示数字管不应显示任何有效数字:

#define TUBE_DISPLAY_NULL							26

        这个宏定义了一个名为 TUBE_DISPLAY_DECIMAL_POINT_OFFSET 的常量,值为 16。这个值可能用于表示小数点在显示器中的位置偏移量。例如,在一个七段显示器上,使用这个偏移量可以帮助确定小数点的位置,以便正确显示浮点数或需要小数点的数值:

#define TUBE_DISPLAY_DECIMAL_PIONT_OFFSET			16

4.1.3  段码表

        用于存储七段显示器中每个数字和字母的段码:

const uint8_t u8NumTab[] = 
{
	//0,	1,	 2,	  3,	 4,	  5,	 6,   7,   8,   9,   A,   b,  C,    d,   E,   F,  	
	0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
	//0., 1.,	 2.,	3.,	 4.,  5.,   6.,  7.,  8.,  9. Null
	0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x00
};

4.1.4  数码管地址表

//最左至最右数码管 ,依次为0-3号,对应的显示寄存器地址
const uint8_t u8TubeAddrTab[] = 
{
	0xC0,0xC1,0xC2,0xC3
};

 4.1.5  引脚初始化

        由于这里我们使用的软件I2C不受引脚限制,随便找两个普通的GPIO口就可以使用,首先我们随机找两个引脚对其进行初始化:

void TM1637_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	//开启GPIOB的时钟

	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);					//将PB10和PB11引脚初始化为开漏输出

	/*设置默认电平*/
	GPIO_SetBits(GPIOB, GPIO_Pin_10 | GPIO_Pin_11);			//设置PB10和PB11引脚初始化后默认为高电平(释放总线状态)
}

4.1.6  电平配置 

/**
  * 函    数:I2C写SCL引脚电平
  * 参    数:BitValue 协议层传入的当前需要写入SCL的电平,范围0~1
  * 返 回 值:无
  * 注意事项:此函数需要用户实现内容,当BitValue为0时,需要置SCL为低电平,当BitValue为1时,需要置SCL为高电平
  */
void TM1637_W_SCL(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)BitValue);		//根据BitValue,设置SCL引脚的电平
	Delay_us(10);												//延时10us,防止时序频率超过要求
}

/**
  * 函    数:I2C写SDA引脚电平
  * 参    数:BitValue 协议层传入的当前需要写入SDA的电平,范围0~0xFF
  * 返 回 值:无
  * 注意事项:此函数需要用户实现内容,当BitValue为0时,需要置SDA为低电平,当BitValue非0时,需要置SDA为高电平
  */
void TM1637_W_SDA(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOB, GPIO_Pin_11, (BitAction)BitValue);		//根据BitValue,设置SDA引脚的电平,BitValue要实现非0即1的特性
	Delay_us(10);												//延时10us,防止时序频率超过要求
}

/**
  * 函    数:I2C读SDA引脚电平
  * 参    数:无
  * 返 回 值:协议层需要得到的当前SDA的电平,范围0~1
  * 注意事项:此函数需要用户实现内容,当前SDA为低电平时,返回0,当前SDA为高电平时,返回1
  */
uint8_t TM1637_R_SDA(void)
{
	uint8_t BitValue;
	BitValue = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11);		//读取SDA电平
	Delay_us(10);												//延时10us,防止时序频率超过要求
	return BitValue;											//返回SDA电平
}

4.2  IIC相关配置

4.2.1  起始信号

          起始条件:SCL高电平期间,SDA从高电平切换到低电平。

        根据上图虚线框柱的地方进行配置: 

void TM1637_Start(void)
{
	TM1637_W_SDA(1);	//释放SDA,确保SDA为高电平
	TM1637_W_SCL(1);	//释放SCL,确保SCL为高电平
	TM1637_W_SDA(0);	//在SCL高电平期间,拉低SDA,产生起始信号
	TM1637_W_SCL(0);	//起始后把SCL也拉低,即为了占用总线,也为了方便总线时序的拼接
}

4.2.2  终止信号

         终止条件:SCL高电平期间,SDA从低电平切换到高电平。

        同理,根据上图虚线框柱的地方进行配置:

void  TM1637_Stop(void)
{
	TM1637_W_SCL(0);  //拉低SCL,确保SCL为低电平
	TM1637_W_SDA(0);	//拉低SDA,确保SDA为低电平
	TM1637_W_SCL(1);	//释放SCL,使SCL呈现高电平
	TM1637_W_SDA(1);	//在SCL高电平期间,释放SDA,产生终止信号
}

4.2.3  接收应答

        接收应答:主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)

//应答信号
uint8_t TM1637_ReceiveAck(void)
{
	uint8_t AckBit;							//定义应答位变量
	TM1637_W_SDA(1);							//接收前,主机先确保释放SDA,避免干扰从机的数据发送
	TM1637_W_SCL(1);							//释放SCL,主机机在SCL高电平期间读取SDA
	AckBit = TM1637_R_SDA();					//将应答位存储到变量里
	TM1637_W_SCL(0);							//拉低SCL,开始下一个时序模块
	return AckBit;							//返回定义应答位变量
}

4.2.4  发送一个字节

        发送一个字节: SCL低电平期间,主机将数据位依次放到SDA线上(高位先行) ,然后释放SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节。

        主机首先在SCL低电平,主机如果想发送0,就拉低SDA到低电平,主机如果想发送1,就放手,SDA回弹到高电平,在SCL低电平期间允许改变SDA的电平,如图黄色部分:

        但是这里需要注意标准的IIC协议从高位到低位传输的,但是TM1637从低位到高位进行数据传输,因此:

// 向 TM1637 发送一个字节数据
void TM1637_Write_Byte(uint8_t data)
{
    uint8_t i;
    TM1637_W_SCL(0); // 设置时钟线 SCL 为低电平,准备开始发送数据

    // 循环发送 8 位数据
    for (i = 0; i < 8; i++)
    {
        // 根据数据的最低位决定数据线 SDA 的状态
        if(data & 0x01)
        {
            TM1637_W_SDA(1); // 发送 1
        }
        else
        {
            TM1637_W_SDA(0); // 发送 0
        }    
        
        data = data >> 1; // 右移数据,处理下一个位
        
        TM1637_W_SCL(1); // 拉高时钟线,表示位数据有效
        TM1637_W_SCL(0); // 拉低时钟线,准备发送下一个位
    }
}

4.3  TM1637相关配置

        为了方便地对任意一个数码管写入数据,我们采用固定地址的方式,其流程如下:

        相关时序:

4.3.1  发送写显存的数据命令

// 向 TM1637 数码管写入命令
void TM1637_WriteCmd(uint8_t u8Cmd)
{
    // 开始信号,表示通信开始
    TM1637_Start();
    
    // 发送命令字节
    TM1637_Write_Byte(u8Cmd);
    
    // 接收确认应答
    TM1637_ReceiveAck();
    
    // 停止信号,表示通信结束
    TM1637_Stop();
}

4.3.2  向指定地址写入数据

// 向指定地址写入数据
// u8Addr: 要写入的地址
// u8Data: 要写入的数据
void TM1637_WriteData(uint8_t u8Addr, uint8_t u8Data)
{
    // 开始信号,表示通信开始
    TM1637_Start();
    
    // 发送地址字节
    TM1637_Write_Byte(u8Addr);
    
    // 接收确认应答
    TM1637_ReceiveAck();
    
    // 发送数据字节
    TM1637_Write_Byte(u8Data);
    
    // 接收确认应答
    TM1637_ReceiveAck();
    
    // 停止信号,表示通信结束
    TM1637_Stop();
}

4.3.3  在四个数码管上显示数据

// 在四个数码管上显示数据
// sData: 显示数据结构体,包含四个数码管的显示值
void TM1637_TubeDisplay(TM1637Tube_ts sData)
{
    uint8_t temp[4], i;
    
    // 根据 sData 中的值,从 u8NumTab 数组中获取对应的段码
    temp[0] = u8NumTab[sData.tube0]; // 获取第一个数码管的段码
    temp[1] = u8NumTab[sData.tube1]; // 获取第二个数码管的段码
    temp[2] = u8NumTab[sData.tube2]; // 获取第三个数码管的段码
    temp[3] = u8NumTab[sData.tube3]; // 获取第四个数码管的段码
    
    // 遍历四个数码管,逐个写入数据
    for (i = 0; i < 4; i++)
    {
        // 向每个数码管的地址写入对应的段码
        TM1637_WriteData(u8TubeAddrTab[i], temp[i]);
    }
}

        结构体TM1637Tube_ts,该结构体存放到.h中,若是存放到.c文件需要将其放到头文件后面,防止TM1637_TubeDisplay()函数搜索不到:

typedef struct 
{
	uint8_t tube0;
	uint8_t tube1;
	uint8_t tube2;
	uint8_t tube3;
}TM1637Tube_ts;

4.3.4  设置亮度

//设置亮度
//0x88为开显示,u8Brt亮度
void  TM1637_SetBrightness(uint8_t u8Brt)
{
	TM1637_WriteCmd(0x88 | u8Brt);
}

4.3.5  显示开关

//显示开关
//0x88为开显示,0x80关显示
void  TM1637_Switch(bool bState)
{
	bState ? TM1637_WriteCmd(0x88) : TM1637_WriteCmd(0x80);
}

4.3.6  初始化配置

void Display_Init(void)
{
	TM1637_Switch(0);//关显示
	TM1637_SetBrightness(0x87);//设置亮度,开显示
	TM1637_WriteCmd(0x44);//写数据到寄存器,固定地址模式
	memset(&sDisplayData, 0xFF, sizeof(sDisplayData));
}

4.3.7  显示配置

void Display_TubeDataProcess(uint16_t u16Data)
{
	memset(&sDisplayData, 0xFF, sizeof(sDisplayData));

	if (u16Data > 9999)
	{
		u16Data = 9999;//最多四位数
	}
	if (u16Data > 999)//四位数
	{
		sDisplayData.tube0 = (uint8_t)(u16Data / 1000);//千位
		sDisplayData.tube1 = (uint8_t)(u16Data / 100 % 10);//百位
		sDisplayData.tube2 = (uint8_t)(u16Data % 100 / 10);//十位
	  sDisplayData.tube3 = (uint8_t)(u16Data % 10);//个位
	}
	else if (u16Data > 99)//三位数
	{
		sDisplayData.tube0 = TUBE_DISPLAY_NULL;//不显示
		sDisplayData.tube1 = (uint8_t)(u16Data / 100);//百位
		sDisplayData.tube2 = (uint8_t)(u16Data / 10 % 10);//十位
	    sDisplayData.tube3 = (uint8_t)(u16Data % 10);//个位	   
	}
	else if (u16Data > 9)//两位数
	{
		sDisplayData.tube0 = TUBE_DISPLAY_NULL;//不显示
	  sDisplayData.tube1 = TUBE_DISPLAY_NULL;//不显示
		sDisplayData.tube2 = (uint8_t)(u16Data / 10);//十位
	  sDisplayData.tube3 = (uint8_t)(u16Data % 10);//个位
	}
	else//一位数
	{
		sDisplayData.tube0 = TUBE_DISPLAY_NULL;//不显示
	  sDisplayData.tube1 = TUBE_DISPLAY_NULL;//不显示
		sDisplayData.tube2 = TUBE_DISPLAY_NULL;//不显示
	  sDisplayData.tube3 = (uint8_t)u16Data;//个位
	}
	TM1637_TubeDisplay(sDisplayData);
}

4.3.8  TM1637.h文件配置

        以上代码为.c文件配置,下面是.h文件配置:

#ifndef _TM1637_H_
#define _TM1637_H_

#include <stdbool.h>

typedef struct 
{
	uint8_t tube0;
	uint8_t tube1;
	uint8_t tube2;
	uint8_t tube3;
}TM1637Tube_ts;

void TM1637_Init(void);
void TM1637_Start(void);
void  TM1637_Stop(void);
uint8_t TM1637_ReceiveAck(void);
void TM1637_Write_Byte(uint8_t data);
void TM1637_WriteCmd(uint8_t u8Cmd);
void TM1637_WriteData(uint8_t u8Addr, uint8_t u8Data);
void TM1637_TubeDisplay(TM1637Tube_ts sData);
void TM1637_SetBrightness(uint8_t u8Brt);
void TM1637_Switch(bool bState);
void Display_Init(void);
void Display_TubeDataProcess(uint16_t u16Data);

#endif

4.4  主函数

#include "stm32f10x.h"              
#include "Delay.h"
#include "TM1637.h"


int main(void)
{	
	TM1637_Init();
    Display_Init();	
	
	while (1)
	{
		Display_TubeDataProcess(1234);
	}
}

基于STM32通过SN74HC595驱动4位数码管详细解析-CSDN博客

标签:SCL,void,uint8,STM32,数码管,SDA,TM1637
From: https://blog.csdn.net/MANONGDKY/article/details/143433994

相关文章

  • STM32一种计算CPU使用率的方法及其实现原理
    本文将以STM32F429+FreeRTOS+KEIL为测试环境,看下MCU的使用率1、计算STM32使用率的官方方法在其CubeMX的固件库中2、加入自己的工程2.1、文件cpu_utils.c有描述使用的步骤2.2、实操一遍第一步:将上图中的cpu_utils.c文件添加到工程中,并将其头文件路径加......
  • STM32项目实战:基于STM32U5的智能大棚温控系统(LVGL),附项目教程/源码
    《智能大棚温控系统_STM32U5》项目完整文档、项目源码,点击下方链接免费领取。项目资料领取https://s.c1ns.cn/F5XyUSTM32项目实战之“智能大棚温控系统”(基于STM32U5)今天小编来分享一个《智能大棚温控系统》的项目案例,硬件平台是STM32U5开发板+资源扩展板+显示触摸屏+仿真器,项......
  • 基于stm32的bacnet协议
    bacnet协议对于国内网站来说,几乎可以说资料为零,通俗大论一遍,具体操作方法屁都没说先从工具说起开发工具BACnetScan:(讯绕提供)(工具1)链接:https://pan.baidu.com/s/1TJxc0xaEsCT3lJOlG78B7w提取码:t7bwYabe:(工具2)链接:https://pan.baidu.com/s/1jfsbGQwv08GISF0VeOjY_g提取码:mmdc......
  • STM32简介
    STM32F11、片上资源/外设Peripheral深颜色内核里的外设,其它为外部外设各外设作用介绍:NVIC:内核中用于管理中断的设备,比如配置中断优先级SysTick:内核中的定时器,主要用来给操作系统提供定时服务RCC:对系统的时钟进行配置,STM32中其它外设上电情况下,默认是没有时钟的,没有时钟的......
  • 基于STM32的智能红绿灯系统设计
    引言本项目基于STM32微控制器设计了一个智能红绿灯系统,通过集成多个传感器模块和控制设备,实现对道路交通的智能化控制。该系统能够根据交通流量自动调整红绿灯的切换时间,提升道路通行效率,缓解交通拥堵。项目涉及硬件设计、传感器数据处理、交通信号管理的实现,适用于城市十字路......
  • stm32 M750基于4g的物联网(阿里云)环境监测系统设计求助
    前言:基于正点原子的,用的阿里云平台,之前的主函数设备上传数据代码是这个,按下KEY0后成功输送给阿里云 key=key_scan(0);//按键if(key==KEY0_PRES){ snprintf(DTU_DATA,sizeof(DTU_DATA),//将数据以json形式传送到阿里云"......
  • 基于STM32设计的矿山环境监测系统(NBIOT)_262
    文章目录一、前言1.1项目介绍【1】开发背景【2】研究的意义【3】最终实现需求【4】项目硬件模块组成1.2设计思路【1】整体设计思路【2】上位机开发思路1.3项目开发背景【1】选题的意义【2】摘要【3】国内外相关研究现状【5】参考文献1.4......
  • 基于STM32设计的大棚育苗管理系统(4G+华为云IOT)_265
    文章目录一、前言1.1项目介绍【1】项目开发背景【2】设计实现的功能【3】项目硬件模块组成【4】设计意义【5】国内外研究现状【6】摘要1.2设计思路1.3系统功能总结1.4开发工具的选择【1】设备端开发【2】上位机开发1.5参考文献1.6系统框......
  • 基于STM32的扫码取件系统设计思路:PWM、TCP/HTTP、SQLite等技术
    一、项目概述随着电子商务的迅猛发展,快递取件的智能化和便捷性需求日益增长。本项目旨在设计一款基于STM32F103C8T6单片机的扫码取件系统,结合语音播报模块、WiFi模块、显示模块、舵机控制电路和按键电路,实现高效、智能的取件功能。用户通过扫描二维码即可快速取件,同时系统......
  • STM32外设之GPIO&LED指示灯模块程序设计
    文章目录一、STM32外设之GPIO二、CT117E-M4的LED电路原理三、LED指示灯模板程序设计一、STM32外设之GPIO1.GPIO的8种工作模式:模式配置模式寄存器输出类型寄存器输出速度寄存器上/下拉寄存器输入浮空00不使用不使用00输入上拉00不使用不使用01输入下拉00不使用不使用......