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;
}

.
.
.
.
.
.
.
.
.
.
.
待補充

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章