子页网站设计那几个网站可以做h5
子页网站设计,那几个网站可以做h5,网站建设与开发要学什么专业,百度广告联盟怎么赚钱最近一段时间在做I2C通信协议#xff0c;需要在两块STM32之间做I2C通信#xff0c;定的是主机用IO口模拟#xff0c;从机用的是STM32的硬件I2C#xff0c;我的项目要求是需要主从机之间能够进行一串数据收发而不出错#xff0c;实验时在主机方面#xff0c;利用IO口模拟主…最近一段时间在做I2C通信协议需要在两块STM32之间做I2C通信定的是主机用IO口模拟从机用的是STM32的硬件I2C我的项目要求是需要主从机之间能够进行一串数据收发而不出错实验时在主机方面利用IO口模拟主机只需要理解时序就够了同时将速度能够控制在100K标准左右基本的时序理解网上大把的资料所以主机这一块几个小时就搞定了而在做从机时遇到了困难本来从机也想用IO口模拟的但是速度达不到那么快因此只能选择硬件做从机现就从机用中断方式开说总结过程中遇到的几点问题
1、由于STM32的硬件问题建议在使用I2C时将其优先级设为最高。
2、针对程序中除了I2C数据收发还有别的中断程序或者指令要执行而导致I2C数据传输堵塞时可以在执行完该段程序后重新初始化I2C。
主机程序如下 1 #include Hal_IIC/I2C.h2 #include Hal_delay/delay.h3 #include common.h4 #include gizwits_product.h5 6 extern void delayUs(uint32_t nus);7 uint8_t b[5];8 extern uint8_t Cookr[5];9 extern uint8_t WR_flag;10 uint8_t Wifi_SET; //WIFI状态脚11 extern uint8_t Power_flag; //电磁炉开启关闭标志位12 uint8_t Give_Up;13 /*--------------------------------------------------------------------------------14 调用方式void IIC_Init(void) 15 函数说明私有函数I2C专用函数初始化16 ---------------------------------------------------------------------------------*/ 17 void IIC_Init(void)18 { 19 GPIO_InitTypeDef GPIO_InitStructure;20 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); //使能GPIOA时钟21 22 GPIO_InitStructure.GPIO_Pin GPIO_Pin_11|GPIO_Pin_12;23 GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP ; //推挽输出24 GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;25 GPIO_Init(GPIOA, GPIO_InitStructure);26 GPIO_SetBits(GPIOA,GPIO_Pin_11|GPIO_Pin_12); //PA11,PA12 输出高27 }28 /*--------------------------------------------------------------------------------29 调用方式void I2CStart(void) 30 函数说明私有函数I2C专用开始信号31 ---------------------------------------------------------------------------------*/32 void IIC_Start(void)33 {34 SDA_OUT(); //sda线输出35 IIC_SDA1; 36 IIC_SCL1;37 delayUs(4);38 IIC_SDA0;//START:when CLK is high,DATA change form high to low 39 delayUs(4);40 IIC_SCL0; //钳住I2C总线准备发送或接收数据 41 } 42 /*--------------------------------------------------------------------------------43 调用方式void I2CStop(void) 44 函数说明私有函数I2C专用停止信号45 ---------------------------------------------------------------------------------*/46 void IIC_Stop(void)47 {48 SDA_OUT();//sda线输出49 IIC_SCL0;50 IIC_SDA0;//STOP:when CLK is high DATA change form low to high51 delayUs(4);52 IIC_SCL1; 53 IIC_SDA1;//发送I2C总线结束信号54 delayUs(4); 55 }56 /*--------------------------------------------------------------------------------57 调用方式I2CAck(void) 58 函数说明私有函数I2C专用等待从器件接收方的应答0表示接受成功1表示失败59 ---------------------------------------------------------------------------------*/60 uint8_t IIC_Wait_Ack(void)61 {62 uint8_t ucErrTime0;63 SDA_IN(); //SDA设置为输入 64 IIC_SDA1;delayUs(1); 65 IIC_SCL1;delayUs(1); 66 while(READ_SDA)67 {68 ucErrTime;69 if(ucErrTime250)70 {71 IIC_Stop();72 return 1;73 }74 }75 IIC_SCL0;//时钟输出0 76 return 0; 77 } 78 /*--------------------------------------------------------------------------------79 调用方式void SendAck(void) 80 函数说明私有函数I2C专用主器件为接收方从器件为发送方时应答信号。81 ---------------------------------------------------------------------------------*/82 void IIC_Ack(void)83 {84 IIC_SCL0;85 SDA_OUT();86 IIC_SDA0;87 delayUs(2);88 IIC_SCL1;89 delayUs(2);90 IIC_SCL0;91 }92 /*--------------------------------------------------------------------------------93 调用方式void SendAck(void) 94 函数说明私有函数I2C专用主器件为接收方从器件为发送方时非应答信号。95 ---------------------------------------------------------------------------------*/ 96 void IIC_NAck(void)97 {98 IIC_SCL0;99 SDA_OUT();
100 IIC_SDA1;
101 delayUs(2);
102 IIC_SCL1;
103 delayUs(2);
104 IIC_SCL0;
105 }
106 /*--------------------------------------------------------------------------------
107 调用方式void IIC_Send_Byte(unsigned char ch)
108 函数说明私有函数I2C专用
109 ---------------------------------------------------------------------------------*/
110 void IIC_Send_Byte(uint8_t txd)
111 {
112 uint8_t t;
113 SDA_OUT();
114 IIC_SCL0;//拉低时钟开始数据传输
115 for(t0;t8;t)
116 {
117 //IIC_SDA(txd0x80)7;
118 if((txd0x80)7)
119 IIC_SDA1;
120 else
121 IIC_SDA0;
122 txd1;
123 delayUs(2); //对TEA5767这三个延时都是必须的
124 IIC_SCL1;
125 delayUs(2);
126 IIC_SCL0;
127 delayUs(2);
128 }
129 }
130 /*--------------------------------------------------------------------------------
131 调用方式unsigned char IIC_Read_Byte(void)
132 函数说明私有函数I2C专用
133 ---------------------------------------------------------------------------------*/
134 //读1个字节ack1时发送ACKack0发送nACK
135 uint8_t IIC_Read_Byte(unsigned char ack)
136 {
137 unsigned char i,receive0;
138 SDA_IN();//SDA设置为输入
139 for(i0;i8;i )
140 {
141 receive1;
142 IIC_SCL0;
143 delayUs(5);
144 IIC_SCL1;
145 delayUs(5);
146
147 if(READ_SDA)receive;
148
149 }
150 if (!ack)
151 IIC_NAck();//发送nACK
152 else
153 IIC_Ack(); //发送ACK
154 return receive;
155 }
156
157
158 //读温度传感器温度值是由h的高字节和低字节的高四位组成总共12位其中负温度值是由补码形式
159 void T_Read(void)
160 {
161
162 /***************read start*******************/
163 if(WR_flag0x02)
164 {
165
166 IIC_Start();
167 IIC_Send_Byte( 0x30|0x01); //读操作
168 while(IIC_Wait_Ack());
169 // delayMs(500); //等待从机处理一个字节地址位
170 Give_Up IIC_Read_Byte(1);
171 for(uint8_t i0;i4;i)
172 {
173 b[i] IIC_Read_Byte(1);
174 printf(%c,b[i]);
175 }
176 b[4] IIC_Read_Byte(0);
177 printf(%c,b[4]);
178
179 if((b[0]0xFA)(b[4]0xFB))
180 {
181 for(uint8_t i1;i6;i)
182 {
183 Cookr[i] b[i];
184 }
185
186 }
187 }
188
189 /****************read end********************/
190 /****************write start*****************/
191 if(WR_flag0x01)
192 {
193 IIC_Start();
194 IIC_Send_Byte(0x30); //写操作
195 while(IIC_Wait_Ack());
196 IIC_Send_Byte(0xFA);
197 while(IIC_Wait_Ack());
198 delayMs(3); //延时太低传输数据会出错,因为从机还没处理完数据
199 IIC_Send_Byte(Cookr[1]);
200 while(IIC_Wait_Ack());
201 delayMs(3);
202 IIC_Send_Byte(0x03);
203 while(IIC_Wait_Ack());
204 delayMs(3);
205 IIC_Send_Byte(Power_flag);
206 while(IIC_Wait_Ack());
207 delayMs(3);
208 IIC_Send_Byte(0xFB);
209 while(IIC_Wait_Ack());
210 delayMs(3);
211 IIC_Stop();
212 WR_flag0x02;
213 }
214 /***************write end*****************/
215
216 } 从机使用中断方式 1 #include myiic.h2 #include delay.h3 #include led.h4 #include key.h5 #include usart.h6 7 8 #define MY_I2C_ADDRESS 0x30 //模拟从机地址9 unsigned char b[5]{0x00,0x00,0x00,0x00,0x00}; //从机接收操作10 uint8_t Wifi_Set0x00;11 extern u8 flag; //电磁炉开关中断位12 unsigned char a[5]{0xFA,0x00,0x00,0x00,0xFB}; 13 //初始化IIC14 void I2C1_Init(void)15 {16 GPIO_InitTypeDef GPIO_InitStructure;17 I2C_InitTypeDef I2C_InitStructure;18 NVIC_InitTypeDef NVIC_InitStructure;19 20 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); // enable APB1 peripheral clock for I2C121 22 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // enable clock for SCL and SDA pins23 24 GPIO_InitStructure.GPIO_Pin GPIO_Pin_6 | GPIO_Pin_7;25 GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;26 GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_OD; //I2C必须开漏输出实现线与逻辑27 GPIO_Init(GPIOB, GPIO_InitStructure);28 29 30 I2C_InitStructure.I2C_ClockSpeed 100000; // configure I2C1 31 I2C_InitStructure.I2C_Mode I2C_Mode_I2C;32 I2C_InitStructure.I2C_DutyCycle I2C_DutyCycle_2;33 I2C_InitStructure.I2C_OwnAddress1 MY_I2C_ADDRESS;34 I2C_InitStructure.I2C_Ack I2C_Ack_Enable;35 I2C_InitStructure.I2C_AcknowledgedAddress I2C_AcknowledgedAddress_7bit;36 I2C_Init(I2C1, I2C_InitStructure);37 38 //setup interrupts39 I2C_ITConfig(I2C1, I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF, ENABLE); 40 41 42 // Configure the I2C event priority43 NVIC_InitStructure.NVIC_IRQChannel I2C1_EV_IRQn;44 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 1; //抢占优先级145 NVIC_InitStructure.NVIC_IRQChannelSubPriority 0; //响应优先级046 NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE;47 NVIC_Init(NVIC_InitStructure);48 49 // enable I2C150 I2C_Cmd(I2C1, ENABLE);51 }52 53 54 //Clear ADDR by reading SR1, then SR255 56 void I2C_clear_ADDR(I2C_TypeDef* I2Cx) {57 I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR);58 ((void)(I2Cx-SR2));59 }60 61 //Clear STOPF by reading SR1, then writing CR162 63 void I2C_clear_STOPF(I2C_TypeDef* I2Cx) {64 I2C_GetFlagStatus(I2Cx, I2C_FLAG_STOPF);65 I2C_Cmd(I2Cx, ENABLE);66 }67 68 /*--------------------------------------------------------------------------------69 调用方式void I2C1_EV_IRQHandler(void) 70 函数说明私有函数I2C专用中断按键处理函数从机中断都在这里面执行71 ---------------------------------------------------------------------------------*/72 73 uint8_t data 0;74 uint8_t S_data0;75 void I2C1_EV_IRQHandler(void) 76 {77 // KV10; //只是一个测试灯78 //Clear AF from slave-transmission end79 if(I2C_GetITStatus(I2C1, I2C_IT_AF)) 80 {81 I2C_ClearITPendingBit(I2C1, I2C_IT_AF);82 }83 //Big state machine response, since doesnt actually keep state84 switch(I2C_GetLastEvent(I2C1)) 85 {86 //SLAVE87 //Receive88 case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: //EV189 I2C_clear_ADDR(I2C1);90 break;91 case I2C_EVENT_SLAVE_BYTE_RECEIVED: //EV292 //Read it, so no one is waiting, clears BTF if necessary93 b[data] I2C_ReceiveData(I2C1);94 // printf(%c,b[data]);95 data;96 if(data5)97 {98 data0;99 if((b[0]0xFA)(b[4]0xFB))
100 {
101 a[1]b[1];
102 Wifi_Setb[2];
103 flagb[3];
104 // printf(%c,a[1]);
105 }
106
107 }
108 if(I2C_GetFlagStatus(I2C1, I2C_FLAG_DUALF))
109 {//Secondary Receive
110 }
111 else if(I2C_GetFlagStatus(I2C1, I2C_FLAG_GENCALL))
112 {//General Receive
113 }
114 else
115 {//Normal
116 }
117 break;
118 case I2C_EVENT_SLAVE_STOP_DETECTED: //End of receive, EV4
119 I2C_clear_STOPF(I2C1);
120 break;
121
122 //Transmit
123 case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: //EV1
124 I2C_clear_ADDR(I2C1);
125 //Send first byte
126 I2C_SendData(I2C1, 0x00);
127
128 break;
129 case I2C_EVENT_SLAVE_BYTE_TRANSMITTED: //EV3
130 //Determine what you want to send
131 //data 5;
132 if(I2C_GetFlagStatus(I2C1, I2C_FLAG_DUALF))
133 {//Secondary Transmit
134 }
135 else if(I2C_GetFlagStatus(I2C1, I2C_FLAG_GENCALL))
136 {//General Transmit
137 }
138 else
139 {//Normal
140 }
141 //Read flag and write next byte to clear BTF if present
142 I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF);
143 I2C_SendData(I2C1, a[S_data]);
144 S_data;
145 if(S_data5)
146 S_data0;
147 break;
148 case I2C_EVENT_SLAVE_ACK_FAILURE://End of transmission EV3_2
149 //TODO: Doesnt seem to be getting reached, so just
150 //check at top-level
151 I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
152 break;
153 //Alternative Cases for address match
154 case I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED: //EV1
155 break;
156 case I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED: //EV1
157 break;
158 case I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED: //EV1
159 break;
160
161
162 //MASTER
163 case I2C_EVENT_MASTER_MODE_SELECT: //EV5, just sent start bit
164 break;
165 //Receive
166 case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: //EV6, just sent addr
167 break;
168 case I2C_EVENT_MASTER_BYTE_RECEIVED: //EV7
169 break;
170 //Transmit
171 case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: //EV6, just sent addr
172 break;
173 case I2C_EVENT_MASTER_BYTE_TRANSMITTING: //EV8, about to send data
174 break;
175 case I2C_EVENT_MASTER_BYTE_TRANSMITTED: //EV8_2, just sent data
176 break;
177
178 //Alternative addressing stuff, not going to worry about
179 case I2C_EVENT_MASTER_MODE_ADDRESS10: //EV9
180 break;
181 default:
182 //How the FUCK did you get here?
183 //I should probably raise some error, but fuck it,
184 //its late
185 break;
186
187 }
188
189
190 }
191
192 void I2C1_ER_IRQHandler(void) {
193 // GPIO_SetBits(GPIOD, RED);
194 // LED30;
195 //Cant use nice switch statement, because no fxn available
196 if(I2C_GetITStatus(I2C1, I2C_IT_SMBALERT)) {
197 } else if(I2C_GetITStatus(I2C1, I2C_IT_TIMEOUT)) {
198 } else if(I2C_GetITStatus(I2C1, I2C_IT_PECERR)) {
199 } else if(I2C_GetITStatus(I2C1, I2C_IT_OVR)) {
200 //Overrun
201 //CLK stretch disabled and receiving
202 //DR has not been read, b4 next byte comes in
203 //effect: lose byte
204 //should:clear RxNE and transmitter should retransmit
205
206 //Underrun
207 //CLK stretch disabled and I2C transmitting
208 //havent updated DR since new clock
209 //effect: same byte resent
210 //should: make sure discarded, and write next
211 } else if(I2C_GetITStatus(I2C1, I2C_IT_AF)) {
212 //Detected NACK
213 //Transmitter must reset com
214 //Slave: lines released
215 //Master: Stop or repeated Start must must be generated
216 //Master MSL bit
217 //Fixup
218 I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
219 } else if(I2C_GetITStatus(I2C1, I2C_IT_ARLO)) {
220 //Arbitration Lost
221 //Goes to slave mode, but cant ack slave address in same transfer
222 //Can after repeat Start though
223 } else if(I2C_GetITStatus(I2C1, I2C_IT_BERR)) {
224 //Bus Error
225 //In slave mode: data discarded, lines released, acts like restart
226 //In master mode: current transmission continues
227 }
228 }
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/88476.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!