分类 默认分类 下的文章
I2C 读写案例
include <stdio.h>
include <stm32f10x.h>
int fputc(int ch, FILE *fp)
{
if (fp == stdout)
{
if (ch == '\n')
{
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, '\r');
}
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, ch);
}
return ch;
}
// 发送开始信号和从机地址(传输模式)
void start(void)
{
if (I2C1->SR1 || I2C1->SR2)
printf("error!\n");
restart:
I2C_GenerateSTART(I2C1, ENABLE);
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) == ERROR); // 等待开始信号发送完毕
I2C_SendData(I2C1, 0xa0); // 从机地址(传输模式)
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR) // 等待从机确认
{
if (I2C_GetFlagStatus(I2C1, I2C_FLAG_AF) == SET)
{
// 若从机未响应, 则重试
// 执行了写操作后需要等待一段时间才能执行其他命令
I2C_ClearFlag(I2C1, I2C_FLAG_AF);
//printf("NACK!\n");
goto restart;
}
}
}
uint8_t read(uint8_t addr)
{
start();
I2C_SendData(I2C1, addr); // 发送存储器地址
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) == ERROR);
I2C_GenerateSTART(I2C1, ENABLE); // RESTART
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) == ERROR);
I2C_SendData(I2C1, 0xa1); // 从机地址(接收模式)
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) == ERROR);
I2C_GenerateSTOP(I2C1,ENABLE); // 接收最后一字节数据前先准备好STOP信号
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED) == ERROR); // 等待数据接收完毕
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) == SET); // 等待停止信号发送完毕
return I2C_ReceiveData(I2C1);
}
void write(uint8_t addr, uint8_t value)
{
start();
I2C_SendData(I2C1, addr); // 前两个数据可连发, 无需等待TXE置位
I2C_SendData(I2C1, value);
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) == ERROR); // 等待数据完全发送完毕
I2C_GenerateSTOP(I2C1,ENABLE);
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) == SET); // 等待停止信号发送完毕
}
void read_more(uint8_t addr, char *data, uint8_t len)
{
start();
I2C_SendData(I2C1, addr);
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) == ERROR);
I2C_GenerateSTART(I2C1, ENABLE);
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) == ERROR);
I2C_SendData(I2C1, 0xa1);
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) == ERROR);
I2C_AcknowledgeConfig(I2C1, ENABLE);
while (len--)
{
if (len == 0)
{
I2C_AcknowledgeConfig(I2C1, DISABLE);
I2C_GenerateSTOP(I2C1,ENABLE); // 接收最后一字节数据前先准备好STOP信号
}
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED) == ERROR); // 等待当前数据接收完毕
*data++ = I2C_ReceiveData(I2C1);
}
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) == SET); // 等待停止信号发送完毕
}
void write_more(uint8_t addr, const char *data, uint8_t len)
{
start();
I2C_SendData(I2C1, addr);
while (len--)
{
I2C_SendData(I2C1, *data++);
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING) == ERROR); // 等待TXE
}
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) == ERROR); // 等待全部数据发送完毕
I2C_GenerateSTOP(I2C1,ENABLE);
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) == SET); // 等待停止信号发送完毕
}
int main(void)
{
char str[20];
GPIO_InitTypeDef gpio;
I2C_InitTypeDef i2c;
USART_InitTypeDef usart;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_USART1, ENABLE);
// 串口发送引脚设为复用推挽输出
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_9;
gpio.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio);
// I2C引脚设为复用开漏输出
gpio.GPIO_Mode = GPIO_Mode_AF_OD;
gpio.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init(GPIOB, &gpio);
USART_StructInit(&usart);
usart.USART_BaudRate = 115200;
usart.USART_Mode = USART_Mode_Tx;
USART_Init(USART1, &usart);
USART_Cmd(USART1, ENABLE);
I2C_StructInit(&i2c);
i2c.I2C_ClockSpeed = 100000;
I2C_Init(I2C1, &i2c);
I2C_Cmd(I2C1, ENABLE);
write(17, 0x31);
printf("read: 0x%02x\n", read(17));
write_more(17, "Hello!", 7); // 区域16~23
read_more(17, str, sizeof(str));
printf("str: %s\n", str);
write_more(8, "12345678ABCDEFG", 16); // 先将前8个字符写入地址8~15处, 然后回到地址8处写入剩下的字符, 包括最后的\0
read_more(8, str, sizeof(str));
printf("str: %s\n", str);
printf("I2C1->SR1=0x%04x, I2C1->SR2=0x%04x\n", I2C_ReadRegister(I2C1, I2C_Register_SR1), I2C_ReadRegister(I2C1, I2C_Register_SR2));
while (1)
__WFI();
}
【程序运行结果1】
read: 0x31
str: Hello!
str: ABCDEFG
I2C1->SR1=0x0000, I2C1->SR2=0x0000
两个SR寄存器的值都为0表明I2C正常工作。
I2c库函数用法
void Read_Reg(u8 *DataBuff,u8 ByteQuantity,uint16_t RegAddress,u8 SlaveAddress)
{
//这句去掉也正常
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // Added by Najoua 27/08/2008
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/* 发送器件地址(写)*/
I2C_Send7bitAddress(I2C1, SlaveAddress, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); /* EV7 */
//这句去掉也正常
/* Clear EV6 by setting again the PE bit */
I2C_Cmd(I2C1, ENABLE);
I2C_SendData(I2C1,01);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1,RegAddress>>8);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1,RegAddress);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/* 发送器件地址(写)*/
I2C_Send7bitAddress(I2C1, SlaveAddress, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); /* EV7 */
while (ByteQuantity)
{
if(ByteQuantity==1)
{
I2C_AcknowledgeConfig(I2C1, DISABLE); //最后一位后要关闭应答的
I2C_GenerateSTOP(I2C1, ENABLE); //发送停止位
}
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */
*DataBuff = I2C_ReceiveData(I2C1);
DataBuff++;
/* Decrement the read bytes counter */
ByteQuantity--;
}
//再次允许应答模式
I2C_AcknowledgeConfig(I2C1, ENABLE);
//errorflag=0;
//break;
}
void Write_Reg(uint16_t WriteValue,uint16_t RegAddress,u8 SlaveAddress)
{
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // Added by Najoua 27/08/2008
/ Send START condition /
I2C_GenerateSTART(I2C1, ENABLE);
/ Test on EV5 and clear it /
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/ Send EEPROM address for write /
I2C_Send7bitAddress(I2C1, SlaveAddress, I2C_Direction_Transmitter);
/ Test on EV6 and clear it /
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1,0x81);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1,RegAddress>>8);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1,RegAddress);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1,WriteValue>>8);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1,WriteValue);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/ Send STOP condition /
I2C_GenerateSTOP(I2C1, ENABLE);
}
/**
- @brief Transmits the address byte to select the slave device.
- @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
- @param Address: specifies the slave address which will be transmitted
- @param I2C_Direction: specifies whether the I2C device will be a
- Transmitter or a Receiver. This parameter can be one of the following values
- @arg I2C_Direction_Transmitter: Transmitter mode
- @arg I2C_Direction_Receiver: Receiver mode
- @retval None.
*/
void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction)
{
/ Check the parameters /
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
assert_param(IS_I2C_DIRECTION(I2C_Direction));
/ Test on the direction to set/reset the read/write bit /
if (I2C_Direction != I2C_Direction_Transmitter)
{
/* Set the address bit0 for read */
Address |= OAR1_ADD0_Set;
}
else
{
/* Reset the address bit0 for write */
Address &= OAR1_ADD0_Reset;
}
/ Send the address /
I2Cx->DR = Address;
}
define I2C_Direction_Transmitter ((uint8_t)0x00)
define I2C_Direction_Receiver ((uint8_t)0x01)
7位模式下,地址字节最低位若是0则说明主机要进入发送模式,若是1则是接收模式
学生假期外出流程
git使用
Git 不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等。
1.Git 安装配置
Debian/Ubuntu Git 安装命令为:
$ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev
$ apt-get install git
$ git --version
Centos/RedHat 安装命令为:
$ yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
$ yum -y install git-core
$ git --version
Windows 平台上安装
下载https://npm.taobao.org/mirrors/git-for-windows/
2.Git 配置
Git 提供了一个叫做 git config 的工具,专门用来配置或读取相应的工作环境变量。
通过命令git config -h可以查看帮助,设置生效范围有:
usage: git config [options]
Config file location
--global use global config file
--system use system config file
--local use repository config file
-f, --file <file> use given config file
--blob <blob-id> read config from given blob object
配置含义解释:
global 即是读/写当前用户全局的配置文件(~/.gitconfig 文件,属于某个计算机用户)
system 即是读写系统全局的配置文件(/etc/gitconfig 文件,属于计算机)
local 即是当前 clone 仓库 的配置文件(位于 clone 仓库下 .git/config)。
配置个人的用户名称和电子邮件地址:
$ git config --global user.name "runoob"
$ git config --global user.email test@runoob.com
要检查已有的配置信息::
$ git config --list
3.git 配置 https和ssh 免密码登录
https通过记住账号密码免登,ssh通过校验生成的密钥免登。 通常都用ssh校验。
https免密配置方法:
git config --global credential.helper store
[credential]
helper = store
输入一次账号密码后第二次就会记住账号密码。
ssh免密配置方法
git init
git config --global user.name '用户名'
git config --global user.email '用户邮箱'
执行生成公钥和私钥的命令:
ssh-keygen -t rsa -C "用于识别密钥的邮箱地址"
执行查看公钥的命令:
cat ~/.ssh/id_rsa.pub
将上面的id_rsa.pub内容复制粘帖到gitee.com或github.com的"setting--SSH keys"中
有时需要检查ssh的配置文件:
vi ~/.ssh/config
Host gitee.com
HostName gitee.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa
4. git clone 项目
https方式: git clone https://gitee.com/user_name/project_name.git
ssh方式: git clone git@gitee.com:user_name/project_name.git
5. git 提交项目
git status 查看状态
git add . 添加所有的修改文件
git status 查看状态
git commit -m '备注信息' 添加备注
git push origin master 提交到master分支上
5. git本地项目代码上传至远程仓库操作
建立一个本地仓库目录test
mkdir test
进入本地仓库目录
cd test
初始化:
git init
将本地仓库与已经存在的远程仓库(通过web进行创建)进行关联:
git remote add origin git@gitee.com:user_name/remote_project.git
操作提交master步骤:
git add .
git status
git commit -m '备注信息'
git push origin master
window设置UTC硬件时钟
硬件时钟是记录在BIOS中的时间。
对于Windows系统,默认会将BIOS中的硬件时钟当作Localtime,系统在关机时,Windows会将时间同步到硬件时间中去,因此BIOS时钟和系统时钟都成为Localtime.
对于Linux系统,默认会将BIOS中的硬件时钟当作UTC,系统在关机时,Windows会将时间同步到硬件时间中去,因此BIOS时钟和系统时钟都成为UTC.
为方便统一管理,建议Windows系统也设置为UTC
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation]
"RealTimeIsUniversal"=dword:00000001
将上面代码保存为win_utc.reg,双击执行win_utc.reg,重启windows即可。
ubuntu1604安装ctfd-whale动态靶机
1.安装python2
ubuntu1604默认已经安装python3.5
sudo apt install python2
2.安装pip3最新版
sudo wget https://bootstrap.pypa.io/pip/3.5/get-pip.py
python3 get-pip.py
3.安装docker社区版
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install -y docker-ce
sudo systemctl enable docker
sudo systemctl start docker
给普通用户user添加到docker组,使得该用户可以直接使用docker:
sudo usermod -aG docker dgq
4.安装docker-compose最新版
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
5.安装ctfd-whale动态靶机
sudo docker swarm init
docker node update --label-add='name=linux-1' $(docker node ls -q)
git clone https://github.com/VaalaCat/CTFd.git --depth=1
cd CTFd
git submodule update --init
docker-compose up -d
检查docker日志,看看ctfd是否 正常启动
docker logs ctfd_ctfd_1
在线靶场 CTF题目
收费完成靶场使用
1-5元使用一个靶场,靶场临时生成,完成后立即销毁
https://www.mozhe.cn/
有很多免费题目
http://bmzclub.cn
CTF解题BBS
https://www.xuenixiang.com
步进电机知识
ubuntu使用LXD容器
列出可用容器镜像
lxc image list tuna-images: centos |grep amd
下载并运行某个容器镜像
lxc launch tuna-images:
进入容器内部
sudo lxc exec yourcontainername bash
列出本机容器情况
sudo lxc list
表示从宿主机复制文件到容器
lxc file push
表示将容器的文件复制到主机
lxc file pull