#include<reg2051.h> #define uchar unsigned char #define uint unsigned int #define DmxCH 3 bit DMX_SIGN;// 允许接收起始代码 bit CHK_SIGN;// 允许接收起始代码 bit DATA_Flag=0; //bit flag2=0; uint ADDR_CON,RECDAT,READDSS; uchar Dmxdat[DmxCH]; uchar databuff; bit FLASH_flag=0; uchar red,green,bule,lightness=0; sbit r=P1^5; sbit g=P1^6; sbit b=P1^7; /*************************************/ sbit scl=P3^4;//I2C时钟线 sbit sda=P3^5;//I2C数据线 //sbit flag=P1^7; void DELAY_NOP() //延时5us { uchar a,i; for(i=0;i<10;i++) { a--;a--; } } void DELAY(uchar x) { uchar y; for(;x>0;x--) for(y=200;y>0;y--); } void START() //启动总线 { scl=0; sda=1; DELAY_NOP(); scl=1; DELAY_NOP(); sda=0; DELAY_NOP(); scl=0; DELAY_NOP(); } void STOP()//停止总线 { scl=0; sda=0; scl=1; DELAY_NOP(); sda=1; DELAY_NOP(); } void ACK() //应答子函数 { uchar i; scl=1; sda=1; for(i=0;i<200;i++) { if(sda==0) { i=200; } } scl=0; DELAY_NOP(); } void fasong8bit(uchar x)//主机发送8位数据 { uchar i; for(i=0;i<8;i++) { scl=0; if((x&0x80)==0)//要发送的位0 { sda=0; } else { sda=1; } scl=1; x<<=1; DELAY_NOP(); } scl=0; } uchar readbyte()//读出一个字节 { uchar i,x; for(i=0;i<8;i++) { x<<=1; scl=1; DELAY_NOP(); if(sda==1)//如果接收的位是1 { x|=0x01; } else { x|=0x00; } scl=0; } scl=1; return x; } void dingdizhixie(uchar x,y)//指定地址存储 { START(); fasong8bit(0xa0);//写 ACK(); fasong8bit(x);//把数据存入45号存储单元 ACK(); fasong8bit(y);//把要存的数据写入 ACK(); STOP(); } uchar dingdizhidu(uchar x)//指定地址读取 { uchar n; START(); fasong8bit(0xa0); ACK(); fasong8bit(x); ACK(); START(); fasong8bit(0xa1);//读 ACK(); n=readbyte(); ACK(); STOP(); return n; } /*************************************/ void init_serial(void) { TMOD = 0x20; SCON = 0x90; TI = 0; } void pwm() { if(lightness>0) { if(red>0){r=1;red--;}else{r=0;} if(green>0){g=1;green--;}else{g=0;} if(bule>0){b=1;bule--;}else{b=0;} lightness--; } else { lightness=255; red=Dmxdat[0]; green=Dmxdat[1]; bule=Dmxdat[2]; } } void main() { init_serial(); READDSS=dingdizhidu(54); EA=1; ES=1; while(1) { if(FLASH_flag==1) { b=1; b=0; } else { b=0; } g=0; if(DATA_Flag==0) { pwm(); } } } void Serial() interrupt 4 using 2 { databuff=SBUF; RI=0; if(RB8==0) // RB8=0,SBUF=0;复位信号 { CHK_SIGN=0; // 允许接收起始代码 if(databuff==0) // 判断是否收到复位信号,是(SUBF=0),否(SUBF=!0) { DMX_SIGN=0; // 允许接收起始代码 ADDR_CON=0; // 地址号计数器 RECDAT=0; // 数据接收控制 return; } else if(databuff==0xAA) { FLASH_flag=1;//写地址中断处理标志位 return; } else { DMX_SIGN=1; // 暂停接收起始代码 return; } } else { if(FLASH_flag) { READDSS=databuff; dingdizhixie(54,READDSS); DELAY(10); READDSS=dingdizhidu(54); FLASH_flag=0; return; } if(CHK_SIGN==0) // RB8=1,SBUF=0。起始帧 { if (DMX_SIGN==0) { DMX_SIGN=1; if(databuff==0)// 判断是否起始代码 { CHK_SIGN=1; // 接下来开始接收数据 DATA_Flag=1; return; // 收到起始代码而退出中断 } } return; // 没有接收到起始代码而退出中断 } if(CHK_SIGN==1) // RB8=1,接收数据 { ADDR_CON++; // 地址号计数器加1 if(ADDR_CON >= READDSS) // 判断当前地址号计数器是否属于本机地址 { Dmxdat[RECDAT]=SBUF; // 接收数据 RECDAT++; // 下一个数据 if(RECDAT >= DmxCH) // 判断是否到本机的最后一个通道地址(这里DmxCH=4) { CHK_SIGN=0; // 接收完本机所有通道数,则暂停,等待下一个复位 lightness=0; red=0; green=0; bule=0; DATA_Flag=0; return; } } return; } } } |