STM32F103核心板//双数码管//74HC595//串行输入,并行输出//程序//开发过程

STM32F103C8T6//74HC595//双数码管显示

.
.

本次要说明的程序

本程序是在cubemx初始化stm32f103c8后直接生成的初始程序上继续编程。

#include "main.h"
#define SDI_SET  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET)
#define SDI_RESET  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET)
#define SCLK_SET  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET)
#define SCLK_RESET  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET)
#define LOAD_SET  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET)
#define LOAD_RESET  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET)
uint32_t NumShow[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

void Delay1000ms();
void Show(uint32_t shi,uint32_t ge);
void delay(uint16_t temp)
	
{
	uint16_t  i,j,t;
	t=temp;
	while(t!=0)
    {
		for(i=200;i>0;i--)
       	for(j=248;j>0;j--);
		t--;
	}
}

void SystemClock_Config(void);
static void MX_GPIO_Init(void);

int main(void)
{
	uint32_t shi,ge;
	HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  while (1)
  {
		for(shi=0;shi<10;shi++)
		{
			for(ge=0;ge<10;ge++)
			{
			   Show(NumShow[shi],NumShow[ge]);
			   if (ge==10)
		    	 ge=0;
			   Delay1000ms();
				 if (ge%2==1)
				   HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);
				 else
					 HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);
		  }
			if (shi==10)
				shi=0;
		}
  }
}

void Show(uint32_t shi,uint32_t ge)  //因为是两个74HC595的级联,所以先移位个位数,再移位十位数。这样才可显示(十位数,个位数)
{
	uint32_t k,i;
	for(k=0;k<8;k++)        //下面的代码要循环8次,直到把整个数据的所有二进制数位遍历一遍
		{
			 SCLK_RESET;   //数据移位信号先为低电平,为移位准备
             if((ge&0x80)==0x80)  //如果所给的ge数据的二进制形式的最高位和0x80(10000000)相与后值不变,即最高位是1
             {
				 SDI_SET;  //判断出该数据的最高位是1,将该数据的最高位1送入移位寄存器
			 }				 
			 else          //如果不是的话
             SDI_RESET ;   //判断出该数据的最高位是0,将该数据最高位的0送入移位寄存器
	    ge= ge<<1;         //让ge的二进制数据整个左移一位,为下一次判断次高位做准备
		SCLK_SET ;	       //让数据寄存器中的数据移位(Q0->Q1->Q2–>Q3–>…–>Q7)
		}
		LOAD_RESET ;       //先确认拉低  
		LOAD_SET;          //上升沿时移位寄存器的数据进入数据存储寄存器,ST_CP端产生一个正脉冲,更新显示数据
		
		for(i=0;i<8;i++)
		{
			 SCLK_RESET;
             if((shi&0x80)==0x80)
             {
				 SDI_SET;
			 }				 
			 else
             SDI_RESET ;	
		shi=shi<<1;
		SCLK_SET ;			 
		}
		LOAD_RESET ;
		LOAD_SET;
}

void Delay1000ms()		//@30.000MHz
{
	unsigned char i, j, k;
	i = 114;
	j = 255;
	k = 107;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

.
.
.
.
.

效果描述

程序实现数码管从00-99循环显示,每个数之间间隔1s左右

最终实现效果
在这里插入图片描述图1
在这里插入图片描述
图2
.
.
.
.

硬件方面

核心板原理图

在这里插入图片描述

74hc595显示屏驱动芯片

在这里插入图片描述

74595的数据端说明
Q0–Q7八位并行输出端,可以直接控制数码管的8个段
Q7’级联输出端。将它接下一个595的DS端
DS串行数据输入端,级联的话接上一级的Q7’
74595的控制端说明
(MR)’(10脚)低电平时将移位寄存器的数据清零。通常接到VCC防止数据清零
SH_CP(11脚)上升沿时数据寄存器的数据移位。Q0->Q1->Q2–>Q3–>…–>Q7;下降沿移位寄存器数据不变。(脉冲宽度:5V时,大于几十纳秒就行了。通常都选微秒级)
ST_CP(12脚)上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变。通常将ST_CP置为低电平,当移位结束后,在ST_CP端产生一个正脉冲(5V时,大于几十纳秒就行了。通常都选微秒级),更新显示数据。
(OE)’(13脚)高电平时禁止输出(高阻态)。如果单片机的引脚不紧张,用一个引脚控制它,可以方便地产生闪烁和熄灭效果。比通过数据端移位控制要省时省力。

补充:
1> 74595的主要优点是具有数据存储寄存器,在移位的过程中,输出端的数据可以保持不变。这在串行速度慢的场合很有用处,数码管没有闪烁感。
2> 595是串入并出带有锁存功能移位寄存器,它的使用方法很简单,如下面的真值表,在正常使用时ST_CP为低电平,/OE为低电平。从DS每输入一位数据,串行输入时钟SH_CP上升沿有效一次,直到八位数据输入完毕,输出时钟ST_CP上升沿有效一次,此时,输入的数据就被送到了输出端。
.
.
.
.
.

双数码管模块

介绍
在这里插入图片描述
外观尺寸
在这里插入图片描述
电路连接图
在这里插入图片描述
硬件中:
核心板---->PCB------>74HC595
B3--------->SDI------->DS(串行数据输入)
B4--------->SCL------>SH_CP(数据输入时钟线)
B5--------->LOAD---->ST_CP(数据输出时钟线)
C13--------------------->核心板上的灯

.
.
.

程序疑难讲解

#define SDI_SET HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET)
SDI高电平,
#define SDI_RESET HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET)
SDI低电平
串行数据输入

#define SCLK_SET HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET)
#define SCLK_RESET HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET)
SCLK上升沿时数据寄存器的数据移位。Q0->Q1->Q2–>Q3–>…–>Q7;下降沿移位寄存器数据不变。

#define LOAD_SET HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET)
#define LOAD_RESET HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET)
上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变。通常将ST_CP置为低电平,当移位结束后,在ST_CP端产生一个正脉冲,更新显示数据。
.
.
.

该程序最难理解的地方就是下面这部分函数,需要把上面的74HC595的引脚功能理解透彻,再结合下面程序具体分析哈。具体的备注在上面的代码块里面方的也有,大家根据习惯看哈(我知道没多少人看,主要是给自己留作笔记看)
void Show(uint32_t shi,uint32_t ge)
{
uint32_t k,i;
for(k=0;k<8;k++)
//下面的代码要循环8次,直到把整个数据的所有二进制数位遍历一遍
{
SCLK_RESET;
//数据移位信号先为低电平,为移位准备
if((ge&0x80)==0x80)
//如果所给的ge数据的二进制形式的最高位和0x80(10000000)相与后值不变,即最高位是1
{
SDI_SET;
//将该数据的最高位1送入数据缓冲区
}
else
//如果不是的话
SDI_RESET ;
//将该数据最高位的0送入数据缓冲区
ge= ge<<1;
//让ge的二进制数据整个左移一位,为下一次判断次高位做准备
SCLK_SET ;
//让数据寄存器中的数据移位(Q0->Q1->Q2–>Q3–>…–>Q7)
}
LOAD_RESET ;
//先确认拉低
LOAD_SET;
//上升沿时移位寄存器的数据进入数据存储寄存器,ST_CP端产生一个正脉冲,更新显示数据

for(i=0;i<8;i++)
{
SCLK_RESET;
if((shi&0x80)==0x80)
{
SDI_SET;
}
else
SDI_RESET ;
shi=shi<<1;
SCLK_SET ;
}
LOAD_RESET ;
LOAD_SET;
}

.
.
.
.
.
.
.
.
.
.
.
待补充

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值