赞
踩
.
.
本程序是在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
.
.
.
.
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;
}
.
.
.
.
.
.
.
.
.
.
.
待补充
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。