STM32的I2C主从机通信

最近一段时间在做I2C通信协议,需要在两块STM32之间做I2C通信,定的是主机用IO口模拟,从机用的是STM32的硬件I2C,我的项目要求是需要主从机之间能够进行一串数据收发而不出错,实验时在主机方面,利用IO口模拟主机,只需要理解时序就够了,同时将速度能够控制在100K(标准)左右,基本的时序理解网上大把的资料,所以主机这一块几个小时就搞定了,而在做从机时,遇到了困难,本来从机也想用IO口模拟的,但是速度达不到那么快,因此只能选择硬件做从机,现就从机用中断方式开说,总结过程中遇到的几点问题:

1、由于STM32的硬件问题,建议在使用I2C时,将其优先级设为最高。

2、针对程序中除了I2C数据收发,还有别的中断程序或者指令要执行而导致I2C数据传输堵塞时,可以在执行完该段程序后重新初始化I2C。

主机程序如下:

复制代码

  1 #include "Hal_IIC/I2C.h"2 #include "Hal_delay/delay.h"3 #include "common.h"4 #include "gizwits_product.h"5 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_SDA=1;            36     IIC_SCL=1;37     delayUs(4);38      IIC_SDA=0;//START:when CLK is high,DATA change form high to low 39     delayUs(4);40     IIC_SCL=0;  //钳住I2C总线,准备发送或接收数据 41 }      42 /*--------------------------------------------------------------------------------43 调用方式:void I2CStop(void) 44 函数说明:私有函数,I2C专用,停止信号45 ---------------------------------------------------------------------------------*/46 void IIC_Stop(void)47 {48     SDA_OUT();//sda线输出49     IIC_SCL=0;50     IIC_SDA=0;//STOP:when CLK is high DATA change form low to high51      delayUs(4);52     IIC_SCL=1; 53     IIC_SDA=1;//发送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 ucErrTime=0;63     SDA_IN();      //SDA设置为输入  64     IIC_SDA=1;delayUs(1);       65     IIC_SCL=1;delayUs(1);     66     while(READ_SDA)67     {68         ucErrTime++;69         if(ucErrTime>250)70         {71             IIC_Stop();72             return 1;73         }74     }75     IIC_SCL=0;//时钟输出0        76     return 0;  77 } 78 /*--------------------------------------------------------------------------------79 调用方式:void SendAck(void) 80 函数说明:私有函数,I2C专用,主器件为接收方,从器件为发送方时,应答信号。81 ---------------------------------------------------------------------------------*/82 void IIC_Ack(void)83 {84     IIC_SCL=0;85     SDA_OUT();86     IIC_SDA=0;87     delayUs(2);88     IIC_SCL=1;89     delayUs(2);90     IIC_SCL=0;91 }92 /*--------------------------------------------------------------------------------93 调用方式:void SendAck(void) 94 函数说明:私有函数,I2C专用,主器件为接收方,从器件为发送方时,非应答信号。95 ---------------------------------------------------------------------------------*/        96 void IIC_NAck(void)97 {98     IIC_SCL=0;99     SDA_OUT();
100     IIC_SDA=1;
101     delayUs(2);
102     IIC_SCL=1;
103     delayUs(2);
104     IIC_SCL=0;
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_SCL=0;//拉低时钟开始数据传输
115     for(t=0;t<8;t++)
116     {              
117         //IIC_SDA=(txd&0x80)>>7;
118         if((txd&0x80)>>7)
119             IIC_SDA=1;
120         else
121             IIC_SDA=0;
122         txd<<=1;       
123         delayUs(2);   //对TEA5767这三个延时都是必须的
124         IIC_SCL=1;
125         delayUs(2); 
126         IIC_SCL=0;    
127         delayUs(2);
128     }     
129 }         
130 /*--------------------------------------------------------------------------------
131 调用方式:unsigned char IIC_Read_Byte(void) 
132 函数说明:私有函数,I2C专用
133 ---------------------------------------------------------------------------------*/
134 //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
135 uint8_t IIC_Read_Byte(unsigned char ack)
136 {
137     unsigned char i,receive=0;
138     SDA_IN();//SDA设置为输入
139     for(i=0;i<8;i++ )
140     {
141                 receive<<=1;
142         IIC_SCL=0; 
143         delayUs(5);
144             IIC_SCL=1;
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_flag==0x02)
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 i=0;i<4;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 i=1;i<6;i++)
182           {
183               Cookr[i] = b[i];
184           }    
185 
186         }
187     }    
188    
189     /****************read end********************/
190   /****************write start*****************/
191         if(WR_flag==0x01)
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_flag=0x02;    
213         }
214         /***************write end*****************/
215      
216 }

复制代码

从机使用中断方式

复制代码

  1 #include "myiic.h"2 #include "delay.h"3 #include "led.h"4 #include "key.h"5 #include "usart.h"6 7 8 #define MY_I2C_ADDRESS    0x30                         //模拟从机地址9 unsigned char b[5]={0x00,0x00,0x00,0x00,0x00};         //从机接收操作10 uint8_t Wifi_Set=0x00;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_data=0;75 void I2C1_EV_IRQHandler(void) 76 {77 //        KV1=0;                                 //只是一个测试灯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 doesn't 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(data>=5)97                 {98                                 data=0;99                                 if((b[0]==0xFA)&&(b[4]==0xFB))
100                                 {
101                                     a[1]=b[1];
102                                     Wifi_Set=b[2];
103                                     flag=b[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_data>=5)
146                 S_data=0;
147                 break;
148             case I2C_EVENT_SLAVE_ACK_FAILURE://End of transmission EV3_2
149                 //TODO: Doesn't 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                 //it's late
185                 break;
186 
187         }
188 
189 
190 }
191 
192 void I2C1_ER_IRQHandler(void) {
193  //       GPIO_SetBits(GPIOD, RED);
194 //    LED3=0;
195         //Can't 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             //haven't 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 can't 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/news/405228.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css垂直居中那点事

这是我技术博客生涯的第一篇文章&#xff0c;想想还是有点小鸡冻。。。菜鸟的征程现在要开始了 学习css的时候经常被各种问题纠结到不要不要的&#xff0c;没办法&#xff0c;只能写写博客帮助整理一下自己的思绪和帮助一下和我遇到同样问题的小伙伴们 不知道各位学习css的小伙…

Windows常用shell命令大全

From: http://blog.csdn.net/yunzhongfeiniao/article/details/6564577 基于鼠标操作的后果就是OS界面外观发生改变&#xff0c;就得多花学习成本。更主要的是基于界面引导Path与命令行直达速度是难以比拟的。另外Geek很大一部分是键盘控&#xff0c;而非鼠标流的。 整理Wind…

div模拟select/option解决兼容性问题及增加可拓展性

个人博客&#xff1a; http://mcchen.club 想到做这个模拟的原因是之前使用select>option标签的时候发现没有办法操控option的很多样式&#xff0c;比如line-height等&#xff0c;还会由此导致在IE8及以下版本浏览器中的各种问题。 这个模拟思路很简单&#xff0c;也很清晰&…

Linux Socket网络通信示例

记录一下Linux 网络通信编程示例&#xff0c;主要用内网穿透和网络调试助手进行调试。 1、源文件&#xff1a; #include <stdlib.h> #include <sys/types.h> #include <stdio.h> #include <netinet/in.h> #incldue <string.h> //bze…

stm32+lwip(四):网页服务器测试

ST官方有lwip的例程&#xff0c;下载地址如下&#xff1a; https://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-library-expansion/stsw-stm32070.html 本文例子参考ST官方给出的例…

Linux 用C/C++创建新文件并写入内容

1、需求 在Linux环境下用C编写一个函数&#xff0c;用于记录运行日志&#xff0c;要求只存在一个同名文件&#xff0c;每次记录前清除已有的信息。 2、思路 需要完成的是&#xff1a; &#xff08;1&#xff09;查找&#xff08;access&#xff09;是否该文件存在&#xff…

如何将Eclipse中的开源项目使用到Android Studio中

近几日&#xff0c;笔者用到了一些开源项目&#xff0c;比如著名的PTR项目。但是在使用的过程中&#xff0c;遇到了一些问题。 这个开源库是在Eclipse上面写的&#xff0c;我们现在开发用的是Android stuido。 两种软件的项目结构是不同的&#xff0c;那么怎么把PTR用到我们的项…

STM32 网络通信Web Server中 SSI与CGI的应用解析

本次主要解析STM32网络通信中WebServer应用&#xff0c;从网页界面的编写到浏览器与STM32之间进行通信的数据来说明SSI与CGI的原理及应用&#xff0c;并对GET与POST指令进行应用解析。 硬件和软件环境&#xff1a; 1.硬件环境&#xff1a;STM32F407&#xff0c;网卡芯片LAN87…

树莓派SSH 连接不上:socket error Event:32 Error:10053

问题如下&#xff1a; 解决办法&#xff1a;ssh文件夹下的文件权限问题。 cd /etc/ssh sudo chmod 0644 * sudo chmod 0600 ssh_host_ecdsa_key ssh_host_rsa_key登陆成功&#xff1a;

嵌入式设备web服务器比较

现在在嵌入式设备中所使用的web服务器主要有&#xff1a;boa、thttpd、mini_httpd、shttpd、lighttpd、goaheand、appweb和apache等。 Boa 1.介绍 Boa诞生于1991年&#xff0c;作者Paul Philips。是开源的&#xff0c;应用很广泛&#xff0c;特别适合于嵌入式设备&#xff0c…

UML造型——使用EA时序图工具的开发实践和经验

Enterprise Architect&#xff08;下面简称EA&#xff09;是一款基于OMG UML的可视化模型与设计工具。提供了对软件系统的设计和构建、业务流程建模和基于领域建模的支持&#xff0c;被企业和组织不仅应用于对系统的建模&#xff0c;还用于推进模型在整个应用程序开发周期中实现…

Qt QInputDialog文本输入对话框示例

1、代码如下 //引入头文件: #include <QInputDialog>//...//...//...//具体用法&#xff1a; bool isOK;//QInputDialog 是否成功得到输入 QString text QInputDialog::getText(NULL, "参数设定", "输入单次召测统计时间&#xff0c;eg.\"0:0:…

单元测试工具Numega BoundsChecker

From: http://blog.csdn.net/wangweitingaabbcc/article/details/7794985 1 前言 我在本文中详细介绍了测试工具NuMega Devpartner(以下简称NuMega)的使用方法。 NuMega是一个动态测试工具&#xff0c;主要应用于白盒测试。该工具的特点是学习简单、使用方便、功能有效。NuM…

在Codeigniter框架中使用NuSOAP

0、NuSOAP的简介 NuSOAP 是一组功能强大的PHP类&#xff0c;这个工具的发布让使用和创建SOAP消息变得相当简单。 NuSOAP有Dirtrich Ayala编写&#xff0c;可以无缝的与许多最流行的SOAP服务实现交互&#xff0c;它以LGPL协议进行发布。NuSOAP的主要特性包括&#xff1a; 简单&a…

Keil使用PC-Lint

Keil使用PC-Lint 随着项目的推进与迭代&#xff0c;一个Project的代码量往往会不知不觉增长&#xff0c;当项目代码达到数万行&#xff0c;迭代经历较长时间后&#xff0c;仅靠开发人员自身的代码质量已不能满足对整体质量的把控。难以避免会出现一些潜在的逻辑错误与非逻辑错误…

嵌入式产品开发流程

嵌入式产品&#xff0c;与普通电子产品一样&#xff0c;开发过程都需要遵循一些基本的流程&#xff0c;都是一个从需求分析到总体设计&#xff0c;详细设计到最后产品完成的过程。但是&#xff0c;与普通电子产品相比&#xff0c;嵌入式产品的开发流程又有其特殊之处。它包含嵌…

Codeforces 478B 6thweek contest_B

Random teams 题意&#xff1a; 有n个选手和m个队伍&#xff0c;让你分配&#xff0c;条件是每个队伍至少要有1个选手。分配完之后&#xff0c;每队伍里2个人可以组成一组&#xff0c;求分配完之后最多的组数和最少的组数 分析&#xff1a; 1. 最多的情况就是&#xff0c;先每…

如何Keil官网下载器件支持包Software Packs

步骤1&#xff1a;百度一下Keil&#xff0c;在搜索结果中点击打开官网 步骤2&#xff1a;在官网的搜索栏输入Software Packs&#xff0c;点击Go 步骤3&#xff1a;点击打开MDK Software Packs 步骤4&#xff1a;往下拉&#xff0c;找到自己需要的Pack 步骤5&#xff1a;以下载s…

为文档快速插入页眉和页脚

专业的文档往往需要配以漂亮的页眉、页脚等修饰性元素才会更加完美。在Word 2010中您不必再为设计漂亮页眉和页脚而大费周折&#xff0c;内置的“页眉样式库”和“页脚样式库”为您提供了丰富的选择余地。 &#xff08;1&#xff09;打开Word 2010文档&#xff0c;在“插入”选…

[BBS]搭建开源论坛之Jforum搭配开源CKEDITOR

本文作者&#xff1a;sushengmiyan本文地址&#xff1a;http://blog.csdn.net/sushengmiyan/article/details/47946065使用默认的编辑器的时候&#xff0c;格式都无法保存。现在按照上节的方法更改了编辑器。今天再对编辑器进行更改&#xff0c;适应jforum.效果如下图了。记录几…