📄 led_8_8.c
字号:
#include "LED_8_8.H"
#define LED1 0x00
#define LED2 0x08
#define LED3 0x10
#define LED4 0x18
sbit SPI_DATA = P1^4;
sbit SPI_CS = P1^3;
sbit SPI_CLK = P1^2;
void Delay_1ms(int z);
unsigned char Show[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};
unsigned char Show_Temp[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};
unsigned char Pos_x = 0; //坐标初始位置(0,0)对应第2个点阵最后一行的第一个点上
unsigned char Pos_y = 0;
unsigned char LED_Sel = 2; //点阵块的选择,范围1--4
unsigned char Dis_num = 30; //坐标当前位置所对应显示数组位,范围0--31;
//****************************************************************************
//* 名称:LocateXY()
//* 功能:使当前坐标位置亮,但移动后要使它灭
//* 注意:(7 - Pos_y)<<1 + 16 左移的优先级比加减低,故要加括号:((7 - Pos_y)<<1) + 16
//****************************************************************************
void LocateXY(void) //
{
if( (Pos_x>=0) && (Pos_x<8) )
{
if( (Pos_y>=0) && (Pos_y<8) ) //第二个点阵
{
LED_Sel = 2;
Dis_num = ((7 - Pos_y)<<1) + 16; //左移1位相当与乘以2!
}
else
if( Pos_y>=8 && Pos_y<16) //第一个点阵
{
LED_Sel = 1;
Dis_num = (15 - Pos_y)<<1;
}
}
else
if( Pos_x>=8 && Pos_x<16)
{
if( Pos_y>=0 && Pos_y<8) //第四个点阵
{
LED_Sel = 4;
Dis_num = ((7 - Pos_y)<<1) + 17;
}
else
if( Pos_y>=8 && Pos_y<16) //第三个点阵
{
LED_Sel = 3;
Dis_num = ((15 - Pos_y)<<1) + 1;
}
}
//=========================坐标所在的位置要为亮,当移走时就灭=======================
if(Pos_x < 8)
Show[Dis_num] |= ( 0x80>>Pos_x );
else
Show[Dis_num] |= ( 0x80>>(Pos_x-8) );
}
//****************************************************************************
//* 名称:Locate_Task()
//* 功能:实现光标的移动和点阵的亮灭控制,相当于在点阵上画图
//* 说明:可惜这点阵板没有地址锁存芯片74HC573,与键盘有冲突了
//****************************************************************************
void Locate_Task(void)
{
//*************************************************************
LocateXY();
//************************************************************
if(KeyValue)
{
if(KeyValue < 5) //当执行光标移动工作时,要把原来的光标显示清除
{
Show[Dis_num] = Show_Temp[Dis_num];
}
switch(KeyValue)
{
case 1: Pos_x++;
if(Pos_x >= 16)
{ Pos_x = 0; }
break;
case 2: if(Pos_x == 0)
{ Pos_x = 15; }
else
Pos_x--;
break;
case 3: Pos_y++;
if(Pos_y >= 16)
{ Pos_y = 0; }
break;
case 4: if(Pos_y == 0)
{ Pos_y = 15; }
else
Pos_y--;
break;
case 5: if(Show[Dis_num] != Show_Temp[Dis_num]) //当坐标值不相等时(即原来没有置1)置1
{
if(Pos_x < 8)
Show[Dis_num] |= (0x80>>Pos_x);
else
Show[Dis_num] |= (0x80>>(Pos_x-8));
}
else //清0
{
if(Pos_x < 8)
Show[Dis_num] &= (0x7F>>Pos_x);
else
Show[Dis_num] &= (0x7F>>(Pos_x-8));
}
Show_Temp[Dis_num] = Show[Dis_num]; //一定要保存当前值
break;
}
KeyValue = 0;
}
}
/*
void LED_Dis_8(unsigned char LED_Num,unsigned char *Word)
{
unsigned char row;
LED_Num = LED_Num<<3;
for(row=0; row<8; row++)
{
P2 = LED_Num|row;
HC595_SendDat(Word[row]);
Delay_1ms(1);
}
}
*/
/*
void LED_Dis_16(unsigned char *Word) //16*16点阵的显示,没用到定时中断,用延时
{
unsigned char i = 0;
unsigned char row;
row = 0 ;
for(i=0; i<=7; i++) //显示第1个点阵
{
P2 = i;
HC595_SendDat(Word[row]);
row = row+2;
Delay_1ms(1);
}
row = 1;
for(i=0; i<8; i++) //显示第2个点阵
{
P2 = (2<<3)|i;
HC595_SendDat(Word[row]);
row = row+2;
Delay_1ms(1);
}
row = 16;
for(i=0; i<8; i++) //显示第3个点阵
{
P2 = (1<<3)|i;
HC595_SendDat(Word[row]);
row = row+2;
Delay_1ms(1);
}
row = 17;
for(i=0; i<8; i++) //显示第4个点阵
{
P2 = (3<<3)|i;
HC595_SendDat(Word[row]);
row = row+2;
Delay_1ms(1);
}
}
*/
/*
void LED_Dis_16(unsigned char *Word)
{
unsigned char i = 0;
unsigned char row;
row = 0 ;
for(i=0; i<8; i++) //先显示上面2个点阵
{
P2 = (0<<3)|i;
HC595_SendDat(Word[row]);
row++;
Delay_1ms(1);
P2 = (2<<3)|i;
HC595_SendDat(Word[row]);
row++;
Delay_1ms(1);
}
for(i=0; i<8; i++) //再显示下面2个点阵
{
P2 = (1<<3)|i;
HC595_SendDat(Word[row]);
row ++;
Delay_1ms(1);
P2 = (3<<3)|i;
HC595_SendDat(Word[row]);
row ++;
Delay_1ms(1);
}
}
*/
/****************************************************************************
* 名称:LED_Display()
* 功能:可实现4个8*8点阵构成的16*16点阵的显示
* 入口参数:word 要显示的数组
* 说明:在定时中断0中每隔0.75ms调用一次
****************************************************************************/
unsigned char Couter_8 = 0;
unsigned char LED_Number = 0;
//=========================第二版本==============================================
unsigned char Show_Number = 0;
void LED_Display(unsigned char *Word)
{
Couter_8++;
Show_Number = Show_Number + 2; //加2是为了点阵间隔显示,由电路布局决定
if(Couter_8 >= 8)
{
Couter_8 = 0;
LED_Number++;
if(LED_Number >= 4)
{
LED_Number = 0;
}
switch(LED_Number) //主要是初始化Show_Number,以减少乘除或移位指令的使用
{
case 0:
Show_Number = 0;
break;
case 1:
Show_Number = 16;
break;
case 2:
Show_Number = 1;
break;
case 3:
Show_Number = 17;
break;
}
}
P2 = (LED_Number<<3)|Couter_8;
HC595_SendDat( Word[Show_Number] );
}
/****************************************************************************
* 名称:HC595_SendDat()
* 功能:向74HC595发送一字节数据
* 入口参数:dat 要发送的数据
* 说明:发送数据时,高位先发送。
****************************************************************************/
void HC595_SendDat(unsigned char dat)
{ char i;
SPI_CS = 0; // SPI_CS = 0
for(i=0; i<8; i++) // 发送8位数据
{ SPI_CLK = 0; // SPI_CLK = 0
/* 设置SPI的DATA输出值 */
if( (dat&0x80)!=0 )
SPI_DATA = 1;
else
SPI_DATA = 0;
dat <<= 1;
SPI_CLK = 1; // SPI_CLK = 1
}
SPI_CS = 1; // SPI_CS = 1,输出显示数据
}
/*
void Delay_1ms(int z)
{
int i,j;
for(i=0;i<z;i++)
for(j=0;j<80;j++);
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -