找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 304|回复: 1
打印 上一主题 下一主题
收起左侧

有没有DMX512协议解码的单片机程序?求分享

[复制链接]
跳转到指定楼层
#
ID:1130793 发表于 2024-8-22 10:16 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

楼主
ID:878061 发表于 2024-8-23 07:47 | 只看该作者
#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;                                                          }                                 } }
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表