|||
已经五月底了,马上就要答辩了,快要离开校园了~走向新的工作岗位了。
由于前段时间在公司里实习接触了STM32单片机,这次回校就准备好好学习学习~到现在为止,基本上是扎扎实实的学了半个月时间了,这半个月的时间里学习了基本IO口(GPIO),通用定时器,高级定时器,外部中断,Systick时钟,串口(232和485),CAN,I2C,DS18B20,程序加密等操作,除了CAN因为设备的限制,现在没法进行调试,其他的都已经调试成功了,在这段时间的学习和程序调试中学到了很多知识,也发现了一些STM32单片机的一些问题。
一、232串口printf重映射的问题
在刚刚开始用串口调试中,发现STM32单片的串口printf确实很方便,直接就可以把变量的值和字符直接送到上位机的串口调试助手中,但是在随着程序慢慢的变大,需要通过printf传输给上位机的数据越来越多。这时候问题就来了,容易导致系统的“串口死机”,注意:仅仅只是串口挂掉了,系统还是在正常运行。针对这个问题在网上找了一些资料,也没有完全解释清楚到底是什么问题,好像说是串口的缓存被挤爆了,然后进入了硬件中断从而导致串口失效,针对这种说法,我还没有进行验证,也不知道是否正确。只是我后来我将程序进行了修改,将所有的printf程序都注释掉,重新使用STM32的串口发送数据,这个问题就解决了。
二、STM32的硬件I2C的问题
在调试I2C之前,在网上也找了很多资料,很多人说STM32的硬件I2C有各种bug,难以调试等各种问题。就准备用软件进行模拟I2C的功能,但是调试中也遇到了各种时序问题,好长时间都没有调试成功。后来想了很久,既然STM32单片机现在卖的这么火,内部的硬件不可能出现这么大的问题,通过各种查资料,程序调试,经过了三天的紧张调试,终于将硬件I2C的功能调通了。其实说起来很简单,第一要主要I2C的引脚在复用中要使用开漏输出复用的模式,同时在硬件上,I2C端口需要4.7K上拉电阻。附上I2C硬件调试的原始程序,希望对后来者有帮助:
void I2C_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;//¶¨ÒåÒ»¸öGPIO¿Ú½á¹¹Ìå±äÁ¿
I2C_InitTypeDef I2C_InitStructure; //¶¨ÒåÒ»¸öI2C½Ó¿Ú½á¹¹Ìå
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE); //¹Ò½ÓI2C 2ʱÖÓ
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10|GPIO_Pin_11; //PB10 SCL, PB11, SDA
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //ÉèÖÃGPIOËÙ¶È
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_OD; //¸´ÓÿªÂ©Êä³ö
GPIO_Init(GPIOB,&GPIO_InitStructure);
I2C_DeInit(I2C2); //I2C2½Ó¿Úȱʡֵ£¬¸´Î»
I2C_InitStructure.I2C_Mode=I2C_Mode_I2C; //I2C ģʽ
I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2; //I2C¿ìËÙģʽ TLOW/THIGH=2
I2C_InitStructure.I2C_OwnAddress1=0x30; //×ÔÉíµØÖ· 0x30
I2C_InitStructure.I2C_Ack=I2C_Ack_Enable; //ʹÄÜACKÓ¦´ð
I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit; //Ó¦´ð7λµØÖ·
I2C_InitStructure.I2C_ClockSpeed=200000; // I2CʱÖÓËÙ¶È
I2C_Init(I2C2,&I2C_InitStructure); //³õʼ»¯ÅäÖÃ
I2C_Cmd(I2C2,ENABLE); //ʹÄÜI2C2
}
/****************************************************************************
* Ãû ³Æ :void I2C_WriteByte(uint8_t DeviceAddress,uint16_t WriteAddr,uint8_t Buffer_Byte)
* ¹¦ ÄÜ :дһ¸ö×Ö½ÚµÄÊý¾ÝдÈëI2C ÖÐ
* Èë¿Ú²ÎÊý: DeviceAddress ҪдÈëµÄÉ豸µØÖ·
Buffer_Byte ҪдÈëµÄ×Ö½Ú
WriteAddr ҪдÈëÉ豸µÄ¼Ä´æÆ÷µØÖ·
* ³ö¿Ú²ÎÊý:ÎÞ
* ˵ Ã÷ :
* µ÷Ó÷½·¨:ÎÞ
****************************************************************************/
void I2C_WriteByte(uint8_t DeviceAddress,uint16_t WriteAddr,uint8_t Buffer_Byte)
{
uint8_t addr1,addr2;
addr1=DeviceAddress+((WriteAddr/256)<<1);
addr2=WriteAddr%256;
I2C_GenerateSTART(I2C2,ENABLE); //·¢ËÍÆðʼÐźÅ
while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT)); //·¢ËÍÍê±Ï EV5
I2C_Send7bitAddress(I2C2,addr1,I2C_Direction_Transmitter); //ÏòÉ豸·¢ËÍÉ豸µØÖ·
while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); //·¢ËÍÍê³É EV6
I2C_AcknowledgeConfig(I2C2,DISABLE); //ʧÄÜI2CµÄÓ¦´ð¹¦ÄÜ
I2C_SendData(I2C2,addr2); //·¢ËͼĴæÆ÷µØÖ·
while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //·¢ËÍÍê³ÉEV8
I2C_AcknowledgeConfig(I2C2,DISABLE); //ʧÄÜI2CµÄÓ¦´ð¹¦ÄÜ
I2C_SendData(I2C2,Buffer_Byte);
while(!(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED))); //·¢ËÍÍê³ÉEV8
I2C_GenerateSTOP(I2C2,ENABLE); //·¢ËÍÍ£Ö¹ÐźÅ
Delay_10ms();
}
/****************************************************************************
* Ãû ³Æ :void I2C_ReadByte(uint8_t DeviceAddress,uint16_t ReadAddr,uint8_t *pBuffer)
* ¹¦ ÄÜ :½«I2C ÖеÄÒ»¸ö×Ö½ÚÊý¾Ý¶Á³ö·ÅÈëpBuffer »º´æÖÐ
* Èë¿Ú²ÎÊý: DeviceAddress Òª¶Á³öµÄÉ豸µØÖ·
pBuffer »º³åÇøµØÖ·Ö¸Õë
WriteAddr Òª¶Á³öÉ豸µÄ¼Ä´æÆ÷µØÖ
* ³ö¿Ú²ÎÊý:¶ÁÈ¡ÊÇ·ñ³É¹¦
* ˵ Ã÷ :
* µ÷Ó÷½·¨:ÎÞ
****************************************************************************/
void I2C_ReadByte(uint8_t DeviceAddress,uint16_t ReadAddr,uint8_t *pBuffer)
{
uint8_t addr1,addr2;
addr1=DeviceAddress+((ReadAddr/256)<<1);
addr2=ReadAddr%256;
I2C_GenerateSTART(I2C2,ENABLE); //·¢ËÍÆðʼÐźÅ
while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT)); //EV5 ·¢ËÍÍê³É
I2C_Send7bitAddress(I2C2,addr1,I2C_Direction_Transmitter); //ÏòÉ豸·¢ËͶÁÈ¡É豸µØÖ·
while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//·¢ËÍÍê³É EV6
I2C_Cmd(I2C2,ENABLE); //ʹÄÜI2C
I2C_AcknowledgeConfig(I2C2,DISABLE); //ʹÄÜI2CµÄÓ¦´ð¹¦ÄÜ
I2C_SendData(I2C2,addr2); //·¢ËͶÁ¼Ä´æÆ÷µØÖ·
while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //·¢ËÍÍê³É EV8
I2C_AcknowledgeConfig(I2C2,DISABLE); //ʧÄÜI2CµÄÓ¦´ð¹¦ÄÜ
I2C_GenerateSTART(I2C2,ENABLE); //ÖØз¢¿ªÊ¼ÃüÁî
while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT)); //·¢ËÍÍê³É EV5
I2C_Send7bitAddress(I2C2,addr1+1,I2C_Direction_Receiver); //·¢ËͶÁÈ¡É豸µØÖ·
while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//·¢ËÍÍê³ÉEV6
while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_RECEIVED)); //½ÓÊÕÊý¾ÝÍê±Ï EV7
I2C_AcknowledgeConfig(I2C2,DISABLE); //ʧÄÜI2CµÄÓ¦´ð¹¦ÄÜ
*pBuffer=I2C_ReceiveData(I2C2); //½ÓÊÕI2C
I2C_GenerateSTOP(I2C2,ENABLE); //·¢ËÍÍ£Ö¹ÐźÅ
}
另外软件模拟I2C的程序就不上传了,比较长,网上这方面的内容还是比较多的,大家多找找~
今天就先讲这么多,晚上还得技术调试SPI接口,希望不会出现问题,可以顺利的搞完~~~~~~~~~~~
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-9-24 12:56
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社