[8/16位单片机] 请教一个中断后计时出错的问题

[复制链接]
343|13
 楼主 | 2019-5-14 11:41 | 显示全部楼层 |阅读模式
具体问题:中断修改返回PC,从中断返回之后,执行延时程序的时候总是出错,发现STATUS的Z位经常无法置1,然后导致程序出错(硬件电路表现是无反应,仿真是错误退出)。经过多种方法验证以及步进调试,发现了一个规律:如果延时非常短,STATUS的Z位可以正常置1,但是稍长的延时(比如0.5S或1S),Z又不能置1了会一直延时导致错误。因为中断之前的延时不管多长时间都是正常的,中断之后就出现Z不能正常置1的出错,非常非常想不通!
我用的型号是16F1823,请大大们不吝指点,成分感谢!

使用道具

评论回复
 楼主 | 2019-5-14 15:20 | 显示全部楼层
有遇到过这问题的吗?

使用道具

评论回复
| 2019-5-14 17:54 | 显示全部楼层
没有遇到

你有代码吗,复现这个问题的

使用道具

评论回复
| 2019-5-14 23:38 | 显示全部楼层
是被中断打断了?不该啊

使用道具

评论回复
 楼主 | 2019-5-15 00:21 | 显示全部楼层
原来的代码非常长,同时因为公司的保密制度原因,我刚刚尝试写了另外一个简单的代码准备发上来,结果,这个简单的却不存在Z位不能置1的问题!
难道我那个程序中断后Z位不能置1是因为耗电太多的原因吗?毕竟同一个延时子程序,中断前正常,中断后不正常,想不到其他原因
刚刚写的这个简单的代码,和我遇到问题的那个采用同样的中断处理方式,发上来给大大看看是不是中断处理有缺陷,请指点一下,感谢!

  1. #include p16f1823.inc
  2. __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
  3. __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_LO & _LVP_OFF
  4. errorlevel 0,-302

  5.     ORG            0000H            
  6.     GOTO    START                  
  7.     ORG            0004H
  8.     BANKSEL IOCAF
  9.     CLRF IOCAF
  10.     BANKSEL TOSH
  11.     CLRF TOSH
  12.     MOVLW 10H
  13.     MOVWF TOSL
  14.     RETFIE

  15. INTPP ORG 0010H
  16.         BCF PORTC,0
  17. DELAY2;延时程序,蓝灯闪
  18.         MOVLW 0F0H
  19.         MOVWF 75H
  20.         CLRF 74H
  21.         INCFSZ 74H,F
  22.         GOTO $-1
  23.         DECFSZ 75H,F
  24.         GOTO $-3
  25.        
  26.         BTFSS 73H,1
  27.         GOTO $+4
  28.         BSF PORTC,1
  29.         BCF 73H,1
  30.         GOTO DELAY2
  31.         BCF PORTC,1
  32.         BSF 73H,1
  33.         GOTO DELAY2

  34. START ORG 0040H
  35. BANKSEL TRISC;初始化
  36. BCF TRISC,0
  37. BCF TRISC,1
  38. BANKSEL PORTC
  39. BCF PORTC,0
  40. BCF PORTC,1
  41. BANKSEL ANSELA
  42. BCF ANSELA,4
  43. BANKSEL IOCAF
  44. CLRF IOCAF
  45. MOVLW B'10001000'
  46. MOVWF INTCON
  47. BANKSEL IOCAN
  48. BSF IOCAN,4

  49. DELAY1;延时程序,黄灯闪
  50. BANKSEL PORTC
  51.         MOVLW 0F0H
  52.         MOVWF 72H
  53.         CLRF 71H
  54.         INCFSZ 71H,F
  55.         GOTO $-1
  56.         DECFSZ 72H,F
  57.         GOTO $-3
  58.        
  59.         BTFSS 73H,0
  60.         GOTO $+4
  61.         BSF PORTC,0
  62.         BCF 73H,0
  63.         GOTO DELAY1
  64.         BCF PORTC,0
  65.         BSF 73H,0
  66.         GOTO DELAY1
  67.     END
复制代码



使用道具

评论回复
| 2019-5-15 11:46 | 显示全部楼层
这种不用怀疑吧,程序问题

使用道具

评论回复
| 2019-5-15 11:48 | 显示全部楼层
中断需要保存程序状态字

使用道具

评论回复
| 2019-5-15 12:18 | 显示全部楼层
把修改TOS的命令放到主程序里试试,在中断服务程序里改TOS不妥当

使用道具

评论回复
 楼主 | 2019-5-15 16:18 | 显示全部楼层
中断后要跳到指定PC地址的,返回主程序再改,怎么改?
PIC搞个TOS寄存器,不就是为了方便改的吗?

使用道具

评论回复
 楼主 | 2019-5-15 16:40 | 显示全部楼层
锵才才 发表于 2019-5-15 12:18
把修改TOS的命令放到主程序里试试,在中断服务程序里改TOS不妥当

在中断里改TOS会导致什么样的问题呢?我查找不到相关的资料

使用道具

评论回复
| 2019-5-16 00:01 | 显示全部楼层
你这个在做的类似任务调度,那你应该注意到STATUS是影子寄存器组的一员,并且这个也是应该做现场切换的很重要的东西。

使用道具

评论回复
 楼主 | 2019-5-16 00:37 | 显示全部楼层
bellstudio 发表于 2019-5-16 00:01
你这个在做的类似任务调度,那你应该注意到STATUS是影子寄存器组的一员,并且这个也是应该做现场切换的很重 ...

是的,你猜的很对!
STATUS是设计为不需要保存的,没有需要保存的东西,正在执行的任务遇到中断后,是再重新执行一次。
DATASHEET翻烂了找不到答案,步进的方法调试的结果就是Z不能置1,但是不知道为什么?
可能之前说得不够清楚,是DECFSZ/BTFSS之类的双周期指令Z不能置1,像SUBLW之类的单周期能正常置1

使用道具

评论回复
 楼主 | 2019-5-16 00:48 | 显示全部楼层
说明书里提到“Note 1: INTF flag is sampled here (every Q1).
2: Asynchronous interrupt latency = 3-5 TCY. Synchronous latency = 3-4 TCY, where TCY = instruction cycle time.
Latency is the same whether Inst (PC) is a single cycle or a 2-cycle instruction.”
那么像DECFSZ这种双周期指令,遇到中断是怎么处理的呢?直接丢弃第二个指令?或者用特殊寄存器保存起来(未在说明书中列出的那种)中断后再执行?

使用道具

评论回复
| 2019-5-16 08:32 | 显示全部楼层
16F1823, 为啥还要写汇编?

使用道具

评论回复
扫描二维码,随时随地手机跟帖
*滑动验证:
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

快速回复 返回顶部 返回列表