TWI

介绍TWI其实也是在介绍IIC,因为他们是同一协议,只是名字不一样而已,我也是看m16的接口看到有SDA、SCL这两个接口,查找文档才发现有TWI这个的,这大大方便了我写IIC协议控制LCD1602,因为之前我也写了软件模拟IIC协议,觉的太麻烦了,如果你的单片机没有SDA和SCL接口,说明没有硬件IIC协议,那么你可以写软件模拟IIC协议,别人已经写的很好了,我就不写了,因为太麻烦了,我懒得写-_-

先来介绍下TWI

介绍什么的太麻烦了,我不想写了,所以大家看技术文档吧,没有技术文档可以和我要,剩下的我直奔重点

寄存器介绍

TWI比特率寄存器-TWBR

通过配置比特率寄存器,设置传输数据的速率,工作在主机模式下,才需要配置

TWI控制寄存器-TWCR

我们只需要配置控制的寄存器就行,读取状态的就不用配置了,看自己需要的功能置1相应的位,常用的就是配置 TWEA: 使能TWI 应答 ,TWEN: TWI使能, TWIE: 使能TWI 中断 ,其他的一般不用

TWI状态寄存器-TWSR

这个就看TWPS1和TWPS0配置分频器就行,相信大家学过定时器就知道分频器了

数据寄存器就不需要多介绍了,因为这只是放置数据的,知道读取数据是读这个寄存器就行了

TWI(从机) 地址寄存器- TWAR

如果你是设置单片机为从机,就需要配置地址,以便主机能根据地址找到这个设备,但我们写IIC协议控制LCD1602,就不需要了,因为单片机设置的是主机

代码

寄存器介绍完了,怎么去写START,STOP,其实根本就不用我们抄心,人家技术文档都写好了,步骤都写好了,其中TWINT,TWSTA等这些的值是啥,新手可能一脸懵逼,其实就是宏定义的数字,看前面的寄存器,有对应位的名字,例如TWCR寄存器,TWINT就是第7位,当然,TWINT在编译器里已经预定义好了,直接写名字就行

先使能TWI,初始化下

//TWI初始化函数
void twi_init(void)
{TWCR = 0x00; //禁止TWITWBR = 50; //设置比特率9600//TWAR = 0x4E; //设置从机地址TWSR|= 0x01; //设置分频因子TWCR = 0x45; //启动TWISEI();
}

这个流程其实很简单
发送START,
发送地址SLA+W(SLA是7位地址,W是写,所以写成Address<<1|0 )
发送数据DATA


#define IIC_Start() TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)  ///发出Start信号
#define IIC_Stop()  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO)  ///发出Stop信号
#define IIC_Wait()  while (!(TWCR & (1<<TWINT)))  /*I2C总线单字节写入*/
uchar TWI_Write( /*uchar addr,*/ char data)
{TWBR = 50;  //设定波特率///START启动IIC_Start();IIC_Wait(); //等待Start完成if( (TWSR & 0xf8) != TW_START )     //Start未发出,错误退出return 0;/*发送设备地址*/TWDR = IIC_Address<<1|0; //芯片地址 0x3F ,赋值给数据寄存器 TWDR ,等待发送TWCR = (1 << TWINT) | (1 << TWEN);   //对控制寄存器TWCR的 TWINT 位软件写1进行清零,然后 使能TWI硬件接口 ,让TWI进行工作,发送 TWDR寄存器 中的数据IIC_Wait();                          //等待数据发送完毕 TWINT重新置位if ((TWSR & 0xF8) != TW_MT_SLA_ACK )//&& (TWSR & 0xF8) != TW_MT_SLA_NACK)return 0; //检测到TWINT位置位,比对TWSR寄存器内的状态量 , 如果正确则向下进行数据传输,错误返回 0/*data 写入数据*/TWDR = data;                           //将要写入的数据 ,赋值给数据寄存器 TWDR ,等待发送TWCR = (1 << TWINT) | (1 << TWEN);   //对控制寄存器TWCR的 TWINT 位软件写1进行清零,然后 使能TWI硬件接口 ,让TWI进行工作,发送 TWDR寄存器 中的数据IIC_Wait();                          //等待数据发送完毕 TWINT重新置位if ((TWSR & 0xF8) != TW_MT_DATA_ACK)// && (TWSR & 0xF8) != TW_MT_DATA_NACK)return 0; //检测到TWINT位置位,比对TWSR寄存器内的状态量 , 如果正确则向下进行数据传输,错误返回 0/*stop 停止*/IIC_Stop();                          //数据传输完成,发送STOP信号,释放对总线的控制return 1;                            //写入数据成功 ,返回1 ,用来判断是否成功写入数据
}

上面的应答标识符是需要根据下面的状态码来判断是否介绍到应答ACK了,有地址应答和数据应答,注意区分

#define IIC_Address         0x3f        //PCF8574T地址
///主机发送模式时各状态字的后续动作
#define TW_START            0x08        //开始信号已发出
#define TW_REP_START        0x10        //重复开始信号已发出
#define TW_MT_SLA_ACK       0x18        //写字节已发出并受到ACK信号
#define TW_MT_SLA_NACK      0x20        //写字节已发出并受到NACK信号
#define TW_MT_DATA_ACK      0x28        //数据已发出并受到ACK 信号
#define TW_MT_DATA_NACK     0x30        //数据已发出并受到NACK 信号
#define TW_MT_ARB_LOST      0x38        //丢失总线控制权
///主机接收模式时各状态字的后续动作
#define TW_MR_ARB_LOST      0x38        //丢失总线控制权,未收到应答信号
#define TW_MR_SLA_ACK       0x40        //读命令已发出并受到ACK
#define TW_MR_SLA_NACK      0x48        //读命令已发出并受到NACK
#define TW_MR_DATA_ACK      0x50        //数据已收到,ACK已发出
#define TW_MR_DATA_NACK     0x58        //数据已收到,NACK已发出
发送模式已经介绍完了,IIC协议准备好了,那么就可以写LCD1602的写命令和写数据了

发送的data中,第0位是RS接口,第1位RW接口,第2位是E接口,第4~7位是D4-D5接口,其实如果你写过3+4线接LCD1602就是应该知道,PCF8574T模块转接LCD1602就是用的3+4接线法。

写命令其实就是RS=0,RW=0,然后再测试D0-D7,根据LCD1602的命令集,直接去查每个命令执行什么功能,我就不过多写了。
//*************写命令****************************void LCD_write_command(unsigned char command){delay_nus(16);LCD_data&=~(1<<(1-1));//RS=0;指令寄存器LCD_data&=~(1<<(2-1));//RW=0;//LCD_data&=~(1<<(4-1));TWI_Write(LCD_data);LCD_data&=0X0f; //清高四位LCD_data|=command & 0xf0; //写高四位TWI_Write(LCD_data);Enable_LCD_write();command=command<<4; //低四位移到高四位LCD_data&=0x0f; //清高四位LCD_data|=command&0xf0; //写低四位TWI_Write(LCD_data);Enable_LCD_write();}

写命令和写数据函数非常像,如果你看错就会写成一样的
知道哪不同了吗?对,就这是RS=1,其他的都一样

//*************写数据****************************void LCD_write_data(unsigned char value)
{delay_nus(16);LCD_data|=(1<<(1-1));//RS=1;数据寄存器LCD_data&=~(1<<(2-1));//RW=0;TWI_Write(LCD_data);LCD_data&=0X0f; //清高四位LCD_data|=value&0xf0; //写高四位TWI_Write(LCD_data);Enable_LCD_write();value=value<<4; //低四位移到高四位LCD_data&=0x0f; //清高四位LCD_data|=value&0xf0; //写低四位TWI_Write(LCD_data);Enable_LCD_write();}

液晶使能比较简单,就不介绍了

//********************液晶屏使能*********************
uchar LCD_data;void Enable_LCD_write()
{LCD_data|=(1<<(3-1));//E=1;TWI_Write(LCD_data);delay_nus(25);LCD_data&=~(1<<(3-1));//E=0;TWI_Write(LCD_data);
}

最后贴一下总的代码,其实有些代码是测试用的,看着用吧

/**/
#include "iom16v.h"
#include <macros.h>
typedef unsigned char uchar;
typedef unsigned int  uint;#define IIC_Address         0x3f        //PCF8574T地址
///主机发送模式时各状态字的后续动作
#define TW_START            0x08        //开始信号已发出
#define TW_REP_START        0x10        //重复开始信号已发出
#define TW_MT_SLA_ACK       0x18        //写字节已发出并受到ACK信号
#define TW_MT_SLA_NACK      0x20        //写字节已发出并受到NACK信号
#define TW_MT_DATA_ACK      0x28        //数据已发出并受到ACK 信号
#define TW_MT_DATA_NACK     0x30        //数据已发出并受到NACK 信号
#define TW_MT_ARB_LOST      0x38        //丢失总线控制权
///主机接收模式时各状态字的后续动作
#define TW_MR_ARB_LOST      0x38        //丢失总线控制权,未收到应答信号
#define TW_MR_SLA_ACK       0x40        //读命令已发出并受到ACK
#define TW_MR_SLA_NACK      0x48        //读命令已发出并受到NACK
#define TW_MR_DATA_ACK      0x50        //数据已收到,ACK已发出
#define TW_MR_DATA_NACK     0x58        //数据已收到,NACK已发出#define IIC_Start() TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)  ///发出Start信号
#define IIC_Stop()  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO)  ///发出Stop信号
#define IIC_Wait()  while (!(TWCR & (1<<TWINT)))            ///等待Start信号发出/*I2C总线单字节写入*/
uchar TWI_Write( /*uchar addr,*/ char data)
{TWBR = 50;  //设定波特率///START启动IIC_Start();IIC_Wait(); //等待Start完成if( (TWSR & 0xf8) != TW_START )     //Start未发出,错误退出return 0;TWDR = IIC_Address<<1|0; //芯片地址 0x3F ,赋值给数据寄存器 TWDR ,等待发送TWCR = (1 << TWINT) | (1 << TWEN);   //对控制寄存器TWCR的 TWINT 位软件写1进行清零,然后 使能TWI硬件接口 ,让TWI进行工作,发送 TWDR寄存器 中的数据IIC_Wait();                          //等待数据发送完毕 TWINT重新置位if ((TWSR & 0xF8) != TW_MT_SLA_ACK )//&& (TWSR & 0xF8) != TW_MT_SLA_NACK)return 0; //检测到TWINT位置位,比对TWSR寄存器内的状态量 , 如果正确则向下进行数据传输,错误返回 0//     /*addr 操作地址*/
//    TWDR = addr;                         //将写入数据的绝对地址 ,赋值给数据寄存器 TWDR ,等待发送
//    TWCR = (1 << TWINT) | (1 << TWEN);   //对控制寄存器TWCR的 TWINT 位软件写1进行清零,然后 使能TWI硬件接口 ,让TWI进行工作,发送 TWDR寄存器 中的数据
//    IIC_Wait();                          //等待数据发送完毕 TWINT重新置位
//    if ((TWSR & 0xF8) != 0x28)
//        return 0; //检测到TWINT位置位,比对TWSR寄存器内的状态量 , 如果正确则向下进行数据传输,错误返回 0/*data 写入数据*/TWDR = data;                           //将要写入的数据 ,赋值给数据寄存器 TWDR ,等待发送TWCR = (1 << TWINT) | (1 << TWEN);   //对控制寄存器TWCR的 TWINT 位软件写1进行清零,然后 使能TWI硬件接口 ,让TWI进行工作,发送 TWDR寄存器 中的数据IIC_Wait();                          //等待数据发送完毕 TWINT重新置位if ((TWSR & 0xF8) != TW_MT_DATA_ACK)// && (TWSR & 0xF8) != TW_MT_DATA_NACK)return 0; //检测到TWINT位置位,比对TWSR寄存器内的状态量 , 如果正确则向下进行数据传输,错误返回 0/*stop 停止*/IIC_Stop();                          //数据传输完成,发送STOP信号,释放对总线的控制return 1;                            //写入数据成功 ,返回1 ,用来判断是否成功写入数据}/*I2C总线单字节读取*/
uchar TWI_Read(uchar addr)
{uchar Receive_Byte ;TWBR = 2;                            //设定波特率///*start 启动*///IIC_Start();                         //硬件发送START信号,并且清零TWINT位,使能硬件TWI,使TWI开始工作IIC_Wait();                          //等待 发送START完成 TWINT位置位if ((TWSR & 0xF8) != TW_START)return 0; //检测到TWINT位置位,比对TWSR寄存器内的状态量,如果正确则向下进行数据传输,错误返回 0/*SLA_W 芯片地址*/TWDR = IIC_Address;           //芯片地址 0x3F ,赋值给数据寄存器 TWDR ,等待发送TWCR = (1 << TWINT) | (1 << TWEN);   //对控制寄存器TWCR的 TWINT 位软件写1进行清零,然后 使能TWI硬件接口 ,让TWI进行工作,发送 TWDR寄存器 中的数据IIC_Wait();                          //等待数据发送完毕 TWINT重新置位if ((TWSR & 0xF8) != TW_MT_SLA_ACK)return 0; //检测到TWINT位置位,比对TWSR寄存器内的状态量 , 如果正确则向下进行数据传输,错误返回 0///*addr 操作地址*/TWDR = addr;                         //将写入数据的绝对地址 ,赋值给数据寄存器 TWDR ,等待发送TWCR = (1 << TWINT) | (1 << TWEN);   //对控制寄存器TWCR的 TWINT 位软件写1进行清零,然后 使能TWI硬件接口 ,让TWI进行工作,发送 TWDR寄存器 中的数据IIC_Wait();                          //等待数据发送完毕 TWINT重新置位if ((TWSR & 0xF8) != TW_MT_DATA_ACK)return 0; //检测到TWINT位置位,比对TWSR寄存器内的状态量 , 如果正确则向下进行数据传输,错误返回 0///*restart 重启动*/IIC_Start();                         //硬件发送 RESTART 信号,并且清零TWINT位,使能硬件TWI,使TWI开始工作IIC_Wait();                          //等待数据发送完毕 TWINT重新置位if ((TWSR & 0xF8) != TW_REP_START)return 0; //检测到TWINT位置位,比对TWSR寄存器内的状态量 , 如果正确则向下进行数据传输,错误返回 0///*SLA_R 芯片地址*/TWDR = 0xA1;                         //芯片地址 0xA0 并注明是读取操作(最后一位为 1 ),赋值给数据寄存器 TWDR ,等待发送TWCR = (1 << TWINT) | (1 << TWEN);   //对控制寄存器TWCR的 TWINT 位软件写1进行清零,然后 使能TWI硬件接口 ,让TWI进行工作,发送 TWDR寄存器 中的数据IIC_Wait();                          //等待数据发送完毕 TWINT重新置位if ((TWSR & 0xF8) != TW_MR_SLA_ACK  )return 0; //检测到TWINT位置位,比对TWSR寄存器内的状态量 , 如果正确则向下进行数据传输,错误返回 0/*读取数据*/TWCR = (1 << TWINT) | (1 << TWEN);   //对控制寄存器TWCR的 TWINT 位软件写1进行清零,然后 使能TWI硬件接口 ,让TWI进行工作,发送 TWDR寄存器 中的数据IIC_Wait();                          //等待数据发送完毕 TWINT重新置位if ((TWSR & 0xF8) != TW_MR_DATA_NACK )return 0; //检测到TWINT位置位,比对TWSR寄存器内的状态量 , 如果正确则向下进行数据传输,错误返回 0Receive_Byte = TWDR;                 //读取到的数据放到局部变量里///*stop 停止*/IIC_Stop();                          //数据传输完成,发送STOP信号,释放对总线的控制return Receive_Byte;                 //将读取到的数据作为函数的输出
}void delay_nus(int n)
{while(n--)NOP();
}
void delay_nms(int n)
{while(n--)delay_nus(1000);
}
//********************液晶屏使能*********************
uchar LCD_data;void Enable_LCD_write()
{LCD_data|=(1<<(3-1));//E=1;TWI_Write(LCD_data);delay_nus(25);LCD_data&=~(1<<(3-1));//E=0;TWI_Write(LCD_data);
}//*************写命令****************************void LCD_write_command(unsigned char command){delay_nus(16);LCD_data&=~(1<<(1-1));//RS=0;指令寄存器LCD_data&=~(1<<(2-1));//RW=0;//LCD_data&=~(1<<(4-1));TWI_Write(LCD_data);LCD_data&=0X0f; //清高四位LCD_data|=command & 0xf0; //写高四位TWI_Write(LCD_data);Enable_LCD_write();command=command<<4; //低四位移到高四位LCD_data&=0x0f; //清高四位LCD_data|=command&0xf0; //写低四位TWI_Write(LCD_data);Enable_LCD_write();}//*************写数据****************************void LCD_write_data(unsigned char value)
{delay_nus(16);LCD_data|=(1<<(1-1));//RS=1;数据寄存器LCD_data&=~(1<<(2-1));//RW=0;TWI_Write(LCD_data);LCD_data&=0X0f; //清高四位LCD_data|=value&0xf0; //写高四位TWI_Write(LCD_data);Enable_LCD_write();value=value<<4; //低四位移到高四位LCD_data&=0x0f; //清高四位LCD_data|=value&0xf0; //写低四位TWI_Write(LCD_data);Enable_LCD_write();}
//**********************设置显示位置*********************************void set_position(unsigned char x,unsigned char y)
{unsigned char position;if (y == 0)position = 0x80 + x;elseposition = 0xc0 + x;LCD_write_command(position);}//**********************显示字符串*****************************void display_string(unsigned char x,unsigned char y,unsigned char *s)
{set_position(x,y);while (*s){LCD_write_data(*s);s++;}}//*************液晶初始化****************************void LCD_init(void)
{//    LCD_write_data(0x08);
//    LCD_write_command(0x0F);
//    LCD_write_command(0x28);//数据4位
//    LCD_write_data(0x0C);
//    LCD_write_data(0x08);
//    LCD_write_command(0x28);
//    LCD_write_command(0x01);//光标清0
//    LCD_write_command(0x0C);//开显示、无光标、不闪烁
//    LCD_write_command(0x06);//光标加一、整屏不移动//    LCD_write_command(0x28);
//    delay_nus(40);
//    LCD_write_command(0x28);
//    delay_nus(40);
//    Enable_LCD_write();
//    delay_nus(40);
//    LCD_write_command(0x28); //4位显示!!!!!!!!!!!!!!!!!!
//    LCD_write_command(0x0c); //显示开
//    LCD_write_command(0x01); //清屏
//    delay_nms(2);LCD_write_command(0x33);delay_nus(50) ;
//  LCD_write_command(0x28);
//  delay_nus(50) ;LCD_write_command(0x0C);delay_nus(50) ;
//  LCD_write_command(0x06);
//  delay_nus(50) ;
//  LCD_write_command(0x01);
//  delay_nus(50);
}//TWI初始化函数
void twi_init(void)
{TWCR = 0x00; //禁止TWITWBR = 50; //设置比特率//TWAR = 0x4E; //设置从机地址TWSR|= 0x01; //设置分频因子TWCR = 0x45; //启动TWISEI();
}int main(void)
{MCUCSR |= 0x80;MCUCSR |= 0x80;DDRC |= (1<<4);PORTC |= (1<<4);twi_init();LCD_init();
//LCD_write_command(0x80);//第一行数据//TWI_Write('A');
//    TWI_Write('B');
//    TWI_Write('C');
//    TWI_Write('D');
//    TWI_Write('E');
//    TWI_Write('F');
//    TWI_Write('G');
//    display_string(4,0,"LiaoMi"); //显示一段文字
//    display_string(4,1,"2016.7.8");//显示一段文字return 0;
}

atmega16应用之TWI(IIC) PCF8574T转接LCD1602相关推荐

  1. 基于ATMEGA16单片机,MQ-3酒精传感器,LCD1602液晶显示的酒精浓度检测阈值报警仪

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 本文章为个人单片机课程大作业,代码都是自己写的,只是记录自己的学习过程,不做任何商用. 目录 单片机大作业: 一.使用仪器.材料 二. ...

  2. STM32通过(软/硬IIC)控制LCD1602液晶显示屏(IIC转8位并口的PCF8574转接板的使用)原创

    STM32通过(软/硬IIC)控制LCD1602液晶显示屏(IIC转8位并口的PCF8574转接板的使用)原创 A0,A1,A2全部悬空,那么PCF8574的IIC地址为0x4e.(具体原因,看PCF ...

  3. 一起学nRF51xx 13 - twi iic

    前言 在IIC总线是PHILIPS公司推出的一种串行总线.IIC总线有2根信号线SCK(时钟线)和SDA(数据线).NRF51822中所谓的TWI总线跟IIC总线兼容,这里统称为IIC总线.IIC总线 ...

  4. 51单片机 使用IIC转接板驱动LCD1602

    #include <reg52.h> #include "intrins.h" #define uchar unsigned char #define uint uns ...

  5. ATmega16开发板教程(7)——LCD1602

    ​8.LCD1602 LCD1602作为最基础的字符型液晶显示屏,能过显示16x02=32个字符.那么时序的操作--读写是最主要的内容,今天就带大家一起读读时序. 在看时序图前,对LCD的引脚功能要了 ...

  6. IIC/I2C/接口LCD1602转接板使用心得

    首先下载库文件 https://pan.baidu.com/s/1zLYSlDuxTMvxjclyk94hNg 注意:如果是从淘宝店下载的库文件有可能出现只显示一个首字符的现象,此时需要修改 Liqu ...

  7. K_A04_001 基于单片机驱动LCD1602字符滚动显示(8位并行+IIC通信)

    目录 一.资源说明 二.基本参数 1.参数 LCD1602模块 PCA8574 模块(IIC) 2.引脚说明 LCD1602 PCA8574 模块(IIC) 3.LCD1602并行V0接线 4.PCA ...

  8. Arduino--LCD1602(IIC)

    (1)简介 前篇文章介绍了LCD1602的四位数据线控制方法: https://blog.csdn.net/u011816009/article/details/106573622 但是该方法还是需要 ...

  9. 【花雕动手做】有趣好玩的音乐可视化系列项目(31)--LCD1602液晶屏

    偶然心血来潮,想要做一个音乐可视化的系列专题.这个专题的难度有点高,涉及面也比较广泛,相关的FFT和FHT等算法也相当复杂,不过还是打算从最简单的开始,实际动手做做试验,耐心尝试一下各种方案,逐步积累 ...

最新文章

  1. 饥荒海难机器人怎么用_饥荒海难机器人作用详解 机器人有什么用
  2. h5直播开发之旅总结
  3. 如何证明你的性能测试结果可信?
  4. Virtualbox设置虚拟机访问外网以及主机访问虚拟机
  5. go语言之进阶篇http客户端编程
  6. sftp服务器同步文件到本地,服务器之间通过sftp的方式同步文件,并入库到本地数据的表中...
  7. iphone NSNotificationCenter
  8. ucore和linux区别,附录 - 附录A—ucore历史 - 《操作系统的基本原理与简单实现》 - 书栈网 · BookStack...
  9. webpack文件系统缓存
  10. 在layoutsubviews中设置子控件的frame,保证执行alpha和frame动画流畅度
  11. Paip.断点调试MYSQL存储过程跟函数的解决方案大法
  12. 算法:两个数之和为目标数Two Sum II - Input array is sorted
  13. Java实现简易版的【图书管理系统】
  14. 实时 摔倒识别 /运动分析/打架等异常行为识别/控制手势识别等所有行为识别全家桶 原理 + 代码 + 数据+ 模型 开源!
  15. ERROR Error loading vue.config.js: ERROR Error: Command failed: git describe --always报错可能的原因
  16. JAVA程序修改PDF内容_java 修改pdf
  17. PSD格式截图软件 ScreenToLayers 1.2.3中文版
  18. 令人不寒而栗的黄蓉(转)
  19. web网页上一个帖子点赞是怎么制作的_如何查看17年以前的百度贴吧帖子
  20. 计算机专业自我总结100字,计算机专业学生自我评价100字

热门文章

  1. 彪哥情人节期间征女友一名铃声 彪哥情人节期间征女友一名手机...
  2. redis-Java集成Redis
  3. 关于发送邮件的几种方式
  4. MacbookPro电脑Hosts文件位置在哪里修改
  5. 实施工程师或技术支持必须熟悉的技能
  6. 计算机风景画作品,电脑制作的风景画
  7. vb.net在自己的应用中嵌入谷歌地球的方法
  8. 使用pandas的drop函数删除数据
  9. Win10修改msconfig后无法开机怎么办?
  10. (二)最新版Django项目数据库迁移;读取数据库增添删改;以及显示在html或vue前端(Django+Vue+Mysql,数据库管理数据分析网站)