基于树莓派3的CAN总线编程
基于树莓派3的CAN总线编程
简介
树莓派3使用Python控制SPI接口的MCP2515 CAN模块。实现命令行控制CAN的收发。
环境搭建
- Raspiberry Pi Model 3B 安装Raspbian,并使能SPI功能(默认关闭)
- python2.7
- spidev-3.2(如有更新,下载最新版本)
- MCP2515模块(SPI接口)
使用说明
共mcp2515.py和mcp2515_run.py两个文件,放在同一目录下,运行mcp2515_run.py。
如上图所示,命令行支持如下命令:
mcp -init //初始化,自动调用
mcp -w 1 2 3 //发送数据,这里发送了3个字节:0x01,0x02,0x03
mcp -r //读取接收缓冲区,示例中没有收到数据,为空
help //帮助信息
exit //退出命令行
源代码
mcp2515_run.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import spidev,time
import sys,cmd,shlex,types
from mcp2515 import *
spi = spidev.SpiDev(0,0)
def mcp2515_reset():
tmpc = [0xc0]
spi.writebytes(tmpc)
def mcp2515_writeReg(addr, val):
buf = [0x02, addr, val]
spi.writebytes(buf)
def mcp2515_readReg(addr):
buf = [0x03, addr, 0x55]
buf = spi.xfer2(buf)
return int(buf[2])
def mcp2515_init():
mcp2515_reset()
time.sleep(2)
#设置波特率为125Kbps
#set CNF1,SJW=00,长度为1TQ,BRP=49,TQ=[2*(BRP+1)]/Fsoc=2*50/8M=12.5us
mcp2515_writeReg(CNF1,CAN_125Kbps);
#set CNF2,SAM=0,在采样点对总线进行一次采样,PHSEG1=(2+1)TQ=3TQ,PRSEG=(0+1)TQ=1TQ
mcp2515_writeReg(CNF2,0x80|PHSEG1_3TQ|PRSEG_1TQ);
#set CNF3,PHSEG2=(2+1)TQ=3TQ,同时当CANCTRL.CLKEN=1时设定CLKOUT引脚为时间输出使能位
mcp2515_writeReg(CNF3,PHSEG2_3TQ);
mcp2515_writeReg(TXB0SIDH,0xFF)#发送缓冲器0标准标识符高位
mcp2515_writeReg(TXB0SIDL,0xEB)#发送缓冲器0标准标识符低位(第3位为发送拓展标识符使能位)
mcp2515_writeReg(TXB0EID8,0xFF)#发送缓冲器0拓展标识符高位
mcp2515_writeReg(TXB0EID0,0xFF)#发送缓冲器0拓展标识符低位
mcp2515_writeReg(RXB0SIDH,0x00)#清空接收缓冲器0的标准标识符高位
mcp2515_writeReg(RXB0SIDL,0x00)#清空接收缓冲器0的标准标识符低位
mcp2515_writeReg(RXB0EID8,0x00)#清空接收缓冲器0的拓展标识符高位
mcp2515_writeReg(RXB0EID0,0x00)#清空接收缓冲器0的拓展标识符低位
mcp2515_writeReg(RXB0CTRL,0x40)#仅仅接收拓展标识符的有效信息
mcp2515_writeReg(RXB0DLC,DLC_8)#设置接收数据的长度为8个字节
mcp2515_writeReg(RXF0SIDH,0xFF)#配置验收滤波寄存器n标准标识符高位
mcp2515_writeReg(RXF0SIDL,0xEB)#配置验收滤波寄存器n标准标识符低位(第3位为接收拓展标识符使能位)
mcp2515_writeReg(RXF0EID8,0xFF)#配置验收滤波寄存器n拓展标识符高位
mcp2515_writeReg(RXF0EID0,0xFF)#配置验收滤波寄存器n拓展标识符低位
mcp2515_writeReg(RXM0SIDH,0xFF)#配置验收屏蔽寄存器n标准标识符高位
mcp2515_writeReg(RXM0SIDL,0xE3)#配置验收屏蔽寄存器n标准标识符低位
mcp2515_writeReg(RXM0EID8,0xFF)#配置验收滤波寄存器n拓展标识符高位
mcp2515_writeReg(RXM0EID0,0xFF)#配置验收滤波寄存器n拓展标识符低位
mcp2515_writeReg(CANINTF,0x00)#清空CAN中断标志寄存器的所有位(必须由MCU清空)
mcp2515_writeReg(CANINTE,0x01)#配置CAN中断使能寄存器的接收缓冲器0满中断使能,其它位禁止中断
mcp2515_writeReg(CANCTRL,REQOP_NORMAL|CLKOUT_ENABLED)#将MCP2515设置为正常模式,退出配置模式
#tmpc = mcp2515_readReg(CANSTAT)#读取CAN状态寄存器的值
#tmpd = int(tmpc[0]) & 0xe0
#if OPMODE_NORMAL!=tmpd:#判断MCP2515是否已经进入正常模式
# mcp2515_writeReg(CANCTRL,REQOP_NORMAL|CLKOUT_ENABLED)#再次将MCP2515设置为XX模式,退出配置模式
print '\r\nMCP2515 Initialized.\r\n'
def mcp2515_write(buf):
for i in range(50):
time.sleep(2) #通过软件延时约nms(不准确)
if not mcp2515_readReg(TXB0CTRL)&0x08:#快速读某些状态指令,等待TXREQ标志清零
break
N = len(buf)
for j in range(N):
mcp2515_writeReg(TXB0D0+j,buf[j])#将待发送的数据写入发送缓冲寄存器
mcp2515_writeReg(TXB0DLC,N)#将本帧待发送的数据长度写入发送缓冲器0的发送长度寄存器
mcp2515_writeReg(TXB0CTRL,0x08)#请求发送报文
def mcp2515_read():
N = 0
buf = []
if mcp2515_readReg(CANINTF) & 0x01:
N = mcp2515_readReg(RXB0DLC)#读取接收缓冲器0接收到的数据长度(0~8个字节)
for i in range(N):
buf.append(mcp2515_readReg(RXB0D0+i))#把CAN接收到的数据放入指定缓冲区
mcp2515_writeReg(CANINTF,0)#清除中断标志位(中断标志寄存器必须由MCU清零)
return buf
class MyCmd(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self)
self.prompt='wyq@rpi2 ~ $ '
mcp2515_init()
def emptyline(self):
pass
def do_test(self,arg):
lex = shlex.shlex(arg)
for x in lex:
print x
def do_exit(self,arg):
return True
def do_mcp(self,arg):
lex = shlex.shlex(arg)
try:
for x in lex:
if x=='-':
opt = lex.next()
if opt.lower()=='init':
mcp2515_init()
elif opt.lower()=='w':
buf = []
for i in lex:
buf.append(int(i))
mcp2515_write(buf)
elif opt.lower()=='r':
buf = mcp2515_read()
print 'Received:',len(buf)
for i in buf:
print hex(int(i))
else:
pass
except BaseException, e:
print e
def do_help(self,arg):
print '基于MCP2515的CAN收发控制器'
print 'Author:汪永强 QQ:917888229 Date:2016-8-18'
print '发送指令: mcp -w XX YY ZZ'
print '接收指令: mcp -r'
print '重初始化: mcp -init'
if __name__=='__main__':
mycmd = MyCmd()
mycmd.cmdloop()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
mcp2515.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#/* Configuration Registers */
CANSTAT = 0x0E
CANCTRL = 0x0F
BFPCTRL = 0x0C
TEC = 0x1C
REC = 0x1D
CNF3 = 0x28
CNF2 = 0x29
CNF1 = 0x2A
CANINTE = 0x2B
CANINTF = 0x2C
EFLG = 0x2D
TXRTSCTRL = 0x0D
#/* Recieve Filters */
RXF0SIDH = 0x00
RXF0SIDL = 0x01
RXF0EID8 = 0x02
RXF0EID0 = 0x03
RXF1SIDH = 0x04
RXF1SIDL = 0x05
RXF1EID8 = 0x06
RXF1EID0 = 0x07
RXF2SIDH = 0x08
RXF2SIDL = 0x09
RXF2EID8 = 0x0A
RXF2EID0 = 0x0B
RXF3SIDH = 0x10
RXF3SIDL = 0x11
RXF3EID8 = 0x12
RXF3EID0 = 0x13
RXF4SIDH = 0x14
RXF4SIDL = 0x15
RXF4EID8 = 0x16
RXF4EID0 = 0x17
RXF5SIDH = 0x18
RXF5SIDL = 0x19
RXF5EID8 = 0x1A
RXF5EID0 = 0x1B
#/* Receive Masks */
RXM0SIDH = 0x20
RXM0SIDL = 0x21
RXM0EID8 = 0x22
RXM0EID0 = 0x23
RXM1SIDH = 0x24
RXM1SIDL = 0x25
RXM1EID8 = 0x26
RXM1EID0 = 0x27
#/* Tx Buffer 0 */
TXB0CTRL = 0x30
TXB0SIDH = 0x31
TXB0SIDL = 0x32
TXB0EID8 = 0x33
TXB0EID0 = 0x34
TXB0DLC = 0x35
TXB0D0 = 0x36
TXB0D1 = 0x37
TXB0D2 = 0x38
TXB0D3 = 0x39
TXB0D4 = 0x3A
TXB0D5 = 0x3B
TXB0D6 = 0x3C
TXB0D7 = 0x3D
#/* Tx Buffer 1 */
TXB1CTRL = 0x40
TXB1SIDH = 0x41
TXB1SIDL = 0x42
TXB1EID8 = 0x43
TXB1EID0 = 0x44
TXB1DLC = 0x45
TXB1D0 = 0x46
TXB1D1 = 0x47
TXB1D2 = 0x48
TXB1D3 = 0x49
TXB1D4 = 0x4A
TXB1D5 = 0x4B
TXB1D6 = 0x4C
TXB1D7 = 0x4D
#/* Tx Buffer 2 */
TXB2CTRL = 0x50
TXB2SIDH = 0x51
TXB2SIDL = 0x52
TXB2EID8 = 0x53
TXB2EID0 = 0x54
TXB2DLC = 0x55
TXB2D0 = 0x56
TXB2D1 = 0x57
TXB2D2 = 0x58
TXB2D3 = 0x59
TXB2D4 = 0x5A
TXB2D5 = 0x5B
TXB2D6 = 0x5C
TXB2D7 = 0x5D
#/* Rx Buffer 0 */
RXB0CTRL = 0x60
RXB0SIDH = 0x61
RXB0SIDL = 0x62
RXB0EID8 = 0x63
RXB0EID0 = 0x64
RXB0DLC = 0x65
RXB0D0 = 0x66
RXB0D1 = 0x67
RXB0D2 = 0x68
RXB0D3 = 0x69
RXB0D4 = 0x6A
RXB0D5 = 0x6B
RXB0D6 = 0x6C
RXB0D7 = 0x6D
#/* Rx Buffer 1 */
RXB1CTRL = 0x70
RXB1SIDH = 0x71
RXB1SIDL = 0x72
RXB1EID8 = 0x73
RXB1EID0 = 0x74
RXB1DLC = 0x75
RXB1D0 = 0x76
RXB1D1 = 0x77
RXB1D2 = 0x78
RXB1D3 = 0x79
RXB1D4 = 0x7A
RXB1D5 = 0x7B
RXB1D6 = 0x7C
RXB1D7 = 0x7D
#/*******************************************************************
# * Bit register masks *
# *******************************************************************/
#/* TXBnCTRL */
TXREQ = 0x08
TXP = 0x03
#/* RXBnCTRL */
RXM = 0x60
BUKT = 0x04
#/* CANCTRL */
REQOP = 0xE0
ABAT = 0x10
OSM = 0x08
CLKEN = 0x04
CLKPRE = 0x03
#/* CANSTAT */
REQOP = 0xE0
ICOD = 0x0E
#/* CANINTE */
RX0IE = 0x01
RX1IE = 0x02
TX0IE = 0x04
TX1IE = 0x80
TX2IE = 0x10
ERRIE = 0x20
WAKIE = 0x40
MERRE = 0x80
#/* CANINTF */
RX0IF = 0x01
RX1IF = 0x02
TX0IF = 0x04
TX1IF = 0x80
TX2IF = 0x10
ERRIF = 0x20
WAKIF = 0x40
MERRF = 0x80
#/* BFPCTRL */
B1BFS = 0x20
B0BFS = 0x10
B1BFE = 0x08
B0BFE = 0x04
B1BFM = 0x02
B0BFM = 0x01
#/* CNF1 Masks */
SJW = 0xC0
BRP = 0x3F
#/* CNF2 Masks */
BTLMODE = 0x80
SAM = 0x40
PHSEG1 = 0x38
PRSEG = 0x07
#/* CNF3 Masks */
WAKFIL = 0x40
PHSEG2 = 0x07
#/* TXRTSCTRL Masks */
TXB2RTS = 0x04
TXB1RTS = 0x02
TXB0RTS = 0x01
#/*******************************************************************
# * Bit Timing Configuration *
# *******************************************************************/
#/* CNF1 */
SJW_1TQ = 0x40
SJW_2TQ = 0x80
SJW_3TQ = 0x90
SJW_4TQ = 0xC0
#/* CNF2 */
BTLMODE_CNF3 = 0x80
BTLMODE_PH1_IPT = 0x00
SMPL_3X = 0x40
SMPL_1X = 0x00
PHSEG1_8TQ = 0x38
PHSEG1_7TQ = 0x30
PHSEG1_6TQ = 0x28
PHSEG1_5TQ = 0x20
PHSEG1_4TQ = 0x18
PHSEG1_3TQ = 0x10
PHSEG1_2TQ = 0x08
PHSEG1_1TQ = 0x00
PRSEG_8TQ = 0x07
PRSEG_7TQ = 0x06
PRSEG_6TQ = 0x05
PRSEG_5TQ = 0x04
PRSEG_4TQ = 0x03
PRSEG_3TQ = 0x02
PRSEG_2TQ = 0x01
PRSEG_1TQ = 0x00
#/* CNF3 */
PHSEG2_8TQ = 0x07
PHSEG2_7TQ = 0x06
PHSEG2_6TQ = 0x05
PHSEG2_5TQ = 0x04
PHSEG2_4TQ = 0x03
PHSEG2_3TQ = 0x02
PHSEG2_2TQ = 0x01
PHSEG2_1TQ = 0x00
SOF_ENABLED = 0x80
WAKFIL_ENABLED = 0x40
WAKFIL_DISABLED = 0x00
#/*******************************************************************
# * Control/Configuration Registers *
# *******************************************************************/
#/* CANINTE */
RX0IE_ENABLED = 0x01
RX0IE_DISABLED = 0x00
RX1IE_ENABLED = 0x02
RX1IE_DISABLED = 0x00
G_RXIE_ENABLED = 0x03
G_RXIE_DISABLED = 0x00
TX0IE_ENABLED = 0x04
TX0IE_DISABLED = 0x00
TX1IE_ENABLED = 0x08
TX2IE_DISABLED = 0x00
TX2IE_ENABLED = 0x10
TX2IE_DISABLED = 0x00
G_TXIE_ENABLED = 0x1C
G_TXIE_DISABLED = 0x00
ERRIE_ENABLED = 0x20
ERRIE_DISABLED = 0x00
WAKIE_ENABLED = 0x40
WAKIE_DISABLED = 0x00
IVRE_ENABLED = 0x80
IVRE_DISABLED = 0x00
#/* CANINTF */
RX0IF_SET = 0x01
RX0IF_RESET = 0x00
RX1IF_SET = 0x02
RX1IF_RESET = 0x00
TX0IF_SET = 0x04
TX0IF_RESET = 0x00
TX1IF_SET = 0x08
TX2IF_RESET = 0x00
TX2IF_SET = 0x10
TX2IF_RESET = 0x00
ERRIF_SET = 0x20
ERRIF_RESET = 0x00
WAKIF_SET = 0x40
WAKIF_RESET = 0x00
IVRF_SET = 0x80
IVRF_RESET = 0x00
#/* CANCTRL */
REQOP_CONFIG = 0x80
REQOP_LISTEN = 0x60
REQOP_LOOPBACK = 0x40
REQOP_SLEEP = 0x20
REQOP_NORMAL = 0x00
ABORT = 0x10
OSM_ENABLED = 0x08
CLKOUT_ENABLED = 0x04
CLKOUT_DISABLED = 0x00
CLKOUT_PRE_8 = 0x03
CLKOUT_PRE_4 = 0x02
CLKOUT_PRE_2 = 0x01
CLKOUT_PRE_1 = 0x00
#/* CANSTAT */
OPMODE_CONFIG = 0x80
OPMODE_LISTEN = 0x60
OPMODE_LOOPBACK = 0x40
OPMODE_SLEEP = 0x20
OPMODE_NORMAL = 0x00
#/* RXBnCTRL */
RXM_RCV_ALL = 0x60
RXM_VALID_EXT = 0x40
RXM_VALID_STD = 0x20
RXM_VALID_ALL = 0x00
RXRTR_REMOTE = 0x08
RXRTR_NO_REMOTE = 0x00
BUKT_ROLLOVER = 0x04
BUKT_NO_ROLLOVER = 0x00
FILHIT0_FLTR_1 = 0x01
FILHIT0_FLTR_0 = 0x00
FILHIT1_FLTR_5 = 0x05
FILHIT1_FLTR_4 = 0x04
FILHIT1_FLTR_3 = 0x03
FILHIT1_FLTR_2 = 0x02
FILHIT1_FLTR_1 = 0x01
FILHIT1_FLTR_0 = 0x00
#/* TXBnCTRL */
TXREQ_SET = 0x08
TXREQ_CLEAR = 0x00
TXP_HIGHEST = 0x03
TXP_INTER_HIGH = 0x02
TXP_INTER_LOW = 0x01
TXP_LOWEST = 0x00
#/*******************************************************************
# * Register Bit Masks *
# *******************************************************************/
DLC_0 = 0x00
DLC_1 = 0x01
DLC_2 = 0x02
DLC_3 = 0x03
DLC_4 = 0x04
DLC_5 = 0x05
DLC_6 = 0x06
DLC_7 = 0x07
DLC_8 = 0x08
#/*******************************************************************
# * CAN SPI commands *
# *******************************************************************/
CAN_RESET = 0xC0
CAN_READ = 0x03
CAN_WRITE = 0x02
CAN_RTS = 0x80
CAN_RTS_TXB0 = 0x81
CAN_RTS_TXB1 = 0x82
CAN_RTS_TXB2 = 0x84
CAN_RD_STATUS = 0xA0
CAN_BIT_MODIFY = 0x05
CAN_RX_STATUS = 0xB0
CAN_RD_RX_BUFF = 0x90
CAN_LOAD_TX = 0x40
#/*******************************************************************
# * Miscellaneous *
# *******************************************************************/
DUMMY_BYTE = 0x00
TXB0 = 0x31
TXB1 = 0x41
TXB2 = 0x51
RXB0 = 0x61
RXB1 = 0x71
EXIDE_SET = 0x08
EXIDE_RESET = 0x00
#MCP2515波特率预分频
CAN_10Kbps = 0x31
CAN_25Kbps = 0x13
CAN_50Kbps = 0x09
CAN_100Kbps = 0x04
CAN_125Kbps = 0x03
CAN_250Kbps = 0x01
CAN_500Kbps = 0x00
基于树莓派3的CAN总线编程的更多相关文章
- DIY一个基于树莓派和Python的无人机视觉跟踪系统
DIY一个基于树莓派和Python的无人机视觉跟踪系统 无人机通过图传将航拍到的图像存储并实时传送回地面站差点儿已经是标配.假设想来点高级的--在无人机上直接处理拍摄的图像并实现自己主动控制要怎么实现 ...
- 基于引擎的matlab+vc混合编程的配置
前段时间在项目中做了一些关于基于引擎的vc+matlab混合编程的工作. 如果你是混合编程新手,我相信使用引擎的方式编程是比较简单快捷的一种方式. 当然这种方法也有其缺点,就是不能脱离matlab运行 ...
- atitit.基于组件的事件为基础的编程模型--服务器端控件(1)---------服务器端控件和标签之间的关系
atitit.基于组件的事件为基础的编程模型--服务器端控件(1)---------服务器端控件和标签之间的关系 1. server控件是要server了解了标签.种类型的server控件: 1 1. ...
- 基于树莓派的智能家居项目的设想与实现 Hestia
注:本人内容的准确性仅限于笔者写该篇文章时的情况,不保证后续与实际项目代码一致.实时内容还请关注Github项目托管页面:https://github.com/GenialX/hestia-serve ...
- Spring学习之旅(八)Spring 基于AspectJ注解配置的AOP编程工作原理初探
由小编的上篇博文可以一窥基于AspectJ注解配置的AOP编程实现. 本文一下未贴出的相关代码示例请关注小编的上篇博文<Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AO ...
- Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AOP编程比较
本篇博文用一个稍复杂点的案例来对比一下基于XML配置与基于AspectJ注解配置的AOP编程的不同. 相关引入包等Spring AOP编程准备,请参考小编的其他博文,这里不再赘述. 案例要求: 写一 ...
- .Net Core 基于CAP框架的事件总线
.Net Core 基于CAP框架的事件总线 CAP 是一个在分布式系统中(SOA,MicroService)实现事件总线及最终一致性(分布式事务)的一个开源的 C# 库,她具有轻量级,高性能,易使用 ...
- 基于STM32F10x的串口(USART)输入输出编程
1 前言 STM32有强大的固件库,绝大部分函数都可以有库里面的函数组合编写.固件库可以到ST官网(www.st.com)上下载,也可以搜索“STM32 固件库 v3.5”下载到固件库.本文章就是基于 ...
- 树莓派项目——基于树莓派的WIFI网络互传系统设计
一 实验原理 所需硬件:树莓派3B,TP-LINK WiFi模块,笔记本电脑,网线 所需软件:Putty.远程桌面链接.python.cmd界面 树莓派3B是只有信用卡大小的微型电脑,其系统基于Lin ...
随机推荐
- html基础标签下
1.1 单标签 ◆注释标签 ctrl+/ ◆水平线标签 <hr> ◆换行标签 <br> 1.2 双标签 ◆段落标签 <p></p> ◆ ...
- Oracle查询时15分钟划分
select to_date(to_char(sysdate, 'yyyy-MM-dd hh24') || ':' || floor(to_number(to_char(s ...
- android 所有焦点问题
一. 主动获取焦点 setFocusable(true); // 是设置能否获得焦点而已.. requestFocus(); //是让控件得到焦点 requestFocusI ...
- Expo大作战(二)--expo的生命周期,expo社区交流方式,expo学习必备资源,开发使用expo时关注的一些问题
简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...
- [Android] Spinners介绍及用法
本文地址:http://www.cnblogs.com/rossoneri/p/4366018.html Spinners介绍 Spinners提供了从一个集(set)中选择某个值(value)的一个 ...
- 留言板0.4_model中的数据库(1)
1.先在数据库中加入一天测试数据先 2.在model的"views"中载入数据库和model的类 import pymysql from .models import UserMe ...
- CSS样式----CSS属性:字体属性和文本属性(图文详解)
本文最初于2015-10-04发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. 本文重要内容 CSS的单位 字体属性 文本属性 定 ...
- 转:C# 深入理解堆栈、堆在内存中的实现
尽管在.NET framework下我们并不需要担心内存管理和垃圾回收(GarbageCollection),但是我们还是应该了解它们,以优化我们的应用程序.同时,还需要具备一些基础的内存管理工作机制 ...
- Windows DHCP备份还原命令
DHCP服务器如果要更换,最简单的方法就是命令导入导出 导出netsh dhcp server export e:\dhcp.txt all 导入netsh dhcp server import ...
- 汇编语言debug命令与指令机器码
一.debug命令 二.标志信息 -r用这个指令,得到的信息右下角: NV UP EI PL NZ NA PO NC 这些符号代表的就是标志寄存器里常用标志位的值.这个是符号值对应表: 溢出标志OF( ...