📄 show.c
字号:
#include <reg51.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
//1 端口定义
sbit KEY=P1^3;
sbit SPEAKER=P1^4;
sbit DS=P1^5;
sbit ST_CP=P1^6;
sbit SH_CP=P1^7;
//1 函数原形声明
void shiftClock(void);
void strobeClock(void);
void shift74HC595(void);
void pushBuff(uchar c);
void powerUpInit(void);
void buffInit(void);
uchar getchar(void);
void delay1ms(uint n);
void reset(void);
//1全局变量声明
#define LED_NUMS 48 //LED数
#define BUFF_SIZE 16 //接收串口数据的缓冲区大小
#define OFF 0
#define ON 1
#define LIGHT 1
#define START 0
#define STOP 1
uchar overTimeErr;
uchar buffcnt;
uchar buffer[BUFF_SIZE];
uchar *inpt,*outpt;
uint WDT;
uchar user[LED_NUMS/8];
uchar code mask[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
bit spkCtlr;
/************************************************************
功能:系统主程序,上电复位入口
入口:无
出口:无
************************************************************/
void main(void)
{
powerUpInit();
while (1)
{
WDT=0;
shift74HC595();
}
}
/************************************************************
功能:串行移位8x32=256,执行时间11.8ms
入口:无
出口:无
************************************************************/
void shift74HC595(void)
{
uchar locate;
uchar i;
uchar lightCount=0;
//2 统计LED亮的个数
for (i=0; i<LED_NUMS; i++)
{
if (user[i /8] & mask[i % 8])
lightCount++;
}
//2 大于5个LED亮,轮闪
if (lightCount > 5)
{
i=LED_NUMS-1;
locate=LED_NUMS-1;
while (lightCount-- != 0)
{
i=LED_NUMS-1;
while (locate < i)
{
DS=!LIGHT;
shiftClock();
i--;
}
do
{
if ((user[i / 8] & mask[i % 8]) != 0)
{
locate=i;
locate--;
DS=LIGHT;
shiftClock();
while (i-- != 0)
{
DS=!LIGHT;
shiftClock();
}
break;
}
else
{
DS=!LIGHT;
shiftClock();
}
}while (i-- != 0);
strobeClock();
delay1ms(500);
}
}
//2 小于5个LED亮,同时亮
else
{
i=LED_NUMS-1;
do
{
DS=user[i / 8] & mask[i % 8];
shiftClock();
}while (i-- != 0);
strobeClock();
}
}
/************************************************************
功能:提供一个74HC595的移位脉冲
入口:无
出口:无
************************************************************/
void shiftClock(void)
{
SH_CP=START;
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
SH_CP=STOP;
}
/************************************************************
功能:提供一个74HC595的选通脉冲
入口:无
出口:无
************************************************************/
void strobeClock(void)
{
ST_CP=START;
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
ST_CP=STOP;
}
/************************************************************
功能:放一个字符到键盘输入缓冲区
入口:c=要放到缓冲区的字符
出口:无
************************************************************/
void pushBuff(uchar c)
{
if (buffcnt < BUFF_SIZE) // If buffer not full
{
*inpt = c; // Put character into buffer
inpt++; // Increment pointer
buffcnt++;
if (inpt >= buffer + BUFF_SIZE)// Pointer wrapping
inpt = buffer;
}
}
/***********************************
功能:上电初始化程序
入口:无
出口:无
************************************/
void powerUpInit(void)
{
// TH1=0xdc;TL1=0x00; //重装10ms时常
// TH0=0xb8;TL0=0x00; //重装20ms时常
// EX0=ET1=ET0=PX0=1;
// TR0=TR1=IT0=1;
spkCtlr=OFF;
TH0=TL0=0x1a; //250us
TH1=TL1=0xfd; //定时器1:9600bps发生器
TMOD=0x22;
SCON=0x50; //8位UART,允许接收
EA=ES=ET0=1;
TR1=TR0=1;
buffInit();
shiftClock();
strobeClock();
}
/***********************************
功能:键盘初始化程序
入口:无
出口:无
************************************/
void buffInit(void)
{
inpt = buffer; // Initialize buffer
outpt = buffer;
buffcnt = 0;
overTimeErr = 0;
}
/************************************************************
功能:等待从键盘输入按键
入口:无
出口:得到的一个键
************************************************************/
uchar getchar(void)
{
uchar byte;
#if 0
while(buffcnt == 0); // Wait for data
#else
if (buffcnt == 0)
return(0);
#endif
byte = *outpt; // Get byte
outpt++; // Increment pointer
if (outpt >= buffer + BUFF_SIZE)// Pointer wrapping
outpt = buffer;
buffcnt--; //Decrement buffer count
return(byte);
}
/*****************************************************
功能:延时nx1ms子程序 晶振4MHz
入口:n
*****************************************************/
void delay1ms(uint n)
{
uchar i;
while(n--)
{
WDT=0;
i=104;
while(--i);
}
}
/***********************************
功能:外部中断0中断服务程序
入口:无
出口:无
************************************/
void int0(void) interrupt 0
{
}
/***********************************
功能:定时器0中断服务程序
入口:无
出口:无
FOSC=11.0592MHZ 定时周期=250us
************************************/
void timer0(void) interrupt 1 //定时器0中断
{
if (overTimeErr != 0)
{
if (--overTimeErr == 0)
buffInit();
}
if (++WDT > 20000)
reset();
if (!KEY)
spkCtlr=OFF;
SPEAKER=spkCtlr;
}
/***********************************
功能:外部中断1中断服务程序
入口:无
出口:无
************************************/
void int1(void) interrupt 2
{
}
/***********************************
功能:定时器1中断服务程序
入口:无
出口:无
FOSC=11.0592MHZ 定时周期=10ms
************************************/
void timer1(void) interrupt 3
{
}
/***********************************
功能:串口中断服务程序
入口:无
出口:无
命令码:
0x7ca5:关警笛
0x7c55:响警笛
0x7dxx:布防 xx对应相应防区,为0xff时表示全部
0x7exx:撤防
0x7fxx:报警
************************************/
void sio(void) interrupt 4
{
uint cmd;
uchar tmp;
if (RI)
{
overTimeErr=80; //250x80=20ms
pushBuff(SBUF);
RI=0;
}
if (buffcnt >= 2)
{
cmd=(getchar() << 8) + getchar();
if (cmd == 0x7ca5) //关警笛
spkCtlr=OFF;
else if (cmd == 0x7c55) //响警笛
spkCtlr=ON;
else if ((cmd >> 8) == 0x7d) //点亮该用户号批示灯
{
spkCtlr=ON;
tmp=cmd & 0x00ff;
if (tmp == 0xff)
{
for (tmp=0; tmp < LED_NUMS/8; tmp++)
user[tmp]=0xff;
}
else
{
tmp--;
user[tmp / 8] |= mask[tmp % 8];
}
}
else if ((cmd >> 8) == 0x7e) //关闭该用户号批示灯
{
spkCtlr=OFF;
tmp=cmd & 0x00ff;
if (tmp == 0xff)
{
for (tmp=0; tmp < LED_NUMS/8; tmp++)
user[tmp]=0x00;
}
else
{
tmp--;
user[tmp / 8] &= ~mask[tmp % 8];
}
}
else
buffInit();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -