STM32F103VET6+DM9000调试日志

        记录基于stm32f103vet6调试工作。

        调试工程是在正点原子网络通信实验上做的修改,该例程使用的是stm32f103zet6主控,144pin。

        主要修改为FSMC总线的管脚重定义,按照硬件给的原理图对照着来就行,需要注意的是例程里使用的是NE2,而我们使用的主控是没有这的,只能使用NE1,在初始化的时候注意使用BANK1NE1。例程使用的是FSMC_A7,我们主控同样没有这个定义,只能用FSMC_A16或者FSMC_A17,我们使用的是FSMC_A17,所以在操作总线的基地址要按照规则做修改。


//初始化DM9000
//返回值:
//0,初始化成功
//1,DM9000A ID读取错误
u8 DM9000_Init(void)
{
    u32 temp;
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
    FSMC_NORSRAMTimingInitTypeDef ReadWriteTiming;  //DM9000的读写时序

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE,ENABLE);  //使能GPIOD E 时钟
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);   //使能FSMC时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;       //PD2 推挽输出  reset
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
    GPIO_Init(GPIOD,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;       //PC6 推挽输出 int
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   //上拉输入
    GPIO_Init(GPIOC,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | // FSMC_D0
                                  GPIO_Pin_15 | // FSMC_D1
                                  GPIO_Pin_0 | // FSMC_D2
                                  GPIO_Pin_1 | // FSMC_D3
                                  GPIO_Pin_8 | // FSMC_D13
                                  GPIO_Pin_9 | // FSMC_D14
                                  GPIO_Pin_10 ; // FSMC_D15
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
    GPIO_Init(GPIOD,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | // FSMC_D4
                                  GPIO_Pin_8 | // FSMC_D5
                                  GPIO_Pin_9 | // FSMC_D6
                                  GPIO_Pin_10 | // FSMC_D7
                                  GPIO_Pin_11 | // FSMC_D8
                                  GPIO_Pin_12 | // FSMC_D9
                                  GPIO_Pin_13 | // FSMC_D10
                                  GPIO_Pin_14 | // FSMC_D11
                                  GPIO_Pin_15 ; // FSMC_D12
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
    GPIO_Init(GPIOE,&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;      //PD12复用 CMD
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
    GPIO_Init(GPIOD,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;       //PD7复用 NE1
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
    GPIO_Init(GPIOD,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;       //PD4复用 FSMC_NOE
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
    GPIO_Init(GPIOD,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;       //PD5复用 FSMC_NWE
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
    GPIO_Init(GPIOD,&GPIO_InitStructure);


    //PG6外部中断,中断线6
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource6);

    EXTI_InitStructure.EXTI_Line = EXTI_Line6;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    EXTI_ClearITPendingBit(EXTI_Line6); //清除中断线6挂起标志位

    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;          //外部中断线6
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   //抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;          //子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    ReadWriteTiming.FSMC_AddressSetupTime = 0;      //地址建立时间
    ReadWriteTiming.FSMC_AddressHoldTime = 0;
    ReadWriteTiming.FSMC_DataSetupTime = 3;     //数据建立时间
    ReadWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
    ReadWriteTiming.FSMC_CLKDivision = 0x00;
    ReadWriteTiming.FSMC_DataLatency = 0x00;
    ReadWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A;//使用模式A

    FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;  //NE1
    FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
    FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
    FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
    FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
    FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
    FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
    FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
    FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
    FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
    FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
    FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
    FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
    FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &ReadWriteTiming;
    FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &ReadWriteTiming;
    FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
    FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1,ENABLE); //使能FSMC的Bank1_Bank1_NORSRAM1

    temp=*(vu32*)(0x1FFFF7E8);              //获取STM32的唯一ID的前24位作为MAC地址后三字节
    dm9000cfg.mode=DM9000_AUTO;
    dm9000cfg.queue_packet_len=0;
    //DM9000的SRAM的发送和接收指针自动返回到开始地址,并且开启接收中断
    dm9000cfg.imr_all = IMR_PAR|IMR_PRI;
    //初始化MAC地址
    dm9000cfg.mac_addr[0]=2;
    dm9000cfg.mac_addr[1]=0;
    dm9000cfg.mac_addr[2]=0;
    dm9000cfg.mac_addr[3]=(temp>>16)&0XFF;  //低三字节用STM32的唯一ID
    dm9000cfg.mac_addr[4]=(temp>>8)&0XFFF;
    dm9000cfg.mac_addr[5]=temp&0XFF;
    //初始化组播地址
    dm9000cfg.multicase_addr[0]=0Xff;
    dm9000cfg.multicase_addr[1]=0Xff;
    dm9000cfg.multicase_addr[2]=0Xff;
    dm9000cfg.multicase_addr[3]=0Xff;
    dm9000cfg.multicase_addr[4]=0Xff;
    dm9000cfg.multicase_addr[5]=0Xff;
    dm9000cfg.multicase_addr[6]=0Xff;
    dm9000cfg.multicase_addr[7]=0Xff;

    DM9000_Reset();                         //复位DM9000
    delay_ms(100);
    temp=DM9000_Get_DeiviceID();            //获取DM9000ID
    printf("DM9000 ID:%#x\r\n",temp);
    if(temp!=DM9000_ID) return 1;           //读取ID错误
    DM9000_Set_PHYMode(dm9000cfg.mode);     //设置PHY工作模式

    DM9000_WriteReg(DM9000_NCR,0X00);
    DM9000_WriteReg(DM9000_TCR,0X00);       //发送控制寄存器清零
    DM9000_WriteReg(DM9000_BPTR,0X3F);
    DM9000_WriteReg(DM9000_FCTR,0X38);
    DM9000_WriteReg(DM9000_FCR,0X00);
    DM9000_WriteReg(DM9000_SMCR,0X00);      //特殊模式
    DM9000_WriteReg(DM9000_NSR,NSR_WAKEST|NSR_TX2END|NSR_TX1END);//清除发送状态
    DM9000_WriteReg(DM9000_ISR,0X0F);       //清除中断状态
    DM9000_WriteReg(DM9000_TCR2,0X80);      //切换LED到mode1
    //设置MAC地址和组播地址
    DM9000_Set_MACAddress(dm9000cfg.mac_addr);      //设置MAC地址
    DM9000_Set_Multicast(dm9000cfg.multicase_addr); //设置组播地址
    DM9000_WriteReg(DM9000_RCR,RCR_DIS_LONG|RCR_DIS_CRC|RCR_RXEN);
    DM9000_WriteReg(DM9000_IMR,IMR_PAR);
    temp=DM9000_Get_SpeedAndDuplex();       //获取DM9000的连接速度和双工状态
    if(temp!=0XFF)                          //连接成功,通过串口显示连接速度和双工状态
    {
        printf("DM9000 Speed:%dMbps,Duplex:%s duplex mode\r\n",(temp&0x02)?10:100,(temp&0x01)?"Full":"Half");
    }else printf("DM9000 Establish Link Failed!\r\n");
    DM9000_WriteReg(DM9000_IMR,dm9000cfg.imr_all);  //设置中断
    return 0;
}
#define DM9000_RST      PDout(2)        //DM9000复位引脚
#define DM9000_INT      PCin(6)         //DM9000中断引脚

//DM9000地址结构体
typedef struct
{
    vu16 REG;
    vu16 DATA;
}DM9000_TypeDef;

//使用NOR/SRAM的 Bank1.sector1,地址位HADDR[27,26]=01 A17作为数据命令区分线
//注意设置时STM32内部会右移一位对其!
#define DM9000_BASE        ((u32)(0x60000000|0x0003FFFE))       //A17   作为数据命令分线
#define DM9000             ((DM9000_TypeDef *) DM9000_BASE)

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值