发现问题
这段时间在学习FreeRTOS,今天移植成功后,写了2个任务。一个是LED每隔1s闪烁任务,另一个是使用UART4每隔100ms发送字符串任务。下载成功后,发现LED闪烁间隔不对,串口打印间隔时间也不对。当时就很纳闷了:RCC是按标准库的例子来配置的,FreeRTOS的系统节拍也是配置正确的,不可能会出现这种问题。后来,仔细排查,用示波器测试串口的波形发现一个问题:程序代码配置的是115200波特率,但实际输出波形算出来是38400,相差3倍。到这就开始怀疑RCC配置了,这时,我把MCO引脚打开,让其出示SYSCLK时钟,示波器上面反应的是72MH。接着又让它输出APB1CLK时钟,是正常的36MHz。调试到这里就感觉莫名其妙了,后来仔细查看RCC配置代码,发现官方例子是使用的25MHz的晶振,于是我换上25Mhz,重算了下分频系数等。烧写后,就变正常了。这里说下官网的例子模板
问题解决
STM32F107的时钟树
从图中可以看出,STM32F107的SYSCLK时钟有2条配置路线。第一条可以使用8M外部晶振来配置系统72MHz。第二条可以使用25M外部晶振来配置系统72MHz时钟。起出使用的是第一条路线,系统时钟也是正确配置成72MHz了,但是串口时钟是不正确的(其实是HSE_VALUE值没修改)。换成25MHz晶振,按第二条线路配置后,串口就正常了
官方RCC配置例子代码
void RCC_Configuration(void)
{
RCC_ClocksTypeDef RCC_ClockFreq;
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus != ERROR)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/****************************************************************/
/* HSE=25MHz, HCLK=72MHz, PCLK2=72MHz, PCLK1=36MHz */
/****************************************************************/
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* ADCCLK = PCLK2/4 */
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
/* Configure PLLs *********************************************************/
/* PPL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
RCC_PREDIV2Config(RCC_PREDIV2_Div5);
RCC_PLL2Config(RCC_PLL2Mul_8);
/* Enable PLL2 */
RCC_PLL2Cmd(ENABLE);
/* Wait till PLL2 is ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET)
{}
/* PPL1 configuration: PLLCLK = (PLL2 / 5) * 9 = 72 MHz */
RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while (RCC_GetSYSCLKSource() != 0x08)
{}
}
RCC_GetClocksFreq(&RCC_ClockFreq);
/* Enable USART2 clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
/* Enable ETHERNET clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ETH_MAC | RCC_AHBPeriph_ETH_MAC_Tx |
RCC_AHBPeriph_ETH_MAC_Rx, ENABLE);
/* Enable GPIOs clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |
RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE| RCC_APB2Periph_AFIO, ENABLE);
/* Enable ADC1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
}
可以发现官方的例子代码是使用25MHz外部晶振来配置的系统时钟,我在官方的代码基础上修改我的8M晶振配置就不能正常运行
我修改的代码
void bsp_RCC_Init(void)
{
RCC_ClocksTypeDef RCC_ClockFreq;
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
if(RCC_WaitForHSEStartUp() != ERROR)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/****************************************************************/
/* HSE=8MHz, HCLK=72MHz, PCLK2=72MHz, PCLK1=36MHz */
/****************************************************************/
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* ADCCLK = PCLK2/4 */
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
/* Configure PLLs *********************************************************/
/* PPL2 configuration: PLL2CLK = (HSE / 2) * 10 = 40 MHz */
RCC_PREDIV2Config(RCC_PREDIV2_Div2);
RCC_PLL2Config(RCC_PLL2Mul_10);
/* Enable PLL2 */
RCC_PLL2Cmd(ENABLE);
/* Wait till PLL2 is ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET)
{}
/* PPL1 configuration: PLLCLK = (HSE / 1) * 9 = 72 MHz */
RCC_PREDIV1Config(RCC_PREDIV1_Source_HSE, RCC_PREDIV1_Div1);
RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while (RCC_GetSYSCLKSource() != 0x08)
{}
}
}
上面我修改的代码使用后就出现了串口波特率错误的问题。在keil调试查看寄存器发现UART->BRR的数值与理论计算的不一样。追溯USART_Init()函数配置过程,发现获取的PCLK1时钟频率不是36MHz。
仔细查询源头代码,发现HSE_VALUE定义的是25000000,这就导致图中RCC_GetClockFreq()函数获取的PCLK1_Frequency的值计算出错。所以需将HSE_VALUE改成8000000。
另一种办法,更换外部8M晶振为25M,修改RCC配置为官方代码,就可以正常运行
总结
STM32F107具有以太网、USB OTG 等网络设备,以太网使用MII接口时需要提供25MHz时钟,STM32F107使用外部25MHz晶振来作为时钟源是最好不过了,官方也推荐使用25MHz。使用8M晶振需要修改HSE_VALUE值为8000000,然后配置相应的PLL时钟了。
上一篇:关于STM32中PA15引脚作为普通io的使用
下一篇:STM32 USART出现乱码
推荐阅读
史海拾趣
为了进一步扩大业务范围和提升技术实力,Keil公司决定与美国德克萨斯州理查森的Keil Software Inc进行联合运营。这一举措不仅使公司得以接触更广阔的市场,还促进了双方在技术、产品和市场等方面的深度融合。联合运营后,Keil公司的发展速度明显加快,逐渐在嵌入式系统开发工具市场上占据了重要地位。
随着技术的不断进步和市场的不断扩大,ARMKEIL Microcontroller Tools公司开始实施全球化战略。公司不仅在欧洲和美国设立了研发中心和销售网络,还积极开拓亚洲市场,与多个国家和地区的合作伙伴建立了紧密的合作关系。通过全球化布局和市场拓展,ARMKEIL Microcontroller Tools公司的业务范围不断扩大,品牌影响力也逐渐提升。
这五个故事只是ARMKEIL Microcontroller Tools公司发展过程中的一部分。实际上,该公司的成长历程充满了无数的挑战和机遇。正是凭借着对技术的不断追求和对市场的敏锐洞察,ARMKEIL Microcontroller Tools公司才能在激烈的竞争中脱颖而出,成为嵌入式系统开发工具领域的佼佼者。
随着全球环保意识的提高,电子行业对环保的要求也越来越高。Aplus Flash Technology Inc公司积极响应环保号召,将环保理念融入产品设计和生产过程中。公司研发出了一款低能耗、环保型的闪存芯片,不仅降低了产品的能耗和碳排放,还提高了产品的可回收利用率。这一创新举措得到了消费者的广泛认可和支持,也为公司在市场上树立了良好的环保形象。
在追求经济效益的同时,Elpress AB也注重可持续发展和环境保护。公司积极采用环保材料和绿色生产工艺,降低生产过程中的能耗和排放。同时,Elpress AB还积极参与环保公益活动,推动电子行业的绿色发展。这些举措不仅体现了Elpress AB的社会责任感,也为公司的长期发展奠定了坚实的基础。
在追求经济效益的同时,Elpress AB也注重可持续发展和环境保护。公司积极采用环保材料和绿色生产工艺,降低生产过程中的能耗和排放。同时,Elpress AB还积极参与环保公益活动,推动电子行业的绿色发展。这些举措不仅体现了Elpress AB的社会责任感,也为公司的长期发展奠定了坚实的基础。
APT公司成立于1987年,创始人凭借对气体输送技术的深刻理解和前瞻眼光,在加利福尼亚州圣拉斐尔创立了这家公司。初始阶段,公司专注于制造坚固、可靠的气体输送产品,尤其是压力调节器和阀门。尽管市场充满竞争,但APT公司凭借出色的产品性能和可靠的品质,在1988年成功推出了一小部分产品,并迅速获得了市场的认可。销售额的迅速增长和产品供应的紧张,都预示着APT公司正步入快速发展的轨道。
开关死区对SPWM逆变器输出电压波形的影响 摘要:分析开关死区对SPWM逆变器输出电压波形的影响,讨论考虑开关死区时的谐波分析方法,并导出谐波计算公式。用计算机辅助分析和实验方法对理想的和实际的SPWM逆变器进行对比研究,得出一些不同于现有理 ...… 查看全部问答∨ |
基本知识 ADC0809是带有8位A/D转换器、8路多路开关以及微处理机兼容的控制逻辑的CMOS组件。它是逐次逼近式A/D转换器,可以和单片机直接接口。 (1).ADC0809的内部逻辑结构 由上图可知,ADC0809由一个8路模拟开关、一个地址锁存与译 ...… 查看全部问答∨ |
刚好手上有30米的双绞线 没事做了个试验 双绞线和 电源一起使用双绞线传输 可能使用的双绞线质量差了点 传输出来的图像没 同轴电缆 75-3 效果好 要差点 由于采集卡效果差 不要见怪 … 查看全部问答∨ |
|
我用的LPC2138芯片,开发软件是ADS 程序如下: int main(void) { uint8 flag = 0; sys = (SYS_TYPE *) malloc(sizeof(SYS_TYPE)); &nb ...… 查看全部问答∨ |
|
platformbuilder编译错误,请高手指点,谢谢啦! 这是build.err的内容 D:\\WINCE500\\build.log(1) : error SYSGEN0000: error(s) in sysgen phase 这是build.log的内容 Starting sysgen phase for project ( common ) Found localized resources for Languages ( 0404 0407 040C 0410 0411 ...… 查看全部问答∨ |
RT,就是点击一个按钮后弹出的只有OK键的那种对话框, 小弟对win32不熟悉,望各位详细讲解,谢谢, 另外,想问一下,因为是做手机应用软件的开发, 看一些教程都是用MFC的一个工程去做,为什么我们这用win32呢, 这两个开发手机应用软件有什么 ...… 查看全部问答∨ |
负荷或系统的不对称,引起负序电流流过发电机定子绕组,并在发电机空气隙中建立负序旋转磁场,使转子感应出两倍频率的电流,引起转子发热。大型发电机由于采用了直接冷却式(水内冷和氢内冷),使其体积增大比容量增大要小,同时,基于经济和技术上的 ...… 查看全部问答∨ |
设计资源 培训 开发板 精华推荐
- 兆易创新GD25/55全系列车规级SPI NOR Flash荣获ISO 26262 ASIL D功能安全认证证书
- 新型IsoVu™ 隔离电流探头:为电流测量带来全新维度
- 英飞凌推出简化电机控制开发的ModusToolbox™电机套件
- 意法半导体IO-Link执行器电路板为工业监控和设备厂商带来一站式参考设计
- Melexis采用无磁芯技术缩小电流感测装置尺寸
- 千丘智能侍淳博:用数字疗法,点亮“孤独症”儿童的光
- 数药智能冯尚:ADHD数字疗法正为儿童“多动症”提供更有效便捷服务
- Vicor高性能电源模块助力低空航空电子设备和 EVTOL的发展
- 创实技术electronica 2024首秀:加速国内分销商海外拓展之路
- “跨芯片”量子纠缠实现 有助建构更强大的量子计算能力