[应用方案] NV32F100x 系列软件修改-应用笔记

[复制链接]
 楼主| HuangHongLun 发表于 2019-9-25 15:51 | 显示全部楼层 |阅读模式
一、开关总中断
NV32F100x 不可使用 CPS 指令,使用 MRS/MSR 指令进行开关总中断的操作
使用汇编的用户:
  1. 1. MOV R0,#1
  2. 2. MSR PRIMASK, R0 ;禁用总中断
  3. 3.
  4. 4. MOV R0,#0
  5. 5. MSR PRIMASK, R0 ;使能总中断


使用 C 库的用户:
在 arm_cm0.h 中修改宏定义 DisableInterrupts;和 EnableInterrupts;的宏定义如下
(若在其余处宏定义,请进行对应替换)
  1. 1. /***********************************************************************/
  2. 2. /*!< 使能所有中断 */
  3. 3. #ifndef KEIL
  4. 4. #define EnableInterrupts __set_PRIMASK(0)
  5. 5. #else
  6. 6. #define EnableInterrupts __set_PRIMASK(0)
  7. 7. #endif
  8. 8.
  9. 9. /*!< 禁用所有中断 */
  10. 10. #ifndef KEIL
  11. 11. #define DisableInterrupts __set_PRIMASK(1)
  12. 12. #else
  13. 13. #define DisableInterrupts __set_PRIMASK(1)
  14. 14. #endif



 楼主| HuangHongLun 发表于 2019-9-25 18:43 | 显示全部楼层
二、看门狗
默认上电开门狗开启,在库文件中 SystemInit 函数调用如下两个函数对看门狗进行配置:
WDOG_Disable(); //上电后配置看门狗禁止,之后不可再使能看门狗
WDOG_DisableWDOGEnableUpdate();//上电后配置看门狗禁止,但允许对看门狗再次配置
看门狗解锁操作(wdog.h):
  1. #define WDOG_Unlock() DisableInterrupts; WDOG->CNT = 0x20C5; WDOG->CNT = 0x28D9; EnableInterrupts

看门狗喂狗操作(wdog.c):
  1. 1. /*
  2. 2. *看门狗喂狗操作,在喂狗之前总中断需要关闭,以防在喂狗期间中断打断,造成系统复位
  3. 3. */
  4. 4. void WDOG_Feed(void)
  5. 5. {
  6. 6. DisableInterrupts; //关总中断
  7. 7. WDOG->CNT = 0x02A6;//喂狗序列需要在 128 个总线时钟周期内完成
  8. 8. WDOG->CNT = 0x80B4;
  9. 9. EnableInterrupts; //开总中断
  10. 10. }

关于喂狗操作的建议:
若用户采用 1K 时钟作为看门狗定时时钟,请预留一半时间的空间来喂狗,1K 的时钟偏差范围
在 0.8K-1.2K 之间,不可用于精确定时。
例:若使用 1S 的超时时间,在 500MS 内喂狗。
 楼主| HuangHongLun 发表于 2019-9-25 18:45 | 显示全部楼层
三、Flash 操作
NV32F100x 的 Flash 寿命为:擦/写各两万次
Flash 相关操作须放入 RAM 中执行
在执行 FLASH 相关操作执行时,需要关总中断以防中断打断造成系统紊乱
建议用附件中的 flash.c 和 flash.h 进行替换
对 Flash_Program1LongWord 进行修改,添加 14 和 18 行指令
  1. 1. __ramfunc uint16_t Flash_Program1LongWord(uint32_t wNVMTargetAddress, uint32_t dwData)
  2. 2. {
  3. 3. uint16_t err = FLASH_ERR_SUCCESS;
  4. 4.
  5. 5. //判断是否为字对齐
  6. 6. if(wNVMTargetAddress & 0x03)
  7. 7. {
  8. 8. err = FLASH_ERR_INVALID_PARAM;
  9. 9. return (err);
  10. 10. }
  11. 11. // 清除错误标志
  12. 12. EFMCMD = FLASH_CMD_CLEAR;
  13. 13. //写入数据到对应的地址中
  14. 14. DisableInterrupts;
  15. 15. M32(wNVMTargetAddress) = dwData;
  16. 16. //加载编程命令
  17. 17. EFM_LaunchCMD(FLASH_CMD_PROGRAM);
  18. 18. EnableInterrupts;
  19. 19. return (err);//返回状态
  20. 20. }

对 Flash_Program2LongWords 进行修改,添加 13、16、20 和 23 行指令
  1. 1. __ramfunc uint16_t Flash_Program2LongWords(uint32_t wNVMTargetAddress, uint32_t dwData0, uint32_t dwData1)
  2. 2. {
  3. 3. uint16_t err = FLASH_ERR_SUCCESS;
  4. 4.
  5. 5. //判断是否为字对齐
  6. 6. if(wNVMTargetAddress & 0x03)
  7. 7. {
  8. 8. err = FLASH_ERR_INVALID_PARAM;
  9. 9. return (err);
  10. 10. }
  11. 11. // 清除错误标志
  12. 12. EFMCMD = FLASH_CMD_CLEAR;
  13. 13. DisableInterrupts;
  14. 14. M32(wNVMTargetAddress) = dwData0;//存放数据到以目标地址为起始的 4 个字节的空间中
  15. 15. EFM_LaunchCMD(FLASH_CMD_PROGRAM);//0x20000000,加载编程命令
  16. 16. EnableInterrupts;
  17. 17. wNVMTargetAddress = wNVMTargetAddress +4;//地址是字对齐的,地址向后移一个字
  18. 18.
  19. 19. EFMCMD = FLASH_CMD_CLEAR;
  20. 20. DisableInterrupts;
  21. 21. M32(wNVMTargetAddress) = dwData1;//第二个数据放入处理后的地址的 4 个字节的空间中
  22. 22. EFM_LaunchCMD(FLASH_CMD_PROGRAM);//加载编程命令
  23. 23. EnableInterrupts;
  24. 24. return (err);//返回处理状态
  25. 25. }

模拟 eeprom 控件的字节写函数修改(eeprom.c)
  1. 1. uint16_t EEPROM_WriteByte(uint32_t adr, uint8_t Data)
  2. 2. {
  3. 3. uint32_t err = EEPROM_ERR_SUCCESS;
  4. 4. uint32_t data_mask;
  5. 5. uint32_t r_data;
  6. 6. uint32_t data_m0;
  7. 7. uint32_t data_m1;
  8. 8. uint32_t word_adr = adr &0x3fc;
  9. 9. uint32_t b_sit= adr & 0x3;
  10. 10.
  11. 11. //先让高位为 FF
  12. 12. data_m0 = Data << b_sit*8;
  13. 13. data_mask = 0xFFFFFFFF<<(b_sit+1)*8;
  14. 14. //然后让低位为 FF
  15. 15. data_m1 = 0xFFFFFFFF >> (32-b_sit*8);
  16. 16. data_m1 = data_m1 | data_m0 | data_mask ;
  17. 17. r_data = EEPROM_Read(word_adr);
  18. 18. r_data |= 0xFF<< b_sit*8;
  19. 19. data_m1 = data_m1 & r_data;
  20. 20.
  21. 21. err = EEPROM_Write(word_adr , data_m1);
  22. 22.
  23. 23. return(err);
  24. 24. }
 楼主| HuangHongLun 发表于 2019-9-25 18:45 | 显示全部楼层
四、主频
NV32F100x 的主频校订为 40M,不可以进行超频
若使用 FEI 内部时钟模式,需注释 NV32_config.h 的如下宏定义
  1. 1. //注释掉宏定义则使用内部 31.26K 时钟,主频 40M
  2. 2. //#define TRIM_IRC
 楼主| HuangHongLun 发表于 2019-9-25 18:46 | 显示全部楼层
五、ADC 操作
NV32F100x 的 ADC 转换速率为 400K,输入阻抗 3-5K 欧
在开启 ADC 连续转换模式并且使用 FIFO 时,进行如下操作,否则则会造成数据紊乱。
1.若配置为硬件触发,在中断服务函数中
  1. 1. ADC->SC2 &= ~ADC_SC2_ADTRG_MASK;//先关闭硬件触发,停止采样
  2. 2. //...
  3. 3. //ADC 读取 FIFO 操作
  4. 4. //...
  5. 5. ADC->SC2 |= ADC_SC2_ADTRG_MASK; //再打开硬件触发,开始采样

2.若配置为软件触发模式,建议使用单次 FIFO 模式
 楼主| HuangHongLun 发表于 2019-9-25 18:46 | 显示全部楼层
六、外部晶振
OSC 模块支持两种范围的晶振:32K 低范围和 4-24M 高范围,并分为两种模式低功耗和高增益
32K 低范围只可使用高增益模式,建议匹配电容选择 33pf
在 NV32_config.h 中宏定义如下,即可使能高增益模式
  1. 1. #define CRYST_HIGH_GAIN
 楼主| HuangHongLun 发表于 2019-9-25 18:47 | 显示全部楼层
七、低功耗唤醒
当 MCU,从低功耗模式下唤醒时,需要等待时钟稳定,才可进入正常工作模式。
  1. 1. while((ICS->S&ICS_S_LOCK_MASK)!=ICS_S_LOCK_MASK)
mintspring 发表于 2019-9-25 22:04 | 显示全部楼层
注释的清楚,一看就懂。
捉虫天师 发表于 2019-9-25 23:23 | 显示全部楼层
多谢分享笔记。
捉虫天师 发表于 2019-9-25 23:56 | 显示全部楼层
讲的不错,谢了。
zlmin 发表于 2019-10-3 19:32 来自手机 | 显示全部楼层
感谢分享!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

50

主题

440

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部

50

主题

440

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部