发新帖本帖赏金 20.00元(功能说明)我要提问
12
返回列表
打印
[STM32F1]

大布丁丁-STM32F10x库函数学习笔记

[复制链接]
楼主: 13395410441
手机看帖
扫描二维码
随时随地手机跟帖
21
13395410441|  楼主 | 2016-2-1 17:23 | 只看该作者 回帖奖励 |倒序浏览
中断完了就得说说定时器中断了。
STM32中将定时器分为了两种: 通用定时器(TIMx) 以及基本定时器(TIM6和TIM7)和高级控制定时器(TIM1和TIM8) , 今天我们将要学习的是TIMx , 也就是STM32的通用定时器



以TIM2为例来看吧(这里使用到“ stm32f10x_conf.h”开放 #include"stm32f10x_tim.h" 、 #include"misc.h")
让定时器2每过一段时间点亮一个灯,实现流水灯。

使用特权

评论回复
22
lhp625| | 2016-2-2 14:06 | 只看该作者
楼主整理得不错!!

使用特权

评论回复
23
13395410441|  楼主 | 2016-2-2 18:00 | 只看该作者

大布丁丁-闪存FLASH的读写

本帖最后由 13395410441 于 2016-2-3 11:19 编辑

这个东西还是看看吧。从库函数给的例子可以看得出来:
#if defined (STM32F10X_HD) || defined (STM32F10X_HD_VL) || defined (STM32F10X_CL) || defined (STM32F10X_XL)
  #define FLASH_PAGE_SIZE    ((uint16_t)0x800)
#else
  #define FLASH_PAGE_SIZE    ((uint16_t)0x400)
#endif

#define BANK1_WRITE_START_ADDR  ((uint32_t)0x08008000)
#define BANK1_WRITE_END_ADDR    ((uint32_t)0x0800C000)

#ifdef STM32F10X_XL
#define BANK2_WRITE_START_ADDR   ((uint32_t)0x08088000)
#define BANK2_WRITE_END_ADDR     ((uint32_t)0x0808C000)
#endif /* STM32F10X_XL */
因为我用的是STM32F10X_MD,那个起始结束地址为 ((uint32_t)0x08008000)和 ((uint32_t)0x0800C000),页的大小是((uint16_t)0x400)。知道这些就够了,不懂的去看STM32使用手册。在嵌入式闪存那一节,第20页附近。
那个就这么定义:
#define FLASH_PAGE_SIZE    ((u16)0x400)   //USE_STM3210B
#define StartAddr          ((u32)0x08008000)
#define EndAddr            ((u32)0x0800C000)


uint32_t Data = 0x3210ABCD;//定义个数据
volatile FLASH_Status FLASHStatus;//定义一个FLASH_Status 类型的变量接收flash的状态。
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);        //清除 FLASH 待处理标志位,一共四个,想清全清了也行。
FLASHStatus = FLASH_ErasePage(StartAddr);//擦除一个 FLASH 页面,你也可以通过页面的大小FLASH_PAGE_SIZE    ,把所有页面都清除。尽量避免一次操作多次擦除,保护一下FLASH还是比较好的。也可以FLASH_EraseAllPages(void)擦除所有数据,自己去手册查查吧。


FLASHStatus = FLASH_ProgramWord(StartAddr,Data );//在起始地址开始写数据。


Data = (*(vu32*) StartAddr);//你可以这样读取数据。

-----------------------------------------简单说这么多----------------------------
以后用到再看吧。





使用特权

评论回复
24
13395410441|  楼主 | 2016-2-3 11:20 | 只看该作者
本帖最后由 13395410441 于 2016-2-3 13:59 编辑

I2C我总结一下:
1写周期时间是指从一个写时序的有效停止信号到内部编程/擦除周期结束的这一段时间在写周期期间总线接口电路禁能SDA保持为高电平器件不响应外部操作
2I2C总线协议规定,任何将数据传送到总线的器件作为发送器,任何从总线接收数据的器件为接收器。但由主器件控制传送数据发送或接收的模式。A0 1 2可以连接八个24wc02到总线上。
3I2C总线总线的SDASCL两条信号线同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。
4、在SDA上逐位地串行传送每一位数据,只有在SCL为低电平期间,才允许SDA上的电平改变状态。数据位的传输是边沿触发。
5I2C总线上的所有数据都是以8位字节传送的,发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。 应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示接收器已经成功地接收了该字节;应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。 对于反馈有效应答位ACK的要求是,接收器在第9个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平。 如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送,并释放SDA线,以便主控接收器发送一个停止信号P
6、在特殊情况下,如果需要禁止所有发生在I2C总线上的通信活动,封锁或关闭总线是一种可行途径,只要挂接于该总线上的任意一个器件将时钟线SCL锁定在低电平上即可。


24C02+I2C说一下地址位:
地址八位,高四位1010是芯片自身固定的,把它的三个地址位都设为0的话,第三位是000,最低一位,读24c02时是1,即1010 0001;写24c02时是0,即1010 0000

时钟线高的时候:地址线1-0跳变是起始信号,地址线 0-1跳变是停止信号。传送数据避免不了数据跳变,所以时钟线低的时候传送数据是可靠有效的。看一下手册,注意一点各个指令消耗的时间大小。
--------------------------往24c02写数据过程-----------------------------
1、启动(在SCL高电平时,SDA的 1->0的跳变是起始信号):SDA = 1;SCL = 1;SDA = 0;SCL = 0;//最后别忘时钟拉低奥,别忘了10us的延时奥,参考停止信号代码
2、发送写的器件地址(在SCL低电平时数据有效):起始的时候时钟线拉低了,放心发送数据吧。
3、发送要写的内存地址
4、发送数据(发送数据可以不需要应答信号,就是不判断应答信号,自己看着办吧)
5、停止信号(SCL高电平时,SDA的 1-0跳变是停止信号)        
       I2C_SDA = 0;
        I2C_Delay10us();
        I2C_SCL = 1;
        I2C_Delay10us();
        I2C_SDA = 1;
        I2C_Delay10us();        
--------------------这是起始信号之后的发送数据的内容,发送地址和数据都这么写就可以的------------------------------


       for(a=0; a<8; a++)//从最高位开始发送八位
        {
//这是移位,从高位发送数据
                I2C_SDA = dat >> 7;
                dat = dat << 1;
//这下面是时钟信号
                I2C_Delay10us();
                I2C_SCL = 1;
                I2C_Delay10us();
                I2C_SCL = 0;
                I2C_Delay10us();        
        }

//然后把SCL和SDA都拉高等待信号。
        I2C_SDA = 1;
        I2C_Delay10us();
        I2C_SCL = 1;

//最后等待应答,也就是while循环判断SDA数据线有没有自动拉低(可以设置个标志位来控制要不要判断应答信号),如果超过200us没有应答即SDA没有自动拉低就表示发送失败了,这时候做一些自己的处理拉低信号线SCL就退出吧。如果SDA拉低了这时候拉低信号线SCL退出就可以了。


-------------------------------------------从24c02读数据----------------------------------------
//先发送读的硬件地址和内存地址(24C02)
1、启动(在SCL高电平时,SDA的 1->0的跳变是起始信号):SDA = 1;SCL = 1;SDA = 0;SCL = 0;//最后别忘时钟拉低奥,别忘了10us的延时奥,参考停止信号代码
2、发送写的器件地址(在SCL低电平时数据有效):起始的时候时钟线拉低了,放心发送数据吧。
3、发送要写的内存地址

//再发送要写入的器件地址(单片机)
1、启动(在SCL高电平时,SDA的 1->0的跳变是起始信号):SDA = 1;SCL = 1;SDA = 0;SCL = 0;//最后别忘时钟拉低奥,别忘了10us的延时奥,参考停止信号代码
2、发送读的器件地址(在SCL低电平时数据有效):起始的时候时钟线拉低了,放心发送数据吧。
3、读数据(发送数据可以不需要应答信号,就是不判断应答信号,自己看着办吧)
4、停止信号(SCL高电平时,SDA的 1-0跳变是停止信号)        
       I2C_SDA = 0;
        I2C_Delay10us();
        I2C_SCL = 1;
        I2C_Delay10us();
        I2C_SDA = 1;
        I2C_Delay10us();



24C02—00001.pdf

3.33 MB

24C02—00002.pdf

2.47 MB

I2C总线信号时序总结.zip

118.84 KB

使用特权

评论回复
25
wangjianxing| | 2016-2-3 13:35 | 只看该作者
内容很多,关注一下

使用特权

评论回复
26
13395410441|  楼主 | 2016-2-3 14:32 | 只看该作者

24C02的I2C时序

本帖最后由 13395410441 于 2016-2-3 14:35 编辑

24C02I2C时序
SDA数据线  SCL时钟线SDASCL都是高电平时始终处于空闲状态)
下面读写时候20C02的读写的寻址地址一定要注意了,特别是选择读的时候。而且在读24C02里面的数据结束后一定要发送一个无应答信号(就是1),24C02才能停止发送数据释放SDA,你才能通过SDA发送停止信号的。
1、寻址地址8位(1 0 1 0 A2 A1 A1 R/W’),前四位芯片固定位1010,中间三位由A0 1 2 三个引脚决定,最低位是标志位,从24C02读是1,往24C02写是0
2、起始:
    时钟SCL高时,SDA从高变低 1-0
3、结束
    时钟SCL高时,SDA从低变高 0-1
4、24C02字节写数据时序是:(一个字节一个字节的写)一般网上的代码都是这种吧
    a) 起始信号
    b) 写24C02的地址信号+应答(SDA从高自动拉低算是应答成功)地址:1010 0000
    c) 写24C02的内存地址信号+应答
    d) 往刚才写的内存地址处开始写入数据+应答(可以在代码中设置标志位忽略它,随意)
    e) 结束信号
5、24C02页写数据时序是:(一次可以写16个字节)
    a) 起始信号
    b) 写24C02的地址信号+应答(SDA从高自动拉低算是应答成功)地址:1010 0000
    c) 写24C02的内存地址信号+应答
    d) 往刚才写的内存地址开始写入数据+应答(可以在代码中设置标志位忽略它,随意) 最多可以执行16次。
    e) 结束信号
6、24C02立即读数据(读一个字节)
    a) 起始信号
    b) 写24C02的地址信号+应答(SDA从高自动拉低算是应答成功)地址:1010 0001
    c) 从起始内存地址处开始读数据+无应答
    d) 结束信号
7、24C02选择读数据
    a) 起始信号
    b) 写24C02的地址信号+应答(SDA从高自动拉低算是应答成功)地址:1010 0000
    c) 写24C02的内存地址信号+应答
    d) 起始信号
    e) 写24C02的地址信号+应答(SDA从高自动拉低算是应答成功)地址:1010 0001
    f) 从指定内存地址处开始连续读数据
    g) 最后来个无应答才可以执行结束信号
    h) 结束信号
8、24C02连续读数据
    a) 起始信号
    b) 写24C02的地址信号+应答(SDA从高自动拉低算是应答成功)地址:1010 0001
    c) 从起始内存地址处开始读数据+应答
    d) 最后来个无应答才可以执行结束信号
   e) 结束信号

如果到这里还不是很清楚的话,我有空上传个代码上来说一下。上一楼24楼是我为另一个帖子”大布丁丁-单片机学习常用相关外设“写的一个连接,摘抄了一点51代码,写的有点乱,当时就放在这了也没动。有问题也可以看看上一楼,应该会有帮助。

使用特权

评论回复
27
huangcunxiake| | 2016-2-4 17:53 | 只看该作者
是不是在操作IO的输入输出功能时候,使用准双向上拉,可以通杀呢?

使用特权

评论回复
28
zhengshanjun| | 2016-2-7 14:04 | 只看该作者
:handshake

使用特权

评论回复
29
mega1702| | 2016-2-9 09:37 | 只看该作者
谢谢分享!!!

使用特权

评论回复
30
734774645| | 2016-2-10 07:25 | 只看该作者
好多权威机构提供的例程都是基于Keil4的。

使用特权

评论回复
31
玛尼玛尼哄| | 2016-2-10 14:34 | 只看该作者
大神的话那就没办法了,既然是大神自然不满足版本库,自己动手写自己封装的库也是轻而易举的事情。

使用特权

评论回复
32
bowei181| | 2016-2-17 09:25 | 只看该作者
好详细,前来学习

使用特权

评论回复
33
yanghaixia| | 2016-2-17 09:45 | 只看该作者
非常感谢,受益匪浅

使用特权

评论回复
34
想飞的猫星人| | 2016-2-25 14:36 | 只看该作者
不错不错

使用特权

评论回复
35
500days| | 2016-2-26 22:46 | 只看该作者
有没有内部flash做成U盘的例程呢

使用特权

评论回复
36
user12have| | 2016-3-1 14:59 | 只看该作者
关注了。
谢谢楼主!

使用特权

评论回复
37
HORSE7812| | 2016-3-1 22:19 | 只看该作者
顶起

使用特权

评论回复
38
minder| | 2016-4-8 12:20 | 只看该作者
谢谢分享

使用特权

评论回复
39
chwnin| | 2016-4-9 16:00 | 只看该作者
不错,记下了。。

使用特权

评论回复
发新帖 本帖赏金 20.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则