金沙滩单片机完成通过串口控制流水灯的流动和停止

#include 
#include 
sbit LED = P0^0;
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

unsigned char T0RH = 0;  //T0重载值的高字节
unsigned char T0RL = 0;  //T0重载值的低字节
unsigned char RxdByte = 0;  //串口接收到的字节
unsigned char flag1s = 0;  //1秒定时标志
unsigned int cnt = 0;  //记录T0中断次数

void ConfigTimer0(unsigned int ms);
void ConfigUART(unsigned int baud);
void WaterLamp();
void main()
{
    EA = 1;       //使能总中断
    ENLED = 0;    //流水灯
	ADDR3 = 1;
	ADDR2 = 1;
	ADDR1 = 1;
	ADDR0 = 0;
    ConfigTimer0(1);   //配置T0定时1ms
    ConfigUART(9600);  //配置波特率为9600
	while(1) {
	    if (RxdByte == 0X18) {
		    WaterLamp();
		} else {
			P0 = 0XFF;
		}
	}
	return;
}

void WaterLamp()
{
	    static unsigned char dir = 0;   //定义移位方向变量dir,用于控制移位的方向
	    static unsigned char shift = 0x01;  //定义循环移位变量shift,并赋初值0x01
		P0 = ~shift;       //P0等于循环移位变量取反,控制8个LED
	
		if (flag1s == 1)  //判断1秒定时标志
	    {
	        flag1s = 0;   //1秒定时标志清零
		    if (dir == 0) {           //移位方向变量为0时,左移
	        shift = shift << 1;  //循环移位变量左移1位
	        if (shift == 0x80) {  //左移到最左端后,改变移位方向
	            dir = 1;
	        }
	    } else {   //移位方向变量不为0时,右移               
	        shift = shift >> 1;  //循环移位变量右移1位
	        if (shift == 0x01) {   //右移到最右端后,改变移位方向
	            dir = 0;
	            }
	        }	
		}
}
/* 配置并启动T0,ms-T0定时时间 */
void ConfigTimer0(unsigned int ms)
{
    unsigned long tmp;  //临时变量
    
    tmp = 11059200 / 12;      //定时器计数频率
    tmp = (tmp * ms) / 1000;  //计算所需的计数值
    tmp = 65536 - tmp;        //计算定时器重载值
    tmp = tmp + 13;           //补偿中断响应延时造成的误差
    T0RH = (unsigned char)(tmp>>8);  //定时器重载值拆分为高低字节
    T0RL = (unsigned char)tmp;
    TMOD &= 0xF0;   //清零T0的控制位
    TMOD |= 0x01;   //配置T0为模式1
    TH0 = T0RH;     //加载T0重载值
    TL0 = T0RL;
    ET0 = 1;        //使能T0中断
    TR0 = 1;        //启动T0
}

/* 串口配置函数,baud-通信波特率 */
void ConfigUART(unsigned int baud)
{
    SCON  = 0x50;  //配置串口为模式1
    TMOD &= 0x0F;  //清零T1的控制位
    TMOD |= 0x20;  //配置T1为模式2
    TH1 = 256 - (11059200/12/32)/baud;  //计算T1重载值
    TL1 = TH1;     //初值等于重载值
    ET1 = 0;       //禁止T1中断
    ES  = 1;       //使能串口中断
    TR1 = 1;       //启动T1
}

void InterruptTimer0() interrupt 1
{
    TH0 = T0RH;  //重新加载重载值
    TL0 = T0RL;
	cnt++;       //中断次数计数值加1
    if (cnt >= 1000)  //中断1000次即1秒
    {
        cnt = 0;      //清零计数值以重新开始下1秒计时
        flag1s = 1;   //设置1秒定时标志为1
    }
}

/* UART中断服务函数 */
void InterruptUART() interrupt 4
{
    if (RI)  //接收到字节
    {
        RI = 0;  //手动清零接收中断标志位
        RxdByte = SBUF;  //接收到的数据保存到接收字节变量中
        SBUF = RxdByte;  //接收到的数据又直接发回,叫作-"echo",
                         //用以提示用户输入的信息是否已正确接收
    }
    if (TI)  //字节发送完毕
    {
        TI = 0;  //手动清零发送中断标志位
    }
}

你可能感兴趣的:(51单片机)