(十一)DSP28335基础教程——EQEP实验(直流电机转速检测)

(十一)DSP28335基础教程——EQEP实验(直流电机转速检测)0前言这一节我们来学习DSP的EQEP模块的功能。实验目标:通过光电编码器,将采集直流减速电机的转速并显示在LCD1602上。由于28335控制LCD1602的例程并不多,在下面解释的过程会详细贴出代码,并给出一些注意事项。本节将分为硬件部分、软件部分和实验展示三个方面进行介绍,不清楚的欢迎留言。1硬件部分我们需要五个硬件:可调电源、DSP28335核心板、烧写器、自带光电编码器的直流减速电机和LCD1602。其中,电机的额定电压为12V,因此,我们通过可调电源来调整电压,则可以调整电机的转速

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

0 前言

这一节我们来学习DSP的EQEP模块的功能。实验目标:通过光电编码器,将采集直流减速电机的转速并显示在LCD1602上。

由于28335控制LCD1602的例程并不多,在下面解释的过程会详细贴出代码,并给出一些注意事项。

本节将分为硬件部分、软件部分和实验展示三个方面进行介绍,不清楚的欢迎留言。

1 硬件部分

我们需要五个硬件:可调电源、DSP28335核心板、烧写器、自带光电编码器的直流减速电机和LCD1602。其中,电机的额定电压为12V,因此,我们通过可调电源来调整电压,则可以调整电机的转速。

在这里插入图片描述

下面给出整体硬件架构图。在核心板与直流电机通信部分:IO50为EQEP模块的EQEP1A,负责接收电机编码器的A相脉冲;IO51为EQEP1B,负责接收电机编码器的B相脉冲。在核心板与LCD通信部分:IO24负责控制LCD指令/数据选择;IO25负责控制LCD读写功能选择;IO26负责控制LCD的使能;IO0~IO7则是与LCD的8位数据端通信接口。
在这里插入图片描述

2 软件部分

在软件部分,分为编码器功能设计和LCD显示设计。

首先我们看LCD显示设计的代码:(注意:查看代码时双击点进去看,否则会内容不全)。

需要注意的是,在进行写操作函数的时候,需要加点延时,否则会造成LCD通信出错;还有,在LCD初始化过程中,需要多次写LCD1602_WriteCmd(0x38,0)和LCD1602_WriteCmd(0x38,1),否则会造成LCD只显示第一行,第二行不显示,也就是初始化有问题

bsp_lcd1602.c

/** * ******************************************************************************************** * @file bsp_lcd1602.c * @file SK Electronics * @version V1.0 * @date 2021-xx-xx * @brief lcd1602显示函数接口 * ******************************************************************************************* * @attention * 实验平台:SK-F28335Mini 核心板 * CSDN博客:https://blog.csdn.net/weixin_46556696 * 淘宝:https://shop409670932.taobao.com */
#include "bsp_lcd1602.h"

extern void delay_1ms(Uint16 t);

void GPIO_LCD1602_Init(void)//RS RW E D0~D7进行初始化配置
{ 
   
    EALLOW;

    /*配置RS输出管脚IO24*/
    GpioCtrlRegs.GPAMUX2.bit.GPIO24=0;
    GpioCtrlRegs.GPAPUD.bit.GPIO24=0;
    GpioCtrlRegs.GPADIR.bit.GPIO24=1;

    /*配置RW输出管脚IO25*/
    GpioCtrlRegs.GPAMUX2.bit.GPIO25=0;
    GpioCtrlRegs.GPAPUD.bit.GPIO25=0;
    GpioCtrlRegs.GPADIR.bit.GPIO25=1;

    /*配置E输出管脚IO26*/
    GpioCtrlRegs.GPAMUX2.bit.GPIO26=0;
    GpioCtrlRegs.GPAPUD.bit.GPIO26=0;
    GpioCtrlRegs.GPADIR.bit.GPIO26=1;

    /*配置D0输出管脚IO0*/
    GpioCtrlRegs.GPAMUX1.bit.GPIO0=0;
    GpioCtrlRegs.GPAPUD.bit.GPIO0=0;
    GpioCtrlRegs.GPADIR.bit.GPIO0=1;

    /*配置D1输出管脚IO1*/
    GpioCtrlRegs.GPAMUX1.bit.GPIO1=0;
    GpioCtrlRegs.GPAPUD.bit.GPIO1=0;
    GpioCtrlRegs.GPADIR.bit.GPIO1=1;

    /*配置D2输出管脚IO2*/
    GpioCtrlRegs.GPAMUX1.bit.GPIO2=0;
    GpioCtrlRegs.GPAPUD.bit.GPIO2=0;
    GpioCtrlRegs.GPADIR.bit.GPIO2=1;

    /*配置D3输出管脚IO3*/
    GpioCtrlRegs.GPAMUX1.bit.GPIO3=0;
    GpioCtrlRegs.GPAPUD.bit.GPIO3=0;
    GpioCtrlRegs.GPADIR.bit.GPIO3=1;

    /*配置D4输出管脚IO4*/
    GpioCtrlRegs.GPAMUX1.bit.GPIO4=0;
    GpioCtrlRegs.GPAPUD.bit.GPIO4=0;
    GpioCtrlRegs.GPADIR.bit.GPIO4=1;

    /*配置D5输出管脚IO5*/
    GpioCtrlRegs.GPAMUX1.bit.GPIO5=0;
    GpioCtrlRegs.GPAPUD.bit.GPIO5=0;
    GpioCtrlRegs.GPADIR.bit.GPIO5=1;

    /*配置D6输出管脚IO6*/
    GpioCtrlRegs.GPAMUX1.bit.GPIO6=0;
    GpioCtrlRegs.GPAPUD.bit.GPIO6=0;
    GpioCtrlRegs.GPADIR.bit.GPIO6=1;

    /*配置D7输出管脚IO7*/
    GpioCtrlRegs.GPAMUX1.bit.GPIO7=0;
    GpioCtrlRegs.GPAPUD.bit.GPIO7=0;
    GpioCtrlRegs.GPADIR.bit.GPIO7=1;
    EDIS;
}
void GPIO_LCD1602_DB_OUT(void)//配置D0~D7为输出模式
{ 
   
    EALLOW;
    GpioCtrlRegs.GPADIR.bit.GPIO0=1;
    GpioCtrlRegs.GPADIR.bit.GPIO1=1;
    GpioCtrlRegs.GPADIR.bit.GPIO2=1;
    GpioCtrlRegs.GPADIR.bit.GPIO3=1;
    GpioCtrlRegs.GPADIR.bit.GPIO4=1;
    GpioCtrlRegs.GPADIR.bit.GPIO5=1;
    GpioCtrlRegs.GPADIR.bit.GPIO6=1;
    GpioCtrlRegs.GPADIR.bit.GPIO7=1;
    EDIS;
}
void GPIO_LCD1602_DB_IN(void)//配置D0~D7为输入模式
{ 
   
    EALLOW;
    GpioCtrlRegs.GPADIR.bit.GPIO0=0;
    GpioCtrlRegs.GPADIR.bit.GPIO1=0;
    GpioCtrlRegs.GPADIR.bit.GPIO2=0;
    GpioCtrlRegs.GPADIR.bit.GPIO3=0;
    GpioCtrlRegs.GPADIR.bit.GPIO4=0;
    GpioCtrlRegs.GPADIR.bit.GPIO5=0;
    GpioCtrlRegs.GPADIR.bit.GPIO6=0;
    GpioCtrlRegs.GPADIR.bit.GPIO7=0;
    EDIS;
}
/** * @brief LCD检测忙状态 * @parameter 无 * @return_value 无 */
void LCD1602_WaitReady(void)
{ 
   
    Uint8 sta;
    GPIO_LCD1602_DB_OUT();
    GpioDataRegs.GPADAT.all|=0x000000FF;
    LCD1602_RS_CLR();
    LCD1602_RW_SET();
    GPIO_LCD1602_DB_IN();
    do
    { 
   
        LCD1602_E_SET();
        sta=GpioDataRegs.GPADAT.bit.GPIO7;
        LCD1602_E_CLR();
    }while(sta);
    GPIO_LCD1602_DB_OUT();
}
/** * @brief 写指令 * @parameter cmd 要写入的指令 BusyC 忙检测标志 * @return_value 无 */
void LCD1602_WriteCmd(Uint8 cmd, Uint8 BusyC)
{ 
   
    if(BusyC) LCD1602_WaitReady();
    LCD1602_E_CLR();
    LCD1602_RS_CLR();
    LCD1602_RW_CLR();
    GpioDataRegs.GPADAT.all &= (cmd|0xFFFFFF00);
    DELAY_US(100);
    LCD1602_E_SET();
    DELAY_US(500);
    LCD1602_E_CLR();
    DELAY_US(10);
}

/** * @brief 写数据 * @parameter dat 要写入的数据 * @return_value 无 */
void LCD1602_WriteDat(Uint8 dat)
{ 
   
    LCD1602_WaitReady();
    LCD1602_E_CLR();
    LCD1602_RS_SET();
    LCD1602_RW_CLR();
    GpioDataRegs.GPADAT.all &= (dat|0xFFFFFF00);
    DELAY_US(100);
    LCD1602_E_SET();
    DELAY_US(500);
    LCD1602_E_CLR();
    DELAY_US(10);
}

/** * @brief 设置坐标 * @parameter x 横坐标 y 纵坐标 * @return_value 无 */
void LCD1602_SetCursor(Uint8 x, Uint8 y)
{ 
   
    Uint8 addr;
    if (y == 0)  //由输入的屏幕坐标计算显示RAM的地址
        addr = 0x00 + x;  //第一行字符地址从0x00开始
    else
        addr = 0x40 + x;  //第二行字符地址从0x40开始
    LCD1602_WriteCmd(addr|0x80,1);  //设置RAM地址
}

/** * @brief 显示字符串 * @parameter x,y设置列的起始和结束地址;str字符 len长度 * @return_value 无 */
void LCD1602_ShowStr(Uint8 x, Uint8 y, Uint8 *str, Uint8 len)
{ 
   
    LCD1602_SetCursor(x, y);    //设置起始地址
    while (len--)         //连续写入len个字符数据
    { 
   
        LCD1602_WriteDat(*str++);
    }
}
/** * @brief 显示数字 * @parameter x,y设置列的起始和结束地址;num 数字 * @return_value 无 */
void LCD_ShowNum(Uint8 x, Uint8 y,Uint8 num)
{ 
   
    LCD1602_SetCursor(x, y);    //设置起始地址
    LCD_ShowChar(x,y,num+'0');
}

/** * @brief 显示字符 * @parameter x,y设置列的起始和结束地址;dat 数据 * @return_value 无 */
void LCD_ShowChar(Uint8 x, Uint8 y,Uint8 dat)
{ 
   
    LCD1602_SetCursor(x, y);    //设置起始地址
    LCD1602_WriteDat(dat);
}


/** * @brief 1602初始化 * @parameter 无 * @return_value 无 */
void LCD1602_Init(void)
{ 
   
    GPIO_LCD1602_Init();   //开启GPIO口
    DELAY_US(15000);
    LCD1602_WriteCmd(0x38,0);  //三次显示模式设置,不检测忙信号
    delay_1ms(50);
    LCD1602_WriteCmd(0x38,0);  //三次显示模式设置,不检测忙信号
    delay_1ms(50);
    LCD1602_WriteCmd(0x38,0);  //三次显示模式设置,不检测忙信号
    delay_1ms(50);
    LCD1602_WriteCmd(0x38,0);  //
    delay_1ms(50);
    LCD1602_WriteCmd(0x38,1);  //
    delay_1ms(50);
    LCD1602_WriteCmd(0x08,1);  //关闭显示
    delay_1ms(50);
    LCD1602_WriteCmd(0x01,1);  //清屏
    delay_1ms(50);
    LCD1602_WriteCmd(0x06,1);  //显示光标和移动设置
    delay_1ms(50);
    LCD1602_WriteCmd(0x0C,1);  //显示器开及光标设置
    delay_1ms(50);
}

bsp_lcd1602.h

/** * ******************************************************************************************** * @file bsp_lcd1602.h * @file SK Electronics * @version V1.0 * @date 2021-xx-xx * @brief LCD1602函数接口头文件 * ******************************************************************************************* * @attention * 实验平台:SK-F28335Mini 核心板 * CSDN博客:https://blog.csdn.net/weixin_46556696 * 淘宝:https://shop409670932.taobao.com */

#ifndef _BSP_LCD1602_H_
#define _BSP_LCD1602_H_
#include "DSP28x_Project.h"


#define Uint8 unsigned char
#define LCD1602_RS_SET() GpioDataRegs. GPASET.bit.GPIO24=1
#define LCD1602_RS_CLR() GpioDataRegs. GPACLEAR.bit.GPIO24=1

#define LCD1602_RW_SET() GpioDataRegs. GPASET.bit.GPIO25=1
#define LCD1602_RW_CLR() GpioDataRegs. GPACLEAR.bit.GPIO25=1

#define LCD1602_E_SET() GpioDataRegs. GPASET.bit.GPIO26=1
#define LCD1602_E_CLR() GpioDataRegs. GPACLEAR.bit.GPIO26=1

void LCD1602_Init(void);
void LCD_ShowChar(Uint8 x, Uint8 y,Uint8 dat);
void LCD_ShowNum(Uint8 x, Uint8 y,Uint8 num);
void LCD1602_ShowStr(Uint8 x, Uint8 y, Uint8 *str, Uint8 len);
void LCD1602_SetCursor(Uint8 x, Uint8 y);
void LCD1602_WriteDat(Uint8 dat);
void LCD1602_WriteCmd(Uint8 cmd, Uint8 BusyC);
void LCD1602_WaitReady(void);
void GPIO_LCD1602_Init(void);
void GPIO_LCD1602_DB_OUT(void);
void GPIO_LCD1602_DB_IN(void);


#endif /*_BSP_LCD1602_H_ */

在编码器设计部分,采用的是传统M法测速方式,即:
在这里插入图片描述
其中v(k)代表k时刻的转速,x(k)代表k时刻的位置,x(k-1)代表上一时刻的位置,T代表采样时间间隔。当T时间越短时,所测得的转速精确度越高。

由于本电机采用的是500线的编码器,且程序的eQEP模块中设置的是4倍频的,即编码器AB两相脉冲的上升沿和下降沿都会被算入计数里面。因此,电机旋转一周的时候,将会有500*4=2000个计数脉冲。

此外,eQEP模块还设置了每0.001s采样一次,在这里采样溢出时间如果设置太大的话,容易造成测速不准确。因为当前计数值可能是上一次计数值经过了几个周期了,而程序还误以为是在当前的周期。比如说,上一次计数值是500,而当前计数值是600,此时程序误以为计数值之差只有100,但事实上由于采样时间太大,计数值已经从500到2000,再从0到600,实际之差是2100,因此造成误差!

这里我们先给出测转速r/min的公式:
在这里插入图片描述
其中,c(k)表示当前计数寄存器的值,c(k-1)表示上一次计数寄存器的值。

bsp_encoder.c

/** * ******************************************************************************************** * @file bsp_encoder.c * @file SK Electronics * @version V1.0 * @date 2020-xx-xx * @brief 编码器直流电机测速应用函数接口 * ******************************************************************************************* * @attention * 实验平台:SK-F28335Mini 核心板 * CSDN博客:https://blog.csdn.net/weixin_46556696 * 淘宝:https://shop409670932.taobao.com */
#include "bsp_encoder.h"
#include "bsp_lcd1602.h"
extern unsigned int motor_speed;
extern int DirectionQep;
extern int LineEncoder;
extern int Encoder_N;
extern float Speed_Mr_RPM;
extern float Position_k_1;
extern float Position_k;
unsigned int delay_show=0;
void QEP_pos_speed_get_init(void)
{ 
   
    #if(CPU_FRQ_150MHZ)
        EQep1Regs.QUPRD=150000;//当SYSCLKOUT=150MHZ时,设定Unit Timer
                                //溢出频率为1000HZ
    #endif
    #if(CPU_FRQ_100MHZ)
        EQep1Regs.QUPRD=100000;//当SYSCLKOUT=100MHZ时,设定Unit Timer
                                //溢出频率为1000HZ
    #endif
    EQep1Regs.QDECCTL.bit.QSRC=00;//设置eQEP计数模式
    EQep1Regs.QEPCTL.bit.FREE_SOFT=2;
    EQep1Regs.QEPCTL.bit.PCRM=00;//设定PCRM=00,即QPOSCNT在每次Index
                                 //脉冲都复位
    EQep1Regs.QEPCTL.bit.UTE=1;//使能UTE单元溢出功能
    EQep1Regs.QEPCTL.bit.QCLM=1;//当UTE单元溢出时允许锁存
    EQep1Regs.QEPCTL.bit.QPEN=1;//使能eQEP
    EQep1Regs.QCAPCTL.bit.UPPS=5;//1/32 for unit position
    EQep1Regs.QCAPCTL.bit.CCPS=7;//1/128 for CAP clock
    EQep1Regs.QCAPCTL.bit.CEN=1;//使能eQEP的捕获功能
    EQep1Regs.QPOSMAX=Encoder_N;//设定计数器的最大值
    EQep1Regs.QEPCTL.bit.SWI=1;//软件强制产生一次index脉冲
    InitEQep1Gpio();
}

void QEP_pos_speed_get_Calc(void)
{ 
   
    float tmp1;
    delay_show++;
    //检测转动方向
    DirectionQep=EQep1Regs.QEPSTS.bit.QDF;

    //检测索引信号
    if(EQep1Regs.QFLG.bit.IEL==1)
    { 
   
        EQep1Regs.QCLR.bit.IEL=1;//清除中断信号
    }

    if(EQep1Regs.QFLG.bit.UTO==1)//如果定时器基准单元出现溢出事件 0.001中断一次
    { 
   
        Position_k_1=1.0*EQep1Regs.QPOSLAT;//获取当前位置
        if(DirectionQep==0)//POSCNT is counting down
        { 
   
            if(Position_k >= Position_k_1)
                tmp1=Position_k - Position_k_1;//当前位置还没有过零
            else
                tmp1=Encoder_N+(Position_k - Position_k_1);//当前位置已过零
        }
        else if(DirectionQep==1)//POSCNT is counting up
        { 
   
            if(Position_k <= Position_k_1)
                tmp1=Position_k_1 - Position_k;//当前位置还没有过零
            else
                tmp1=Encoder_N+(Position_k_1 - Position_k);//当前位置已过零
        }
        Speed_Mr_RPM=(tmp1/80)*60;//转/分钟
        Position_k=Position_k_1;//更新上一次位置
        EQep1Regs.QCLR.bit.UTO=1;

        if(delay_show%1000==0)//1秒显示一次
        { 
   
            motor_speed=Speed_Mr_RPM;
            LCD_ShowNum(7,0,motor_speed/100%10);//显示百位
            LCD_ShowNum(8,0,motor_speed/10%10);//显示十位
            LCD_ShowNum(9,0,motor_speed/1%10);//显示个位
            delay_show=0;
        }
    }
}

bsp_encoder.h

/** * ******************************************************************************************** * @file bsp_encoder.h * @file SK Electronics * @version V1.0 * @date 2020-xx-xx * @brief 编码器直流电机测速应用函数接口头文件 * ******************************************************************************************* * @attention * 实验平台:SK-F28335Mini 核心板 * CSDN博客:https://blog.csdn.net/weixin_46556696 * 淘宝:https://shop409670932.taobao.com */

#ifndef _BSP_ENCODER_H_
#define _BSP_ENCODER_H_
#include "DSP28x_Project.h"


void QEP_pos_speed_get_init(void);
void QEP_pos_speed_get_Calc(void);


#endif /*_BSP_ENCODER_H_ */

main.c

/** * ******************************************************************************************** * @file main.c * @file SK Electronics * @version V1.0 * @date 2021-xx-xx * @brief 编码器直流电机转速测试 * ******************************************************************************************* * @attention * 实验平台:SK-F28335Mini 核心板 * CSDN博客:https://blog.csdn.net/weixin_46556696 * 淘宝:https://shop409670932.taobao.com */
#include "DSP28x_Project.h"
#include "bsp_encoder.h"
#include "bsp_lcd1602.h"

#define FLASH_RUN 1
#define SRAM_RUN 2
#define RUN_TYPE FLASH_RUN
#if RUN_TYPE==FLASH_RUN
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;
#endif
int DirectionQep=0;
int LineEncoder=500;
int Encoder_N=2000;
unsigned int motor_speed=0;
float Speed_Mr_RPM=0;
float Position_k_1=0;
float Position_k=0;

void delay_1ms(Uint16 t);
/** * @brief 主函数 * @parameter 无 * @return_value 无 */
void main(void)
{ 
   
/*第一步:初始化系统控制:*/
    InitSysCtrl();
/*第二步:初始化GPIO口*/
    InitGpio();

/* 第三步:清除所有中断 和初始化 PIE 向量表:*/
    DINT;// 关闭全局中断
    InitPieCtrl();// 初始化 PIE 控制寄存器到默认状态,默认状态是全部 PIE 中断被禁用和标志位被清除
    IER = 0x0000;// 禁用 CPU 中断和清除所有 CPU 中断标志位:
    IFR = 0x0000;
    InitPieVectTable();// 初始化 PIE 中断向量表

    // 中断重映射,注册中断程序入口(用户按需求添加)
    EALLOW;


    EDIS;
    //

    /*程序烧录入28335(可选的)*/
#if RUN_TYPE==FLASH_RUN
    MemCopy(&RamfuncsLoadStart,&RamfuncsLoadEnd,&RamfuncsRunStart);
    InitFlash();
#endif
/* 第四步: 初始化片上外设*/
    // InitPeripherals(); //初始化所有外设(本例程不需要)
    delay_1ms(5000);//等待LCD进入工作状态
    LCD1602_Init();//初始化1602显示屏
    LCD1602_ShowStr(0,0,"speed:",6);
    LCD1602_ShowStr(7,0," r/min",10);
    LCD1602_ShowStr(0,1,"SK ELECTRONICS",14);
    QEP_pos_speed_get_init();
/* 第五步:添加用户功能具体代码*/

    EINT;
    ERTM;

    for(;;)
    { 
   
        QEP_pos_speed_get_Calc();

      // GpioDataRegs. GPATOGGLE.bit.GPIO0=1;
      // delay_1ms(1000);
    }
}


void delay_1ms(Uint16 t)
{ 
   
    while(t--)
    { 
   
        DELAY_US(1000);
    }
}

3 实验展示

程序烧录进去后,大家可以看到这个效果图,通过调整可调电源的电压来控制电机转速,明显可以测速并显示在LCD上。实验展示视频可在评论区链接查看!
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210504140342813.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NjU1NjY5Ng==,size_16,color_FFFFFF,t_70#
大家可以参考代码尝试一下, 有疑问的欢迎留言!!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/184832.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • github开发人员在七夕搞事情:remote: Support for password authentication was removed on August 13, 2021.

    github开发人员在七夕搞事情:remote: Support for password authentication was removed on August 13, 2021.1问题描述如果你在七夕(没错就是2020年8月14日)的这一天刚好加班,又刚好去访问了全球最大的同性交友网站,又刚好去更新提交代码,又或你创建了一个新的仓库送给自己,又刚好想把这个仓库送给(push)github,你就刚好会遇到这个问题:remote:SupportforpasswordauthenticationwasremovedonAugust13,2021.Pleaseuseapersonalaccesstokeninstead.具体如下:(yolov4)

  • SSM整合案例(超详细)「建议收藏」

    SSM整合案例(超详细)「建议收藏」SSM整合案例(超详细)环境准备前提须知创建数据库和表结构创建Maven工程ssm导入坐标并建立依赖编写实体类编写持久层接口编写业务层接口编写业务层实现类编写Controller整合步骤保证Spring框架在web工程中独立运行第一步:编写spring配置文件并导入约束第二步:使用注解配置业务层第三步:导入log4j.properties配置文件第四步:测试spring能否独立运行保证SpringMVC在web工程中独立运行第一步:在web.xml中配置核心控制器(Dis

  • window.top.location.href 和 window.location.href 的区别

    window.top.location.href 和 window.location.href 的区别

  • 持续更新:适合Java初学者2021年最新练手项目!【建议收藏】「建议收藏」

    持续更新:适合Java初学者2021年最新练手项目!【建议收藏】「建议收藏」源码下载(实例一):jsp开发完整的博研图书馆后台管理系统,不使用框架开发的,太完美了http://www.zuidaima.com/share/2358272909446144.htm源码下载(实例二):javaWeb图书馆管理系统源码mysql版本https://download.csdn.net/detail/defonds/7123499源码下载(实例三):GitHub-uboger/LibraryManager:JAVAGUI图书馆管理系统htt…

  • GTM(Global Traffic Manager)和GSLB(Global Server Load Balancing)服务介绍「建议收藏」

    GTM(Global Traffic Manager)和GSLB(Global Server Load Balancing)服务介绍「建议收藏」最近看到一篇关于GSLB的文章,写的非常不错,学习了一下,这里做一些记录。一、GTM介绍GTM(GlobalTrafficManager的简写)即全局流量管理,基于网宿智能DNS、分布式监控体系,实现实时故障切换及全球负载均衡,保障应用服务的持续高可用性。GTM基于资源的健康状况及流量负载做智能调度决策,为用户提供最佳访问IP。网宿GTM,提供更可靠、稳定和安全的流量调度服务,助您轻松…

  • 安装DingoApi「建议收藏」

    安装DingoApi「建议收藏」安装DingoApi

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号