标签:
这段时间在做全国光电设计大赛,用到了px4的px4flow光流传感器,用软件模拟iic读取数据不定期会导致px4flow死机,查了资料和光流的源码,发现这个光流用了stm32的硬件iic,所以对软件模拟iic的时序要求可能更高一点所以在原子哥的iic程序上做了修改,代码测验后已经不会死机,做个笔记,保存一下。
1 #include "myiic.h"
2 #include "delay.h"
15
16 //初始化IIC
17 void IIC_Init(void)
18 {
19 GPIO_InitTypeDef GPIO_InitStructure;
20
21 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟
22
23 //GPIOB10,B11初始化设置
24 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
25 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
26 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
27 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
28 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
29 GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
30 IIC_SCL=1;
31 IIC_SDA=1;
32 }
33 //产生IIC起始信号
34 void IIC_Start(void)
35 {
36 SDA_OUT(); //sda线输出
37 IIC_SDA=1;
38
39 delay_us(1);
40
41 IIC_SCL=1;
42 delay_us(2); //4
43 IIC_SDA=0;//START:when CLK is high,DATA change form high to low
44 delay_us(2); //4
45 IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
46 }
47 //产生IIC停止信号
48 void IIC_Stop(void)
49 {
50 SDA_OUT();//sda线输出
51 IIC_SCL=0;
52
53 delay_us(1);
54
55 IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
56 delay_us(2); //4
57 IIC_SCL=1;
58
59 delay_us(1);
60
61 IIC_SDA=1;//发送I2C总线结束信号
62 delay_us(2); //4
63 }
64 //等待应答信号到来
65 //返回值:1,接收应答失败
66 // 0,接收应答成功
67 u8 IIC_Wait_Ack(void)
68 {
69 u8 ucErrTime=0;
70 SDA_IN(); //SDA设置为输入
71 IIC_SDA=1;
72 delay_us(1); //1
73 IIC_SCL=1;
74 delay_us(1); //1
75 while(READ_SDA) //可能可以把数搞大点
76 {
77 ucErrTime++;
78 if(ucErrTime>250)
79 {
80 IIC_Stop();
81 return 1;
82 }
83 }
84 IIC_SCL=0;//时钟输出0
85 return 0;
86 }
87 //产生ACK应答
88 void IIC_Ack(void)
89 {
90 IIC_SCL=0;
91
92 delay_us(1);
93
94 SDA_OUT();
95 IIC_SDA=0;
96 delay_us(2); //2
97 IIC_SCL=1;
98 delay_us(2); //2
99 IIC_SCL=0;
100 }
101 //不产生ACK应答
102 void IIC_NAck(void)
103 {
104 IIC_SCL=0;
105
106 delay_us(1);
107
108 SDA_OUT();
109 IIC_SDA=1;
110 delay_us(2); //2
111 IIC_SCL=1;
112 delay_us(2); //2
113 IIC_SCL=0;
114 }
115 //IIC发送一个字节
116 //返回从机有无应答
117 //1,有应答
118 //0,无应答
119 void IIC_Send_Byte(u8 txd)
120 {
121 u8 t;
122 SDA_OUT();
123 IIC_SCL=0;//拉低时钟开始数据传输
124 for(t=0;t<8;t++)
125 {
126 IIC_SDA=(txd&0x80)>>7;
127 txd<<=1;
128 delay_us(2); //对TEA5767这三个延时都是必须的 //2
129 IIC_SCL=1;
130 delay_us(2); //2
131 IIC_SCL=0;
132 delay_us(2); //2
133 }
134 }
135 //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
136 u8 IIC_Read_Byte(unsigned char ack)
137 {
138 unsigned char i,receive=0;
139 SDA_IN();//SDA设置为输入
140 for(i=0;i<8;i++ )
141 {
142 IIC_SCL=0;
143 delay_us(2); //2
144 IIC_SCL=1;
145 receive<<=1;
146 if(READ_SDA)
147 receive++;
148 delay_us(2); //1
149 }
150 if (!ack)
151 IIC_NAck();//发送nACK
152 else
153 IIC_Ack(); //发送ACK
154 return receive;
155 }
空行间隔的为新增延时,和注释不一样的为改了的延时
标签:
原文地址:http://www.cnblogs.com/Cmoadne/p/5652069.html