变量的作用域
所谓的作用域就是指变量起作用的范围,也是变量的有效范围。变量按作用域可以分为局部变量和全局变量。
局部变量
在一个函数内部声明的变量是内部变量,它只在本函数内有效,在本函数以外是不能使用的,这样的变量就是局部变量。此外,函数的形参也是局部变量。
全局变量
在函数外声明的变量就是全局变量。
还有一种特殊情况,大家在看程序的时候请注意,C语言是允许局部变量和全局变量同名的,它们定义后在内存中占有不同的内存单元。如果在同一源文件中,全局变量和局部变量同名,在局部变量作用域范围内,只有局部变量有效,全局变量不起作用,也就是说局部变量具有更高优先级。
变量的存储类别
变量的存储类别分为自动、静态、寄存器和外部四种。
函数中的局部变量,如果不加static这个关键字来修饰都属于自动变量,也叫作动态存储变量。动态存储变量的关键字是auto,但是这个关键字是可以省略的,所以平时都不用。
那么与动态变量对应的就是静态变量。首先,全局变量均是静态变量,此外,还有一种特殊的局部变量也是静态变量。即在定义局部变量时前边加上static这个关键字,加上这个关键字的变量就称之为静态局部变量,它的特点是,在整个生存期中只赋一次初值,在第一次执行该函数时,它的值就是给定的那个初值,而之后在该函数所有的执行次数中,它的值都是上一次函数执行结束后的值,即它可以保持前次的执行结果。
点阵的初步认识
一个数码管是8个LED组成,同理,一个8×8的点阵就是由64个LED小灯组成。
点阵的图形显示
这里有两种,一种是用74HC138控制点阵行,另一种用74HC595控制点阵行。
#include<REG52.H>
//74HHC138
sbit ADDR0=P2^2;
sbit ADDR1=P2^3;
sbit ADDR2=P2^4;
void main(){
ADDR2=0;ADDR1=0;ADDR0=0; //Y0为低电平
P0=0xff; //第一列led全点亮
while(1);
}
74HC595芯片介绍
8位串行输入、并行输出的位移缓存器,其中并行输出为三态输出(高电平、低电平和高阻抗)。
15和1~7脚QA--QH:并行数据输出
9和QH非:串行数据输出
10脚和SCLK非(MR):低电平复位引脚
11SCK(SHCP):移位寄存器时钟输入
12RCK(STCP):存储寄存器时钟输入
13G非(OE):输出有效
14SER(DS):串行数据输入
移位寄存器和存储器时钟是单独的时钟。数据在SCK的上升沿输入,在RCK的上升沿进入到 存储器中。如果两个时钟连到一起 ,则移位寄存器总是比存储器早一个脉冲。移位寄存器有一个串行输入(DS),和一个串行输出(Q7非 ),和一个异步的低电平复位,存储寄存器有一个并行8位的,具有三态的总线输出,当MR为高电平,OE为低电平时,数据在SHCP上升沿进入移位寄存器,在STCP上升沿输出到并行端口。
注意:J24跳线短接到GND
实现点阵从下到上一行一行移动
#include <REG52.H>
// 74HC595
typedef unsigned char u8;
typedef unsigned int u16;
sbit SRCLK = P3 ^ 6;
sbit RCLK_ = P3 ^ 5;
sbit SER = P3 ^ 4;
u16 j;
#define LED_PORT P0
u8 ghc595_buf[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
void hc595_write_date(u8 dat)
{
u8 i = 0;
for (i = 0; i < 8; i++) {
SER = dat >> 7; // 优先传输一个字节中的高位
dat <<= 1; // 低位向高位移动
// 给移位寄存器时钟一个脉冲
SRCLK = 0;
SRCLK = 1;
}
// 给存储寄存器时钟一个脉冲
RCLK_ = 0;
RCLK_ = 1;
}
void main()
{
u8 i;
LED_PORT = 0x00;
while (1) {
for (i = 0; i < 8; i++) {
hc595_write_date(0x00);
hc595_write_date(ghc595_buf[i]);
for (j = 0; j < 41666; j++)
;
}
}
}
点阵的动画显示
点阵的动画显示,说到底就是对多张图片分别进行取模,使用程序算法巧妙地切换图片。
让点阵显示一个I❤U的动画。
取模;
#include <REG52.H>
typedef unsigned int u16;
typedef unsigned char u8;
sbit SRCLK = P3 ^ 6; // 移位时钟
sbit SER = P3 ^ 4; // 数据
sbit RCLK_ = P3 ^ 5; // 存储时钟
#define LED_COL_PORT P0
u8 code scan_col[8] = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe}; // 列扫描实现动态显示
u8 code love[] = {
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x3C,
0x18,
0x18,
0x18,
0x18,
0x3C,
0x00,
0x66,
0xFF,
0xDB,
0xC3,
0x66,
0x3C,
0x18,
0x00,
0x00,
0x66,
0x66,
0x66,
0x66,
0x3C,
0x18,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
};
void hc595_write_date(u8 dat)
{
u8 i;
for (i = 0; i < 8; i++) {
SER = dat >> 7; // 每次传最高位
dat <<= 1;
SRCLK = 0;
SRCLK = 1; // 移位时钟
}
RCLK_ = 0;
RCLK_ = 1; // 存储时钟
}
void main()
{
u8 i, j, k, l;
while (1) {
for (l = 0; l < 32; l++) { // 一共32张图片
for (j = 0; j < 200; j++) { // 单张图片延时
for (i = 0; i < 8; i++) { // 单张图片显示
P0 = scan_col[i];
hc595_write_date(love[i + l]);
for (k = 0; k < 10; k++)
;
hc595_write_date(0x00);
}
}
}
}
}