基于51单片机372的USB通信代码

发布者:Joyful888Life最新更新时间:2017-11-08 来源: eefocus关键字:51单片机  USB通信 手机看文章 扫描二维码
随时随地手机看文章

#include
#include "INTRINS.h"



#define OP_CMD                  1                          // 命令操作码
#define OP_DATA                 0                          // 数据操作码
#define DELAY_TIMES             8                          // 延时2微秒
#define DELAY_CNT_NUMS          2*DELAY_TIMES                // 延时2微秒所需的时钟周期数(对于22.1184MHz晶振,每个微秒包含22.1184个时钟周期)
//#define MY_USB_VENDOR_ID  0x4348                     // USB设备制造商标识
//#define MY_USB_PRODUCT_ID  0x5537                     // USB设备产品标识


//sbit  USB_CS      =  P1^3;    //cs接地   内部晶振24.5M 倍频49M
sbit  USB_INT     =  P0^0;                                
sbit  USB_A0      =  P1^4;                                
sbit  USB_WR      =  P1^6;                                
sbit  USB_RD      =  P1^5;                                
//sfr   USB_DATA    =  0x84;                                
#define get_usb P2
#define set_usb(dat1) P2=dat1

//#define set_usb(dat1) P2|=(dat1>>1);P17=((dat1 & 0x01)==1)
#define delay_ns _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_()

const UINT8C MyDevDescr[] = { 0x12, 0x01, 0x10, 0x01,
        0xFF, 0x80, 0x37, 0x08,
        0x48, 0x43, 0x37, 0x55,  // 厂商ID和产品ID
        0x00, 0x01, 0x01, 0x02,
        0x00, 0x01 };
// 配置描述符
const UINT8C MyCfgDescr[] = { 0x09, 0x02, 0x27, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32,
         0x09, 0x04, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x37, 0x00,
         0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00,
         0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00,
         0x07, 0x05, 0x81, 0x03, 0x08, 0x00, 0x00 };
// 语言描述符
const UINT8C MyLangDescr[] = { 0x04, 0x03, 0x09, 0x04 };
// 厂家信息
const UINT8C MyManuInfo[] = { 0x0E, 0x03, 'w', 0, 'c', 0, 'h', 0, '.', 0, 'c', 0, 'n', 0 };
// 产品信息
const UINT8C MyProdInfo[] = { 0x0C, 0x03, 'C', 0, 'H', 0, '3', 0, '7', 0, '4', 0 };
UINT8 UsbConfig = 0;


void Delay2us( )
{
  INT8U i;

  i = (INT8U)DELAY_CNT_NUMS;
  while (--i);
}


void mDelaymS( INT8U ms )
{
   INT8U j;
 while ( ms -- ) {
 j=250;
  do
      { 
     Delay2us();
     Delay2us();
     //Delay2us();
     //Delay2us();    
   }
   while ( j -- );
 
 }
}



void CH375_WR_CMD_PORT(INT8U dat)
{
 
 
 
  USB_WR = 1;
  USB_RD = 1;
 
  set_usb(dat);
  delay_ns; 
  USB_A0 = OP_CMD;
                                          // 准备写命令
  _nop_();
 
  //USB_CS = 0;
  USB_WR = 0;
  USB_WR = 0;
  USB_WR = 0;
  USB_WR = 0;
 
  USB_WR = 1;
  //USB_CS = 1;                                             // 结束写命令(USB_WR信号的有效时间不能超过10us)
  USB_A0 = 0;
  P2=0xff;
  //P2|=0x7f;
  //P1|=0x80;
 
}


void CH375_WR_DAT_PORT(INT8U dat)
{
 
 
  USB_WR = 1;
  USB_RD = 1;
 
  set_usb(dat);
  delay_ns; 
  USB_A0 = OP_DATA;                                        // 准备写数据
  _nop_();
 
  //USB_CS = 0;
  USB_WR = 0;
  USB_WR = 0;                                              // 开始写数据
  USB_WR = 0;
  USB_WR = 0;
 
  USB_WR = 1;                                              // 结束写命令(USB_WR信号的有效时间不能超过10us)
  //USB_CS = 1;
  USB_A0 = 0;
  P2=0xff;
  //P2|=0x7f;
  //P1|=0x80;
}

INT8U CH375_RD_DAT_PORT(void)
{
  INT8U nData;
 
  USB_WR   = 1;
  USB_RD   = 1;
 
  delay_ns;
  //delay_ns;                                    // 将USB_DATA(P4口)配置为数字输入
  USB_A0 = OP_DATA;
  //USB_CS = 0;                                       // 准备读数据
  _nop_();
 
  USB_RD = 0;
  USB_RD = 0;
  USB_RD = 0;
 
  nData = get_usb;
 
  USB_RD = 1;                                              // 结束读命令(USB_RD信号的有效时间不能超过10us)
  //USB_CS = 1;
  USB_A0 = 0;
  return nData;                                            // 返回读取的数据
}

INT8U Read374Byte(INT8U mAddr ) 
{
 CH375_WR_CMD_PORT( mAddr );
 return( CH375_RD_DAT_PORT());
}

void Write374Byte( INT8U mAddr, INT8U mData ) 
{
 CH375_WR_CMD_PORT( mAddr );
 CH375_WR_DAT_PORT( mData );
}

void Read374Block( INT8U mAddr, INT8U mLen, INT8U * mBuf ) 
{
 CH375_WR_CMD_PORT( mAddr );
 while ( mLen -- ) *mBuf++ = CH375_RD_DAT_PORT( );
}

void Write374Block( INT8U mAddr, INT8U mLen, INT8U * mBuf )
{
   INT8U dat,k;
 k=0;
 CH375_WR_CMD_PORT( mAddr );
 while ( mLen -- )
       {
     dat= *mBuf++;
     //dat= up[k++];    
        CH375_WR_DAT_PORT(dat);    
    }
}

void write_buf1to374()
{
  INT8U dat,k,mLen;
  Write374Byte( REG_USB_LENGTH, 64 ); 
     //Write374Block( RAM_ENDP2_TRAN, 64, &up[0]);
  k=0;
  mLen=64;
  CH375_WR_CMD_PORT( RAM_ENDP2_TRAN );
  while ( mLen -- )
       {
     //dat= *mBuf++;
     dat= up[k++];    
        CH375_WR_DAT_PORT(dat);    
    }  
    // Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_RECV_TOG );
    Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) );

}

void write_buf2to374() 
{
   INT8U dat,k,mLen;
  Write374Byte( REG_USB_LENGTH, 64 ); 
     //Write374Block( RAM_ENDP2_TRAN, 64, &up[0]);
  k=0;
  mLen=64;
  CH375_WR_CMD_PORT( RAM_ENDP2_TRAN );
  while ( mLen -- )
       {
     //dat= *mBuf++;
     dat= up1[k++];    
        CH375_WR_DAT_PORT(dat);    
    }  
     //Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_RECV_TOG );
  Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) );

}

 


void CH375_Init(void)
{
     //INT8U m;
  //USB_CS=0;
  mDelaymS(100);
  //Write374Byte( REG_SYS_CTRL, BIT_CTRL_RESET_NOW );
  //mDelaymS(50);
  //Write374Byte( REG_SYS_CTRL, 0 );
  //m= Read374Byte(REG_USB_SETUP);
  //Write374Byte( REG_USB_SETUP, 0x03 );
  //m= Read374Byte(REG_USB_SETUP);

  //Write374Byte( REG_USB_SETUP, 0x00 );
     Write374Byte( REG_USB_ADDR, 0x00 );
  //m= Read374Byte(REG_USB_ADDR);
  Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) );               //清端点0控制寄存器
     Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( 0 ) );
     Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( 0 ) );
     Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG ); // 清所有中断标志
     Write374Byte( REG_INTER_EN, BIT_IE_TRANSFER | BIT_IE_BUS_RESET | BIT_IE_USB_SUSPEND );    // 允许使能传输完成中断和USB总线复位中断以及USB总线挂起中断,芯片唤醒完成中断
     //m= Read374Byte(REG_INTER_EN);
  Write374Byte( REG_SYS_CTRL, BIT_CTRL_OE_POLAR );                           // 对于CH374T或者UEN引脚悬空的CH374S必须置BIT_CTRL_OE_POLAR为1
     Write374Byte( REG_USB_SETUP, BIT_SETP_TRANS_EN | BIT_SETP_PULLUP_EN );     // 启动USB设备
  //m= Read374Byte(REG_USB_SETUP);  
  //m= Read374Byte(REG_USB_SETUP);
  //Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_RECV_TOG );
}


void CH375_process()
{
    UINT8 s, l;
 static UINT8 SetupReq, SetupLen;
 static PUINT8 pDescr;
   
  //static UINT8 SetupReq, SetupLen;
  //static PUINT8 pDescr;
  if (USB_INT)
      return;

    s = Read374Byte( REG_INTER_FLAG );
 
    if ( s & BIT_IF_BUS_RESET )
 {  // USB总线复位
    // Write374Byte( REG_USB_SETUP, 0x00 );
  Write374Byte( REG_USB_ADDR, 0x00 );  // 清USB设备地址
  Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) );
  Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( 0 ) );
  Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( 0 ) );
  Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_BUS_RESET );  // 清中断标志
 }
 else if ( s & BIT_IF_TRANSFER )
 {  // USB传输完成
  s = Read374Byte( REG_USB_STATUS );
 
  //Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER );  // 清中断标志
     switch( s & BIT_STAT_PID_ENDP ) {  // USB设备中断状态
  case USB_INT_EP2_OUT: {  // 批量端点下传成功
    //UINT8 buf[64];
    if ( s & BIT_STAT_TOG_MATCH )   // ljj@wch.cn
     {  // 仅同步包
     l = Read374Byte( REG_USB_LENGTH );
     Read374Block( RAM_ENDP2_RECV, l, &down[0] );
     if (down[l-1]==calc_sum(&down[0]))
                  pc_process();
     Write374Byte( REG_USB_ENDP2, Read374Byte( REG_USB_ENDP2 )^ BIT_EP2_RECV_TOG );
     //for ( s = 0; s < l; s ++ ) buf[s] ^= 0xFF;  // 数据取反由计算机验证
     //Write374Block( RAM_ENDP2_TRAN, l, buf );  // 演示回传
     //Write374Byte( REG_USB_LENGTH, l );
     //Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_RECV_TOG );
//     Write374Index( REG_USB_ENDP2 );  // 对于并口连接可以用本行及下面一行代替上一行的程序,减少写一次index的时间,提高效率
//     Write374Data( M_SET_EP2_TRAN_ACK( Read374Data0( ) ) ^ BIT_EP2_RECV_TOG );
     }
    break;
   }
   case USB_INT_EP2_IN: {  // 批量端点上传成功,未处理
       if (!bfree)
         bfree=1;
    Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_TRAN_TOG );
    //Write374Index( REG_USB_ENDP2 );  // 对于并口连接可以用本行及下面一行代替上一行的程序,减少写一次index的时间,提高效率
    //Write374Data( M_SET_EP2_TRAN_NAK( Read374Data0( ) ) ^ BIT_EP2_TRAN_TOG );
    break;
   }
   case USB_INT_EP1_IN: {  // 中断端点上传成功,未处理
    Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( Read374Byte( REG_USB_ENDP1 ) ) ^ BIT_EP1_TRAN_TOG );
    break;
   }
   case USB_INT_EP0_SETUP: {  // 控制传输
    USB_SETUP_REQ SetupReqBuf;
    l = Read374Byte( REG_USB_LENGTH );
    if ( l == sizeof( USB_SETUP_REQ ) ) {
     Read374Block( RAM_ENDP0_RECV, l, (PUINT8)&SetupReqBuf );
     SetupLen = SetupReqBuf.wLengthL;
     if ( SetupReqBuf.wLengthH || SetupLen > 0x7F ) SetupLen = 0x7F;  // 限制总长度
     l = 0;  // 默认为成功并且上传0长度
     if ( ( SetupReqBuf.bType & DEF_USB_REQ_TYPE ) != DEF_USB_REQ_STAND ) { 
      l = 0xFF;  // 操作失败
     }
     else {  // 标准请求
      SetupReq = SetupReqBuf.bReq;  // 请求码
      switch( SetupReq ) {
       case DEF_USB_GET_DESCR:
        switch( SetupReqBuf.wValueH ) {
         case 1:
          pDescr = (PUINT8)( &MyDevDescr[0] );
          l = sizeof( MyDevDescr );
          break;
         case 2:
          pDescr = (PUINT8)( &MyCfgDescr[0] );
          l = sizeof( MyCfgDescr );
          break;
         case 3:
          switch( SetupReqBuf.wValueL ) {
           case 1:
            pDescr = (PUINT8)( &MyManuInfo[0] );
            l = sizeof( MyManuInfo );
            break;
           case 2:
            pDescr = (PUINT8)( &MyProdInfo[0] );
            l = sizeof( MyProdInfo );
            break;
           case 0:
            pDescr = (PUINT8)( &MyLangDescr[0] );
            l = sizeof( MyLangDescr );
            break;
           default:
            l = 0xFF;  // 操作失败
            break;
          }
          break;
         default:
          l = 0xFF;  // 操作失败
          break;
        }
        if ( SetupLen > l ) SetupLen = l;  // 限制总长度
        l = SetupLen >= RAM_ENDP0_SIZE ? RAM_ENDP0_SIZE : SetupLen;  // 本次传输长度
        Write374Block( RAM_ENDP0_TRAN, l, pDescr ); 
        SetupLen -= l;
        pDescr += l;
        break;
       case DEF_USB_SET_ADDRESS:
        SetupLen = SetupReqBuf.wValueL;  // 暂存USB设备地址
        break;
       case DEF_USB_GET_CONFIG:
        Write374Byte( RAM_ENDP0_TRAN, UsbConfig );
        if ( SetupLen >= 1 ) l = 1;
        break;
       case DEF_USB_SET_CONFIG:
        UsbConfig = SetupReqBuf.wValueL;
        break;
       case DEF_USB_CLR_FEATURE:
        if ( ( SetupReqBuf.bType & 0x1F ) == 0x02 ) {  // 不是端点不支持
         switch( SetupReqBuf.wIndexL ) {
          case 0x82:
           Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read374Byte( REG_USB_ENDP2 ) ) );
           break;
          case 0x02:
           Write374Byte( REG_USB_ENDP2, M_SET_EP2_RECV_ACK( Read374Byte( REG_USB_ENDP2 ) ) );
           break;
          case 0x81:
           Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( Read374Byte( REG_USB_ENDP1 ) ) );
           break;
          case 0x01:
           Write374Byte( REG_USB_ENDP1, M_SET_EP1_RECV_ACK( Read374Byte( REG_USB_ENDP1 ) ) );
           break;
          default:
           l = 0xFF;  // 操作失败
           break;
         }
        }
        else l = 0xFF;  // 操作失败
        break;
       case DEF_USB_GET_INTERF:
        Write374Byte( RAM_ENDP0_TRAN, 0 );
        if ( SetupLen >= 1 ) l = 1;
        break;
       case DEF_USB_GET_STATUS:
        Write374Byte( RAM_ENDP0_TRAN, 0 );
        Write374Byte( RAM_ENDP0_TRAN + 1, 0 );
        if ( SetupLen >= 2 ) l = 2;
        else l = SetupLen;
        break;
       default:
        l = 0xFF;  // 操作失败
        break;
      }
     }
    }
    else l = 0xFF;  // 操作失败
    if ( l == 0xFF ) {  // 操作失败
     Write374Byte( REG_USB_ENDP0, M_SET_EP0_RECV_STA( M_SET_EP0_TRAN_STA( 0 ) ) );  // STALL
    }
    else if ( l <= RAM_ENDP0_SIZE ) {  // 上传数据
     Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 ) ), l ) | BIT_EP0_TRAN_TOG );  // DATA1
    }
    else {  // 下传数据或其它
     Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 ) ) ) | BIT_EP0_RECV_TOG );  // DATA1
    }
    break;
   }
   case USB_INT_EP0_IN: {
    switch( SetupReq ) {
     case DEF_USB_GET_DESCR:
      l = SetupLen >= RAM_ENDP0_SIZE ? RAM_ENDP0_SIZE : SetupLen;  // 本次传输长度
      Write374Block( RAM_ENDP0_TRAN, l, pDescr ); 
      SetupLen -= l;
      pDescr += l;
      Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( Read374Byte( REG_USB_ENDP0 ), l ) ^ BIT_EP0_TRAN_TOG );
      break;
     case DEF_USB_SET_ADDRESS:
      Write374Byte( REG_USB_ADDR, SetupLen );
     default:
      Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) );  // 结束
      break;
    }
    break;
   }
   case USB_INT_EP0_OUT: {
    switch( SetupReq ) {
//     case download:
//      get_data;
//      break;
     case DEF_USB_GET_DESCR:
     default:
      Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) );  // 结束
      break;
    }
    break;
   }
   default: {
    break;
   }
  }
  Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER ); 
 }
 else if ( s & BIT_IF_USB_SUSPEND ) {  // USB总线挂起
  Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_USB_SUSPEND );  // 清中断标志
  Write374Byte( REG_SYS_CTRL, Read374Byte( REG_SYS_CTRL ) | BIT_CTRL_OSCIL_OFF );  // 时钟振荡器停止振荡,进入睡眠状态
 }
 else if ( s & BIT_IF_WAKE_UP ) {  // 芯片唤醒完成
  Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_WAKE_UP );  // 清中断标志
 }
 else {  // 意外的中断,不可能发生的情况,除了硬件损坏
  Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG );  // 清中断标志
 }

 
}


关键字:51单片机  USB通信 引用地址:基于51单片机372的USB通信代码

上一篇:C8051F020 AD转换和USB通信
下一篇:AT89C52控制温度传感器DS18B20并在LM016L_LCD上显示

推荐阅读最新更新时间:2024-03-16 15:43

基于51单片机ADC0808自动数字电压表数码管显示
硬件设计 该设计是基于51单片机,ADC采用TI公司的ADC0808,自动数字电压测量表,显示器采用4位数码管,测量范围为0.5~10V,精度约为0.02。 仿真图如下: 程序源码: #include reg52.h unsigned char code dispbitcode ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; unsigned char dispbuf ; unsigned int i; unsigned int j; unsigned int getdata; unsigned int temp; unsigned int temp1;
[单片机]
基于<font color='red'>51单片机</font>ADC0808自动数字电压表数码管显示
格雷码转换为二进制码_51单片机汇编语言子程序
卡诺图是组合逻辑电路设计和分析最常用和有效的数学工具, 格雷码是特点是任意两相邻代码之间只有一位数不同,其余各位均相同,正好和卡诺图循环邻接特点一致。 格雷码转换为二进制码的51单片机汇编语言子程序如下: ;;入口:8位格雷码存于累加器A, ;;返回值:转换所得8位二进制码仍存于累加器A。 GtoB: MOV R5, #8 ;;R5←循环次数 MOV 22H, A ;;原格雷码送至RAM的22H单元暂存 LP1: RLC A ;;A带进位左移 MOV 23H, A ;;RAM的23H单元←(A) MOV A, 22H ;;A←(22H)
[单片机]
格雷码转换为二进制码_<font color='red'>51单片机</font>汇编语言子程序
构造一个51单片机的实时操作系统的方法
目前,大多数的产品开发是在基于一些小容量的单片机上进行的。51系列单片机,是我目前使用最多的单片机系列之一,有非常广大的应用环境与前景,多年来的资源积累,使51系列单片机仍是许多开发者的首选。针对这种情况,近几年涌现出许多基于51内核的扩展芯片,功能越来越齐全,速度越来越快,也从一个侧面说明了51系列单片机在国内的生命力。 多年来我们一直想找一个合适的实时操作系统,作为自己的开发基础。根据开发需求,整合一些常用的嵌入式构件,以节约开发时间,尽最大可能地减少开发工作量;另外,要求这个实时操作系统能非常容易地嵌入到小容量的芯片中。毕竟,大系统是少数的,而小应用是多数而广泛的。显而易见,μC/OS—II是不太适合于以上要求的,而Keil
[单片机]
基于8051单片机的频率测量技术
0引言 随着无线电技术的发展与普及,"频率"已经成为广大群众所熟悉的物理量。而单片机的出现,更是对包括测频在内的各种测量技术带来了许多重大的飞跃,然而,小体积、价廉、功能强等优势也在电子领域占有非常重要的地位。为此.本文给出了一种以单片机为核心的频率测量系统的设计方法。 1 测频系统的硬件结构 测量频率的方法一般分为无源测频法、有源测频法及电子计数法三种。无源测频法(又可分为谐振法和电桥法),常用于频率粗测,精度在1%左右。有源比较法可分为拍频法和差频法,前者是利用两个信号线性叠加以产生拍频现象,再通过检测零拍现象进行测频,常用于低频测量,误差在零点几Hz;后者则利用两个非线性信号叠加来产生差频现象,然后通过检测零差现象进行
[单片机]
基于80<font color='red'>51单片机</font>的频率测量技术
51单片机实验3:led流水灯
开发板led模块电路图如下: 循环左/右移函数头文件为 intrins.h #include reg52.h #include intrins.h #define uc unsigned char void delay(uc n) { uc i,j; for(i=1;i =n;i++) for(j=110;j =1;j--); } void main() { P2=0xFE; while(1) { delay(200); p2=_crol_(P2,1); delay(200); } }
[单片机]
<font color='red'>51单片机</font>实验3:led流水灯
51单片机汇编语言实验(六)-----8255键盘与显示设计
一、实验目的:    掌握8255外接键盘与数码管显示的设计 二、实验设备:    PC计算机一台,Dais-52PRO+实验系统一套。 三、实验内容:    8255键盘与显示设计 四、 8255键盘与显示设计    1、实验原理:    本实验使用8255的PA7到PA0控制数码管字形口、PB5到PB0控制数码管字位口,同时PB4到PB0作为键盘扫描口、PC3~PC0作为键盘读入口。利用CPU控制8255,对4×5键盘进行扫描和键值读取,将键值显示到6位数码管上。本文介绍的是简化版的实验,不控制最后一列键盘,数码管位选端不接线,直接点亮。    2、实验步骤:   ① 按下图拆除14芯扁平电缆;   ②将8
[单片机]
<font color='red'>51单片机</font>汇编语言实验(六)-----8255键盘与显示设计
51单片机实验板DS18B20测温程序
/*********************************************** ** 实验名:51单片机实验板温度测量(DS18B20) ** 创建人: 谢军洋 ** 描 述:P3.7口输入,输出数据。 **------------------------------------------------------------------ ** CPU:MCS-51 ** 语言:汇编 ** Fosc=12M 此次试验的仿真图 ***************************************************/ GE_BIT EQU 30H SHI_BIT EQU 31H BAI_BI
[单片机]
<font color='red'>51单片机</font>实验板DS18B20测温程序
51单片机-IIC入门代码讲解
因IIC时序细节的理解不是一两篇文章就能描写清楚的,这里笔者只针对《手把手教你学51单片机》文档第14章内容做补充辅助理解,如果大家想彻底弄明白IIC的所有通信细节过程,那么就需要“好事多磨”了。 我们现在先贴出IIC的时序流程图 1.起始信号函数 我们同样是运用宋老师的代码,这里笔者把代码和截图一起呈现出来让大家能够一句句地去理解含义,打开宋老师的代码lesson14_1。 void I2CStart() //产生总线起始信号 { I2C_SDA = 1; //首先确保SDA、SCL都是高电平 I2C_SCL = 1; I2CDelay(); //延时几微秒 I2C_SDA = 0; //先拉低SD
[单片机]
<font color='red'>51单片机</font>-IIC入门代码讲解
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved