(1)在使用FSMC作为LCD接口时,同时ENABLE了FreeRTOS,发现生成的工程文件,编译之后会出问题。
研究后发现问题出在“FreeRTOSConfig.h”这段代码:
/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4
#endif
当我使用了FSMC并且ENABLE 了FreeRTOS,“__NVIC_PRIO_BITS”这个宏就会被定义,此时RTOS的宏
“configPRIO_BITS”会被定义为“__NVIC_PRIO_BITS”,这个宏在“stm32f205xx.h”里面:
#define __NVIC_PRIO_BITS 4U /*!< STM32F2XX uses 4 Bits for the Priority Levels */
也就是说“configPRIO_BITS”这个宏被定义为“4U”也就是类型为“unsigned int”的4。
我尝试在汇编函数里,直接将:
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
改为:
mov r0, #4U
编译出错,但如果将“4U”改为“4”是没问题的。
后记:在韦东山第一期加强版视频编写LED程序的视频有讲到,在汇编里面指令需要占据一定的位数,例如:
mov r0, #0x12345678
是不行的,因为“MOV”这个指令本身占据了一定的位数。而“4U“本身为32位,stm32为32位系统,所以”MOV“这个指令码被清零了。具体可以了解下机器码跟汇编。
(2)ADC采集一次信号后不再采集
问题可以参考这个链接:http://www.ing10bbs.com/forum.php?mod=viewthread&tid=194&extra=
除了RCC、SYS,只配置了ADC2的IN8,NVIC Settings打开ADC全局中断:
生成工程的改动很小,增加了一个ADC值获取的回调函数以及一个ADC启动的函数:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
ADC_VAL = ADC2->DR;
}
ADC初始化里面添加了IT启动:
HAL_ADC_Start_IT(&hadc2);
然后进入仿真发现,ADC采样一次信号后,ADC2->DR寄存器里面的值不变了。研究了老半天,看了几遍参考手册中ADC寄存器的描述,怀疑是EOCS寄存器的问题。所以将:
hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
改为:
hadc2.Init.EOCSelection = ADC_EOC_SEQ_CONV;
很好,ADC连续采样了。但又产生一个新的问题,程序一直重复进入ADC中断,不进入while(1);大循环了。
由此猜测,是不是因为ADC采样转化太快了,导致未处理完一次中断又产生新的中断?
又进行修改:
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
改为:
sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES;
这次可以正常运行了。其实,最好在启动ADC之后,关闭不必要的中断源,例如只需要看门狗中断:
__HAL_ADC_DISABLE_IT(&hadc2, ADC_IT_EOC|ADC_IT_JEOC|ADC_IT_OVR);
后记:在MDK仿真下观察寄存器,发现关闭中断的指令,关闭的是”ADC_IT_OVR“这个中断源。
这个是”溢出中断“的中断源。当ADC以”ADC_SAMPLETIME_3CYCLES“进行转换时,当前中断尚未处理完便再次触发中断
就会造成中断溢出。所以将ADC转换速率降低,或者关闭”ADC_IT_OVR“程序可以正常运行。
(3)内部FLASH的操作
MCU是F205VCT6
1、写
//STM FLASH写函数
void STMFLASH_Write_NoCheck ( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite )
{
uint16_t i;
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR|FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
for(i=0;i { HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,WriteAddr,pBuffer[i]); WriteAddr+=2; //地址增加2. } HAL_FLASH_Lock(); } 写之前要去除FLASH的写保护,然后就是写函数中的清楚标志位问题。如执行了 HAL_FLASH_Unlock(); 然后立即执行写函数,会发现第一个数据写不进FLASH,但是后续的数据是正常的。试过增加几十毫秒的延时,但是结果依旧错误。如果在写之前先清除错误标志位,则可以正常写入。 2、擦除 //STM FLASH擦除函数 void SectorErase(u32 SectorNum ) { FLASH_EraseInitTypeDef eraseInit; u32 error; HAL_FLASH_Unlock(); __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR|FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR); eraseInit.Sector = SectorNum; eraseInit.TypeErase = FLASH_TYPEERASE_SECTORS; eraseInit.NbSectors = 1; eraseInit.VoltageRange = FLASH_VOLTAGE_RANGE_3; if ( HAL_FLASHEx_Erase( &eraseInit, &error ) == HAL_OK ) { } HAL_FLASH_Lock(); } 跟写函数一样,解锁FLASH后立即擦除,需要先清除错误标志位。 另外,执行擦除函数,如果是擦除0~3扇区,则可以正常进入仿真(代码在扇区0,擦除扇区0会出现异常,但确实能进入仿真的)界面。 如果擦除4~5扇区,则出现以下问题 不能进入仿真,但是扇区擦除却是成功的。解决办法,暂时未找到
上一篇:STM32定时器----多通道PWM捕获
下一篇:STM32HAL----USB串行FLASH模拟U盘
推荐阅读最新更新时间:2024-03-16 16:07
设计资源 培训 开发板 精华推荐
- 首都医科大学王长明:针对癫痫的数字疗法已进入使用阶段
- 非常见问题解答第223期:如何在没有软启动方程的情况下测量和确定软启动时序?
- 兆易创新GD25/55全系列车规级SPI NOR Flash荣获ISO 26262 ASIL D功能安全认证证书
- 新型IsoVu™ 隔离电流探头:为电流测量带来全新维度
- 英飞凌推出简化电机控制开发的ModusToolbox™电机套件
- 意法半导体IO-Link执行器电路板为工业监控和设备厂商带来一站式参考设计
- Melexis采用无磁芯技术缩小电流感测装置尺寸
- 千丘智能侍淳博:用数字疗法,点亮“孤独症”儿童的光
- 数药智能冯尚:ADHD数字疗法正为儿童“多动症”提供更有效便捷服务
- Vicor高性能电源模块助力低空航空电子设备和 EVTOL的发展
- EEworld版主招新啦!欢迎加入我们的队伍
- DEYISUPPORT:【全新FAQ来袭】今夏且听风吟,你不能错过的精华!
- 读故事写评语喽~ 踩过坑的你是否期待更贴心智能的客户支持,KeysightCare邀您抢楼赢礼!
- 有奖直播:Littelfuse电动车充电桩及车载充电器保护设计方案
- 发帖赢好礼 | MPS 工程师为您解决DC-DC设计难题
- TE户外照明互连解决方案样片来袭 免费申领进行中!
- 2016 TI嵌入式产品研讨会全网首映,下载有好礼!
- 下载白皮书 答题赢好礼|TE《智能监控应用连接解决方案指南》
- ADI有奖直播:基准电压源产品技术及应用选择 7月25日上午10:00-11:30 不容错过~
- 有奖直播: 解读安森美半导体电源解决方案 ,聚焦服务器电源、光伏逆变器