📄 彩灯串口通信.c
字号:
#include<reg52.h>
//初始化子程序
void UART_init();
void timer0_init();
//彩灯控制子程序
void LEDtest(movtime);
void LEDmtest();
void LEDbeg();
void LEDpause();
void LEDagain();
void LEDshop();
void clrtemp(); //清缓冲区
void mode_1(time_mod_1);
void mode_2(time_mod_2);
void mode_3(time_mod_3);
//串口接收信号变量
unsigned char temp[3];
unsigned char r_ready_glag;
unsigned char r_full; //缓冲区接收已满标志
unsigned char r_in; //缓冲区(3字节) 变量
unsigned char T0_temp; //计时器0的中间变量
//串口中断子程序
com_interrupt() interrupt 4 using 3
{
if(RI&&~r_full)
{
temp[r_in]=SBUF; //读取寄存器的值
RI=0;
r_in++;
if(r_in==3)
{
r_full=1;
//ES=0;
r_in=0;
r_ready_glag=1; //接收完毕,标志位置1
}
//r_ready_glag=1;
}
}
main()
{
UART_init();
timer0_init();
P0=0;
while(1)
{
while(r_ready_glag==1)
{
r_full=0;
r_ready_glag=0;
switch(temp[0]) //判断接收到的信号,执行对应的程序
{
case 0x01: { LEDtest(5); clrtemp();} break; //自动测试
case 0x02: { LEDmtest(); } break; //手动选择测试
case 0x03: { LEDbeg(); }break;
case 0x04: { LEDpause(); }break;
case 0x05: { LEDagain(); }break;
case 0x06: { LEDshop(); clrtemp(); }break;
default: break;
}
}
}
}
void UART_init()
{
SCON=0x50; // 工作方式1
// TMOD=0x20; //T1 方式2 自动装初值
TMOD=(TMOD&0x0f)|0x20;
PCON=0x80; ///倍速
TH1=0xf3;TL1=0xf3; //TH1= 252 (fosc=12MHz 4800
//ET1=0; ??
ET1=1; //允许T1中断
TR1=1; //启动T1中断
//ES=0;
ES=1; // 允许串口中断
PS=1; // 串口高优先级
PT1=0; //计时器1 低优先级
EA=1; //CPU允许中断
}
void timer0_init() // 方式1 fosc=12Mhz 定时最大65536*1us=65.536ms 50ms定时 初值 TH=3CH TL=B0h
{
TMOD=(TMOD&0xf0)|0x01;
TH0=0x3c; //TH0=(65536-50000)/256
TL0=0xb0; //TL0=(65536-50000)%256
ET0=1; //允许中断
TR0=0; //暂时不启动中断
PT0=0; //低优先级
EA=1; //允许全部中断
}
void timer0() interrupt 1
{
T0_temp++;
TH0=0x3c;
TL0=0xB0;
}
void LEDtest(movtime) //LED测试子程序 ,VB中测试按钮按下是调用
{
unsigned int i=0;
unsigned char buf;
unsigned char mt;
mt=movtime;
TR0=1;
ET0=1;
buf=0x80;
for(i=1;i<=8;i++)
{
//P0=PO>>i;// 口不能直接移位
P0=buf;
buf=buf>>1;
do{}while(T0_temp!=mt);
T0_temp=0;
}
buf=0x01;
for(i=1;i<=8;i++)
{
//P0=PO>>i;// 口不能直接移位
P0=buf;
buf=buf<<1;
do{}while(T0_temp!=mt);
T0_temp=0;
}
P0=0xff;
for(i=0;i<=4;i++)
{
P0=~P0;
do{}while(T0_temp!=mt);
T0_temp=0;
}
TR0=0; //关闭定时器
}
void LEDmtest() //LED的手动测试子程序
{
P0=temp[1];
}
void LEDbeg()
{
while(r_ready_glag==0)
{
switch(temp[1])
{
case 0x81: { mode_1(temp[2]);} break;
case 0x82: { mode_2(temp[2]);} break;
case 0x83: { mode_3(temp[2]);} break;
// case 0x84: { mode_4(temp[2]);} break;
default: break;
}
}
}
void mode_1(time_mod) //LED测试子程序 ,VB中测试按钮按下是调用
{
unsigned int i=0;
unsigned char buf;
unsigned char mt;
mt=time_mod*2+2;
TR0=1;
ET0=1;
buf=0xc0;
for(i=1;i<=8;i++)
{
//P0=PO>>i;// 口不能直接移位
P0=buf;
buf=buf>>2;
do{}while(T0_temp!=mt);
T0_temp=0;
}
buf=0x03;
for(i=1;i<=8;i++)
{
//P0=PO>>i;// 口不能直接移位
P0=buf;
buf=buf<<2;
do{}while(T0_temp!=mt);
T0_temp=0;
}
TR0=0; //关闭定时器
}
void mode_2(time_mod)
{
unsigned char mt;
mt=time_mod*2+2;
TR0=1;
ET0=1;
P0=0xaa;
do{}while(T0_temp!=mt);
T0_temp=0;
P0=0x55;
do{}while(T0_temp!=mt);
T0_temp=0;
TR0=0; //关闭定时器
}
void mode_3(time_mod)
{
unsigned char mt;
mt=time_mod*2+2;
TR0=1;
ET0=1;
P0=0xaa;
do{}while(T0_temp!=mt);
T0_temp=0;
P0=0x55;
do{}while(T0_temp!=mt);
T0_temp=0;
TR0=0; //关闭定时器
}
void LEDpause()
{
//TR0=0;
ET0=0;
}
void LEDagain()
{
// TR0=1;
ET0=1;
}
void LEDshop()
{
P0=0;
}
//清空缓冲区子程序
void clrtemp()
{
temp[0]=0;
temp[1]=0;
temp[2]=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -