#ifndef__Matrix_H__
#define__Matrix_H__
#ifdef__cplusplus
extern"C" {
#endif
#define SET 0x1 //置1操作
#define CLEAR 0x2 // 清0操作
#define NEGATE 0x3 //取反操作
#defineMOVE_UP 0x1 // 向上平移1
#defineMOVE_DOWN 0x2 // 向下平移1
#defineMOVE_LEFT 0x3 // 向左平移1
#defineMOVE_RIGHT 0x4 // 向右平移1
// 列数据输出到P0口
#defineMatrixOutputData(Dat) {P0 = (Dat);}
// P2口输出对应列的扫描选择线,低有效
#defineMatrixOutputSelect(Select) {P2 = ~(1<
void MatrixClearScreen(void);
void MatrixMove(unsigned char Direction, unsigned char Filling);
unsigned char*MatrixGetBuffer(void);
void MatrixScan(void);
void MatrixSetPoint(unsigned char x, unsigned char y, unsigned char Operation);
#ifdef__cplusplus
}
#endif
#endif/*__Matrix_H__*/
外部应用通过引入点阵屏的模块头文件Matrix.h来实现调用点阵屏驱动函数,简单测试调用(心形在点阵屏内随机平移)实现如下:
#include"reg52.h"
#include"Matrix.h"
// 心形坐标数据
static unsigned charcode HeartShape[][2] = {
{3, 3}, {4, 2}, {5,3}, {5, 4}, {4, 5},
{3, 6}, {2, 5}, {1,4}, {1, 3}, {2, 2},
};
// 以定时器时间为计时标准,记录时间间隔
static volatileunsigned int SystemTick = 0;
// 定时器1.5ms中断处理进行数码管刷新
void T0_Interrupt()interrupt 1
{
TH0 = (65536-1500) / 256;
TL0 = (65536-1500) % 256;
SystemTick++; // 记录时间间隔
MatrixScan(); // 刷新数码管
}
void T0_Init()
{
TMOD = 0x01; // 定时器0工作方式1
// 1.5ms计时中断(12M)
TH0 = (65536-1500) / 256;
TL0 = (65536-1500) % 256;
ET0 = 1; // 定时器T0中断允许
EA = 1; // 总中断允许
}
void main()
{
unsigned char *pBuffer;
unsigned char State = 0;
unsigned char Point;
unsigned char Direction;
unsigned char DataAnd;
unsigned char i;
// 定时器初始化
T0_Init();
// 获得点阵显存,以作数据处理
pBuffer = MatrixGetBuffer();
// 点阵屏清屏
MatrixClearScreen();
// 开启定时器进行计时以及点阵扫描
TR0 = 1;
Point = 0;
while(1) {
switch (State) {
case 0: //状态0为逐点打出心形
if (SystemTick > 334) { // 500ms打心形的一个点
SystemTick = 0;
MatrixSetPoint(HeartShape[Point][0],HeartShape[Point][1], CLEAR);
Point++;
if (Point >sizeof(HeartShape)/sizeof(HeartShape[0])) {
State = 1; // 心形打完,进入状态1,是否到边界判断
Direction = TL0& 0x3; // 随机得出心形的移动方向
}
}
break;
case 1: // 状态1为心形是否移动到点阵屏边界的判断
switch (Direction) { // 移动方向判断是否到相应方向的边界
case 0: // 左边界判断
// 第一列的点有一个亮,则认为图形到了左边界
if (pBuffer[0] !=0xff) {
Direction = TL0& 0x3; // 重新选择移动方向
} else {
State = 2; // 未到左边界,进入状态2进行左平移
}
break;
case 1: // 右边界判断
// 第八列的点有一个亮,则认为图形到了右边界
if (pBuffer[7] !=0xff) {
Direction = TL0& 0x3; // 重新选择移动方向
} else {
State = 2; // 未到右边界,进入状态2进行右平移
}
break;
case 2: // 上边界判断
// 所有列的第一行点有一个亮,则认为图形到了上边界
DataAnd = 0xff;
for (i=0; i<8; i++) {
DataAnd &= pBuffer[i];
}
if (DataAnd & 0x1) {
State = 2; // 未到上边界,进入状态2进行上平移
} else {
Direction = TL0& 0x3; // 重新选择移动方向
}
break;
case 3: // 下边界判断
// 所有列的第八行点有一个亮,则认为图形到了下边界
DataAnd = 0xff;
for (i=0; i<8; i++) {
DataAnd &= pBuffer[i];
}
if (DataAnd & 0x80) {
State = 2; // 未到下边界,进入状态2进行下平移
} else {
Direction = TL0& 0x3; // 重新选择移动方向
}
break;
default:
break;
}
break;
case 2: // 状态2为对点阵屏平移
if (SystemTick < 667){// 1s平移1次
continue;
}
SystemTick = 0;
switch (Direction) {
case 0: // 左平移,平移后的空缺位置灭
MatrixMove(MOVE_LEFT, 0xff);
break;
case 1: // 右平移,平移后的空缺位置灭
MatrixMove(MOVE_RIGHT,0xff);
break;
case 2: // 上平移,平移后的空缺位置灭
MatrixMove(MOVE_UP, 0xff);
break;
case 3: // 下平移,平移后的空缺位置灭
MatrixMove(MOVE_DOWN, 0xff);
break;
default:
break;
}
State = 1; // 平移后再进入状态1进行边界检测
break;
default:
break;
}
}
}
如果觉得《51单片机led点阵C语言 51单片机驱动LED点阵扫描显示C语言程序》对你有帮助,请点赞、收藏,并留下你的观点哦!