通常,我们调试一个芯片的时候,往往是编写程序---下载---更改---下载。。。这种方法固然好,但是像我这样的懒人不大喜欢,我喜欢找一种一劳永逸的方法来解决。于是,开始动手写了这个I am Master!顾名思义,就是将Nucleo作为一个主机,与我们需要使用的软件进行通信。可能这样说你不是很理解,没关系,下面还会一 一介绍的。
电脑作为控制端,通过串口与我们的Nucleo进行通信,而Nucleo根据电脑发送的字符,解析,并且产生一定的时序,与我们需要使用的芯片进行通信。
比如,电脑端通过串口向Nucleo发送 input 0 1 2,代表Nucleo需要将 0 1 2这三个引脚设置成为输入状态. 在我的程序中,将Nucleo左边的A0~A5作为IO部分,分别对应编号0-5。可以用于执行比较简单的任务。
注意:为了保证电脑端有一个良好的人机界面,大家务必使用能够满足linux终端要求的串口软件。比如puTTy,smartty。或者是超级终端。像一般的串口软件无法完成这个项目的要求。因为他们不能够改变字体的颜色。这里推荐大家使用smarTTY,如果使用puTTY的话需要更改我上传的程序。因为当我们按下Enter的时候,puTTY发送的是'',而smarTTY发送的是''。在附件中有最新的smarTTY的安装版软件。
如果在使用smarTTY的时候,发现换行符不能正确显示,请进行这样的设置:
版本更新介绍:
V1.0.0支持函数:
- input
- output
- set
- reset
- toggle
- read
- spi
- spi-config
- man
V1.0.1新增函数:
- servo
- i2c-online
- i2c-write
- i2c-read
V1.0.2更新说明:
- 将i2c-online更改为i2c-scan
- i2c-read命令新增参数-a 可以用于在读取中指定一个寄存器地址。例如:从设备地址为0x90,寄存器地址为0x00的设备处读取1个字节可以使用 i2c-read -d 0x90 -a 0x00 -r 1 。需要注意的是:如果寄存器地址多于1个字节,只能先使用先写地址,在读的方式。例如:从设备地址为0x90,寄存器地址为0x0100的设备处读取1个字节只能分成两部:(1) i2c-write -d 0x90 0x01 0x00 (2) i2c-read -d 0x90 -r 1
- 新增函数clear,用于清屏。
V1.0.3更新说明:
- 为了在STM32系列中的可移植性,进行了一些并无实际卵用的更新。新建了config.h头文件。STM32F3系列的其余Nucleo包马上就会放出。
- 修复了在不输入任何字符,仅按下回车的情况下,提示Unknow command的bug。
V1.0.4更新说明:
- 上电之后SPI的模式被修改为模式0,时钟为4Mhz。
- SPI读取(由-r参数指定的)数据被缓冲,使相临两次读取的时间由原先的100us缩减为7us。
- 串口数据改为中断输入方式,使用RingBuffer(1KB)进行缓存。
- 支持发送命令文件。即将所有要发送的命令写入文件,每一条命令占用一行,通过smarTTY直接发送文件。具体的细节请参考本帖第6楼。
v2.0.0(重要更新)。
- 优化代码结构。如果仅仅为了使用,而不是阅读代码的话,那么这次更新并无卵用。
- 不再使用占用大量CPU时间的printf,改为termiosXXX函数。
- 从gcc库中移植getopt。为命令行解释提供了统一的方法。
- shell函数解析的时候,将使用 "" 引起的字符作为一个参数。不管""内的字符是不是含有空格。例如:输入spi [ "Hello world" 0x24 0xff ] ,经过shell解析传给spi的命令参数为:argv[0]==spi , argv[1] =[ , argv[2] ="Hello world" ,argv[3]= 0x24, argv[4]=0xff, argv[5] = ] 。注意:"Hello world"是一个参数,不同于windows和linux,这里为参数保留了引号。
- 修改spi-config,如果spi-config未提供任何参数,将显示出现在spi的模式。包括模式,时钟频率,Msb/Lsb First。如果提供参数,将对参数进行解析。
:
吐槽,意见,或者建议请联系(PS有没有E语好的大神,帮忙翻译一下man的说明部分):
qianfanguijin@163.com
qianfanguijin@gmail.com
版权声明:
本软件仅供与学习交流之用,未经允许,不得用于商业用途。
I am master v2.0.rar
(2.3 MB, 下载次数: 8)
I am masterv1.0.0.rar
(1.6 MB, 下载次数: 7)
I am masterv1.0.1.rar
(2.22 MB, 下载次数: 7)
I am masterV1.0.2.rar
(2.22 MB, 下载次数: 7)
I am masterV1.0.3.rar
(2.22 MB, 下载次数: 7)
I am masterV1.0.4.rar
(2.24 MB, 下载次数: 7)
master.hexV1.0.4hex文件.rar
(21.51 KB, 下载次数: 7)
SmarTTY-2.0.rar
(4.14 MB, 下载次数: 7)
--------------------------------------
使用入门:
- 从附件中下载工程文件I am master 和 smarTTY软件并解压。
- 打开工程,将hex文件下载至Nucleo334.将使用HSI作为时钟源。
- 打开smarTTY,新建一个串口通信,115200,8bit,无校验,停止位1.
Nucleo通电之后,通过串口发送这样的信息:
先来认识一个命令 man ,类似于linux中的man 。当你遇到某一个命令而不知道如何使用的时候,可以使用这个命令。比如获取input这个命令的解释:
这个命令的功能是将引脚设置成为输入模式,引脚的范围是0-5,对用Arduino接口的A0-A5.现在,我们在0号引脚上面挂接一个LED,在1号引脚上面挂在一个开关(平时为1,按下为0)。可以通过input,output两条命令来切换他们的模式:
在将引脚设置成为输出模式之后,就可以使用set,reset,toggle三条命令来设置引脚了。set是置1,reset是清零,toggle是反转。如果引脚的模式是输入模式,可以使用read来读取。如果read的参数不是0-5范围之内,那么显示的数值就会用N来代替。例如read 0 1 255
==> 1 1 N
显示0,1引脚的电平值为1,255是一个非法引脚。
其余命令的解释大家可以使用man来查看。我的英语很不好,man的解释大部分都是通过谷歌翻译的。大家可以帮助修改一下源文件的翻译,还请告知。谢谢!
在我们平时的调试中,光使用IO接口恐怕难以满足我们的要求。还需要一些更复杂的通信协议,比如说SPI。下面我们就来说说SPI的使用。
不管什么时候,man总是我们靠谱的好朋友。
在SPI通信上,使用板子上面表示的SPI引脚。这里就不详细解释了。可以看一下板子上面的丝印。
spi的参数有着固定的要求:
- [ 表示将CS信号线拉低。注意[也是一个参数,后面需要至少一个空格;
- r:9表示从SPI总线上读取多少个字符。后面的9代表读取9个字符,需要使用十进制表示。
- 其余的参数使用十六进制表示,不区分大小写。前缀可以加0x,也可以不加。想FF,ff,0xFF表示的都是同一个数。
- ] 表示将CS信号拉高。同样 ] 也是一个参数,需要后面至少一个空格。
好了,就这么多,下面就来通过spi这条命令,读写SPI存储芯片W25X16.他的数据手册在附件中,大家可以下载学习一下。
先看W25的一个指令表:
在原PDF的第17页。可以看到上面有一条指令是读ID,解释如下:
在面包板上面插好线之后,使用spi命令与之进行通信:
回应了两个数字,0xEF,0x14,正好与上表的数据吻合。说明通信正确。
通过查看数据手册可以看出,要想往一个地址内写数据,首先要写一个WriteEnable命令,在写完WriteEnable命令之后,StatusRegister寄存器中相应的WEL为会被置1,说明允许写。
在写完WriteEnable命令之后,可以看到WEL位已经被置1了,说明操作正确。
下面将第一扇区格式化,之后往里写如一些数据:
0x20是格式化命令,格式化命令之后WEL位被清零,说明不能在继续写数据。为了能够继续写数据,只好在重新发送一遍WriteEnable命令了。
读取一下格式化之后0x00处连续10个地址的数据:读取的命令是0x03
数据全是0xFF,说明格式化成功了。下面再将0x00连续地址处写如0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A十个数字,写入之后再读取:
这里写入了10个数据,读取了11个数据,可以看到第11个数据是0xff,也就是没有被更改,写入和读取都正确。
好了,spi的操作就说到这里。
当然,你可能疑问,这使用了默认的模式3,如果我想使用模式0怎么办呢?大家可以使用man spi-config寻找答案。
:
102801-0001R-SPIFlash.pdf
(1.26 MB, 下载次数: 7)
一起来开发,定制你自己的命令
可能你觉得这些命令远远不够用,或者你希望定制一个你自己的命令,比如man 你的名字。其实,定制一个这样的命令是一个很简单的事情。
在串口中接受到的字符,最终是要交给shell [void shell ( char * cmd_str) ; ]这个程序来处理的,这个程序将串口接收到的一行字符,在空格处分割,并且转换成为int argc,char *argv[]的形式。这个形式是man函数的标准形式。argv[0]表示的需要调用的应用程序的名字。例如串口输入input 0 1 2,经过shell的处理之后:
- argc=4;
- argv[0]="input"
- argv[1]="0"
- argv[2]="1"
- argv[3]="2"
- argv[4]=NULL
处理之后,shell去一个cmdList列表中寻找名字叫做input的函数。如果找到了,将控制权和argc,argv一起交给input函数。而input就是我们需要编写的,只需要遍历argv,读取每一个引脚的编号,并且设置成为输出即可。具体shell函数在cmdList中寻找input函数的方法在后文中会详细讲到。
下面是一个简单的input函数的实现:
int input(int argc,char *argv[])
{
int i=0;
for(i=0;i<argc;i++)
{
//设置argv表示的引脚为输入方式
}
}
好了,下面就来说说定制命令的详细步骤:
- 每一个命令都需要一个入口函数,格式是int test (int argc,char *argv[])。
- 每一个命令都需要一个解释函数,用于man的调用。格式是void manTest(void);当然,函数的名字可以自己取。
- 计算函数名字的hash,用于shell快速寻找函数的入口点。不过这个hash只是特别简单的计算方法,在后续的更新中,会考虑更换他的计算方法。目前的方法主要是将函数的名字的各个字符异或(^ )。在工程文件下tools/computer_xor下有一个xor.exe,是用于计算hash的。只要在控制台下调用这个程序,参数写你需要求的字符串。例如:
- 上面算出的test的hash值是0x16,记下这个数字,我们在后续中会使用到。
- 打开commands.h,在里面添加两个函数的声明:test和manTest:
- 打开commands.c文件,在cmdList中添加manTest和test:
- 新建一个源文件,test.c,并添加到工程中。写上test和manTest两个函数的实现:
- 好了,目前一切需要做的已经做好了,编译,下载,打开smarTTY,稍微测试一下:
更多更有趣的功能欢迎你来实现!
-----------------------------------------------------------------
在v1.0.1版本中,新增了四个命令,servo,用于控制舵机的。函数的参数在500~2500之间,代表在舵机的50000us中,高电平占用的时间。比如servo 1000代表高电平是1000us,占空比是1000/50000=2%。但是写完之后发现控制舵机并没有什么卵用。因此这里就不再多废话了,主要是讲如何使用I2C接口。
I2C
STM32F1和STM32F4使用的I2C接口是一类,用起来各种复杂,不好用。但是STM32F3的I2C却非常好用。之前看见有人说STM32的I2C是鸡肋,只能说明他没有用过STM32F3的。下面就说说I2C如何使用。主要操作的芯片是LM75,一个温度传感器。
首先介绍三个命令:
- i2c-online:用于获取挂接在I2C接口上所有芯片的设备地址。
- i2c-write:将数据通过I2C接口发送出去。必须指定的参数:-d(设备地址)。
- i2c-read:通过I2C接口读取制定数量字节。必须指定的参数:-d(设备地址),-r(读取的字节数)。
- 注:在V1.0.2版本中,将命令i2c-online改名为i2c-scan
- 注:在V1.0.2版本中,i2c-read新增参数-a,用于指定需要读取的寄存器地址。
为了编写程序的简便,I2C的操作使用流的方式,即只能采用内置的通信方式(START,STOP)。不能指定RESTART。一般的I2C的读取操作是 START+devAddr[Write]+regAddr+ReStart+devAddr[Read]+{some bytes}+STOP。由于不能采用ReStart,所以像这样的读取应该分成先写在读两部分,即:
- START+devAddr[Write]+regAddr+STOP
- START+devAddr[Read]+{read some bytes}+STOP
- devAddr代表设备地址
- regAddr代表需要读取或者写入的寄存器地址。
我的I2C总线上挂接了一个LM75,但是我懒得查数据手册去找他的设备地址,所以可以使用i2c-online查看所有在线的i2c设备的设备地址:
注:在V1.0.2种将i2c-online更改为i2c-scan,并根据设备地址添加了提示。如下图。
通过这条命令查出了唯一的地址,0x90 。那么这个地址就是LM75的设备地址了。之后我们要进行的读和写的操作都要靠这个地址。其实这条命令的实现很简单,只不过从0-127挨个询问,看设备是否应达就行,通过逻辑分析仪抓包如下:(只截取了部分)
好了,有了地址就可以进行操作了,先来看看LM75的寄存器:
从上图中可以看出,0x00是温度寄存器的地址。要想读这个地址处的数值,必须首先发送寄存器地址:
i2c-write必须要有-d参数,用于指示设备地址。其余的数据是要发送的数值。如果想通过i2c发送0x00 0x01 0x02 0x03 这四个数字可以使用这样的命令:
- i2c-write -d 0x90 0x00 0x01 0x02 0x03
- i2c-write 0x00 0x01 0x02 0x03 -d 0x90
- i2c-write 0x00 0x01 -d 0x90 0x02 0x03
- ...
设备地址0x90必须紧跟在-d的后面。除了i2c-write的位置之外,出现在什么地方都是可以的。
在发送完寄存器地址之后,就可以读取寄存器中的数值了。查看数据手册,可以看到LM75的温度寄存器由两个字节组成。在发送的时候先发送高字节,在发送低字节。
之后将两个字节合并成一个16位的有符号数字,数字使用2的补码表示。正温度有正的有符号数表示(最高为是0),负温度的最高位是1 。之后将数据去掉符号右移5位,加上符号,乘以0.125就是所需的温度值。这里有几个事例值,感兴趣的话可以算一下:
先使用i2c-read来读取一下这两个字节:高字节在前:
最后来计算一下结果:0x16C0 >> 5 =0xB6 =186
所以温度值为186*0.125=23.25
可以看出,烟台的晚上还是非常凉爽的!
注:在V1.0.2版本中,i2c-read函数新增参数-a,用于指定寄存器地址(寄存器地址只能为1个字节。如果寄存器地址多于1个字节,只能使用先写在读的方式进行操作)。
另外,需要补充一点的是,i2c-write和i2c-read在正确写入和读取的时候不会输出任何信息的。只有在发生错误的时候才会进行提示:
LM75A.pdf
(137.07 KB, 下载次数: 7)
--------------------------------------------------------------------
V1.0.4命令文件说明
在1.0.4版本中,新增了直接发送命令文件这一特色。下面就针对命令文件结合TCP/IP芯片W5100,进行一下说明。
5100使用SPI方式进行通信,并且仅仅支持模式0. 还需要注意的是,对5100芯片进行读写的时候,SPI的速率不能太低。在之前的操作中,发现使用256KHz的SPI进行通信,不能正常的进行读写。因此在1.0.4版本中,将SPI的时钟频率提升到了4MHz。
上图是SPI通信的协议图。分为3部分。第一部分是操作码。读的时候,操作码是0x0F
,写的时候操作码是0xF0 。 第二部分是5100寄存器地址,2个字节,分为两次发送。第三部分是需要写的数据。1个字节。
看一下相关的寄存器:
比如说设置本机IP,就要分四次来写(本机IP由4个字节组成,每次只能对1个字节进行读写),如果设置成为192.168.1.3,那么应该使用这样的命令:
- spi [ 0xf0 0x00 0x0f 0xc0 ]
- spi [ 0xf0 0x00 0x10 0xa8 ]
- spi [ 0xf0 0x00 0x11 0x01 ]
- spi [ 0xf0 0x00 0x12 0x03 ]
除了本机IP,还需要设置网关IP,子网掩码,MAC地址,共需要20次操作:
- spi [ 0xf0 0x00 0x01 0xc0 ]
- spi [ 0xf0 0x00 0x02 0xa8 ]
- spi [ 0xf0 0x00 0x03 0x01 ]
- spi [ 0xf0 0x00 0x04 0x01 ]
- spi [ 0xf0 0x00 0x05 0xff ]
- spi [ 0xf0 0x00 0x06 0xff ]
- spi [ 0xf0 0x00 0x07 0xff ]
- spi [ 0xf0 0x00 0x08 0x00 ]
- spi [ 0xf0 0x00 0x09 0xde ]
- spi [ 0xf0 0x00 0x0a 0xad ]
- spi [ 0xf0 0x00 0x0b 0xbe ]
- spi [ 0xf0 0x00 0x0c 0xef ]
- spi [ 0xf0 0x00 0x0d 0xfe ]
- spi [ 0xf0 0x00 0x0e 0xed ]
- spi [ 0xf0 0x00 0x0f 0xc0 ]
- spi [ 0xf0 0x00 0x10 0xa8 ]
- spi [ 0xf0 0x00 0x11 0x01 ]
- spi [ 0xf0 0x00 0x12 0x03 ]
- spi [ 0x0f 0x00 0x01 r:1 ]
- spi [ 0x0f 0x00 0x02 r:1 ]
- spi [ 0x0f 0x00 0x03 r:1 ]
- spi [ 0x0f 0x00 0x04 r:1 ]
复制代码
在每次给5100通电的时候,都需要重新发送一下这样的字符,太麻烦了,所以索性将这些命令保存在一个txt文件中,直接通过smarTTY发送文件:
点击smarTTY中的send a binary file(在上图中用圆圈圈出),选择w5100.txt :
最后四个命令是读取网关的ip地址。在设置完这些寄存器之后,就可以使用windows上的ping命令来测试一下了:
断开5100的网线再ping一下:
w5100.txt.rar
(214 Bytes, 下载次数: 7)
w5100_Datasheet_cn.pdf
(1.8 MB, 下载次数: 7)
W5100_Datasheet_v1.2.5.pdf
(1.61 MB, 下载次数: 7)
-------------------------------------------------------------
</argc;i++)
|