#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; } } } |