请各位帮我看一这个if函数多个条件怎么用为什么不对,非常感谢

您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
EXCEL难题1网打尽.doc 54页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
EXCEL难题1网打尽
你可能关注的文档:
··········
··········
EXCEL难题一网打尽(续)
能不能做到让符合条件的单元格所在的列自动隐藏 比如说第一行的第一个单元格=1那么就自动隐藏第一行? 解答用vba。
Sub 隐藏() for i=1 to x x--行号
if sheets(1).cells(i,1)=1 then
Rows(i).Select
Selection.EntireRow.Hidden = True
next i 直接输入一组数如“35”后,自动转换成日期格式 解答:A1中输入,B1中转换。。B1=Left(A1,4)&"—"&MID(A1,5,2)&"—"&MID(A1,7,2)&" "&MID(A1,9,2)&":"&MID(A1,11,2)&":"&MID(A1,13,2)
把sheet1到sheet200的a19这一格,依序贴到sheet0的a1到a200 解答:方法一:公式
可在A1储存格输入以下公式,再行拖曳至A200即可。
=INDIRECT("Sheet"&ROW()&"!A19")
方法二:VBA
Sub Macro1()
'选择工作表 sheet0
Sheets("sheet0").Select
For r = 1 To 200
'将工作表 1~200 里面的 D17 复制到 sheet0 的 A1~A200
Cells(r, 1) = Worksheets(CStr(r)).Range("D17")
On Error Resume Next
End Sub A列记录几百条,如何对这列计数(重复的数值不计) 我只能做到新建一列,B列,然后第一个单元格countif($A$1:$A$100,A1),然后拖动到全部新列。最后在新列下面用sumif(B1:B100,1) 谁有更好地方法? 解答:1、试试这个:{=SUM(IF(COUNTIF(A1:A100,A1:A100)=1,1,0))} 2、操作:①A1作公式栏,A2作字段名栏,如原该两栏有数插入2行。在A1输入:=SUBTOTAL(3,A$2:A$5000) 统计记录数或:=SUBTOTAL(9,A$2:A$5000) 数据汇总 ②选:数据-->筛选-->高级筛选-->选择不重复的记录。 ③复原选:数据-->筛选-->高级筛选-->全部显示。 3、试试这个: {=SUM(IF($A$1:$A$100="","",1/(COUNTIF($A$1:$A$100,$A$1:$A$100))))} 4、请解释一下,因为我单独使用COUNTIF($A$1:$A$100,$A$1:$A$100)数组公式时,它仅仅计算第一个也就是A1的个数. 5、我发觉你的这办法,只对唯一的数据进行了计数,而重复的数据全部未计入(是不是应该将重复的数据也计上一个?)打哈欠的“{=SUM(IF(COUNTIF(A1:A100,A1:A100)=1,1,0))}”也是这样。 TO 剑魔版主你公式中的“1/(COUNTIF($A$1:$A$100,$A$1:$A$100))”像是一个倒数,怎么理解? 6、用倒数是这个意思:如果只出现一次,数组中的相应项统计为1,其倒数为1,Sum统计计1 如果出现 N 次,其倒数为1/N,出现了N次,求和就是Nx1/N,最后Sum统计就只计1。 如果有文本串"YY0115",我想取第三、四的值"01",应该用什么函数 解答:1、=mid("YY)&"" 2、如果你的A1中的数值一定包含后四位阿拉伯数字的话,你可以用这个: =LEFT(RIGHT(A1,4),2)=LEFT(RIGHT(A1,4),2)=LEFT(RIGHT(A1,4),2) 3、我的实际工作中的数据还没有如此规律,该怎么办?如:A1="YY0105",A2="99065",A1取"01",A2取"99"。能否用一个函数去掉A1中"YY",然后都是从阿拉伯数字的第一位开始取两位数? 4、如果阿拉伯数字数量不定,但是以2个英文字母开头(或无英文字母),可以用以下公式:(设数据在A1中) =IF(ISNUMBER(VALUE(A1)),MID(A1,1,2),MID(A1,3,2)) 5、数组公式: {=MID(A1,MIN(IF(EXACT(LOWER(MID(A1,ROW(INDIRECT("A1:A256")),ROW(INDIRECT("A2:A257")))),UPPER(MID(A1,ROW(INDIRECT("A1:A256")),ROW(INDIRECT("A2:A257"))))),ROW(INDIRECT("A1:A256")),"")),2)} 怎样将文字和数字分2列显示 中行10091
正在加载中,请稍后...拒绝访问 | www.excelpx.com | 百度云加速
请打开cookies.
此网站 (www.excelpx.com) 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(42c1ea8a85723a7c-ua98).
重新安装浏览器,或使用别的浏览器if函数为什么算的不对?条件是对的,但是结果是错的。 怎么回事_百度知道
if函数为什么算的不对?条件是对的,但是结果是错的。 怎么回事
如A5=SUM(A1:A4)=1867.74 A6=1867.74
(单元格格式是数值,保留整数位)A7=IF(A6-A5=0,&正确&,&不正确&)
按说A7应该是显示正确的,可为什么我这一直出的是 不正确 呢?抑郁啊
我有更好的答案
EXCEL中显示的数值并不一定是真实值,而是四舍五入后的显示值,所以常常会出现看到数值相同,但事实上并不相同的情况。尤其是小数运算还存在浮点误差,两个相同的小数相减,其结果并一定是0,有可能存在很小的浮点误差。解决此问题的方法,一是中间计算过程用ROUND函数保留小数位数,二是直接判断是否相等,不要用相减等于0的方法:=IF(A6=A5,&正确&,&不正确&)
采纳率:75%
来自团队:
a6-a5==0,一个等号是赋值
本回答被提问者采纳
好像应该是a7=if(a6-a5==0,&正确&,&不正确&)
A6-A5=0 改为A6-A5==0
A7=IF(A6-A5=0 ?&正确&:&不正确&)
1条折叠回答
其他2条回答
为您推荐:
其他类似问题
if函数的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。~~~ 延时不准,请大家来帮忙啊!!!~~~ 我头大了好久了,谢谢先!!
我用STC89C52RC做的一个测温湿度的节点,测试发现定时不准,我不知道为什么。我想问下面3个问题:
【1】我的程序和实现是否有问题?
【2】这个误差是否会与环境温度有关系? (节点测得的温度就是它的工作的环境温度,传感器和单片机、晶振都在一起。)
【3】除了上面2点,可能造成这个问题的原因还有什么?
我是这样实现的:
【1】用Timer0,计时50ms,晶振11.0592MHz
【2】在Timer0的中断程序里面,计数每20个50ms就是1秒,然后每到一定时间(比如5分钟)就将 sendDataFlag置1一次,
【3】main函数里面是while的死循环,如果sendDataFlag为1,就向上位机发送一次温湿度值,并把sendDataFlag置0。
下面上位机收到的结果,
我们可以看到有段时间7:29至8:19这段时间定时比较准,每5分钟一次
但是6:43至7点23这段时间定时就非常不准。
在我以往的试验中,也有这样不准的情况出现,每5分钟就会有1秒左右的误差。下面是昨晚试验的数据:
请大家指点一下,我迷惑了很久了。谢谢先!
可以闰秒,隔一段时间对计时修正,有条件用电网作时钟源,精度很高
中断判断==改成 》=& &&&if(++t&=20)t1++;
回复【1楼】1ongquan&&
可以闰秒,隔一段时间对计时修正,有条件用电网作时钟源,精度很高
-----------------------------------------------------------------------
感谢楼上的回复,不过我还是想找出问题的原因来。
我总感觉应该不是温度的引起的,因为同样在19度左右,有比较精确的情况出现,也有误差较大的情况出现。
请大家帮我看看我的定时器使用有没有问题?比如初始化定时器、中断程序等。
回复【2楼】yao1&&
中断判断==改成 》=& &&&if(++t&=20)t1++;&&
-----------------------------------------------------------------------
感谢2楼的回复。
好的,我试试。
不过我在写程序时,考虑到做&&=&要比&==&多化时间,所以我就用了&==&
能解释一下在什么样的情况下这个程序会跳过20吗?
我也是菜鸟, 我的理解(如果错误见谅):
& &发送数据的函数如果时间大于50ms就会出现 如果程序在发送数据 此时恰好定时器进入中断并且T刚好也加到20 那么发送完数据再进入中断时就错过了这次的判断
& &&&》= 已经包含了== 不会多花时间的 只要检测到==20就会进入中断 如果检测不到20 才会继续检测21.22.23 ....
你如果写==如果检测不到20, 就会隔20次才会再次检测 ;而》=是检测不到20,就隔1次再检测
中断判断==改成 》=& &&&if(++t&=20)t1++;
回复【5楼】yao1&&
& & 我也是菜鸟, 我的理解(如果错误见谅):
& &发送数据的函数如果时间大于50ms就会出现 如果程序在发送数据 此时恰好定时器进入中断并且t刚好也加到20 那么发送完数据再进入中断时就错过了这次的判断
& &&&》= 已经包含了== 不会多花时间的 只要检测到==20就会进入中断 如果检测不到20 才会继续检测21.22.23 ....
你如果写==如果检测不到20, 就会隔20次才会再次检测 ;而》=是检测不到20,就隔1次再检测
&&还有就是c语言的这种计数本来就不是很准确 你要很准确要用汇编写
-----------------------------------------------------------------------
感谢你的回复。我更菜, 大家一起讨论下挺好的。
我引用你的话:“发送数据的函数如果时间大于50ms就会出现 如果程序在发送数据 此时恰好定时器进入中断并且t刚好也加到20 那么发送完数据再进入中断时就错过了这次的判断 ”
我觉得这个有问题。我认为判断不会错过,因为中断发生的时候,发送数据程序就暂停了,而是跳过去执行中断子程序,等中断完成后再跳回去继续执行发送数据的程序。 你觉得我说得对不对?
顺便说一下,在发送数据的过程中不会有其它的中断产生了。
不过我现在已经改了程序,用&=了,目前还是准的,有进一步结果我会来更贴的。
另外,我澄清一下,“考虑到做&&=&要比&==&多花时间” 我指的是执行判断指令==的时间比执行&=这个判断的时间长,而不是说延时的时间会更长。我看你好像误解我的意思了。
回复一下2楼,改用 &= 后,还是不准。
这是最新的数据,每5分钟还是有1秒左右的误差。
难道是你的程序里面有其他的中断影响了?或者程序里有中断屏蔽?
试试看STC的办法,还能省电~~
(原文件名:QQ截图11.png)
回复【10楼】ruizhixing&&睿
难道是你的程序里面有其他的中断影响了?或者程序里有中断屏蔽?
-----------------------------------------------------------------------
没有其它中断了。也没有屏蔽过中断。
还有就是C语言的这种计数本来就不是很准确1周期慢10几个微妙 时间长了就会有误差&&C语言的计数没有计算机那么准确的,误差1秒 我认为正常 你要很准确得用汇编写
回复【11楼】renpeng009&&大鹏集成
试试看stc的办法,还能省电~~
(原文件名:qq截图11.png)
-----------------------------------------------------------------------
呵呵 谢谢回复。
不过我主要是想搞清楚为什么会这样?
如果大家能确认我对定时器的用法没有问题,而且大家认为通过计数器只能实现这样的精度,那么我就再找其它解决方案。
咋不见读取温度的部分?
既然你自己都怀疑了,干脆去掉读取温湿度部分,发送假数据看看时间还准不准。
话说这么长的时间间隔,如果不采用RTC的话,还不如由上位机发送请求呢。。
看你程序中计数器判断的时候改为21和senddatainterval+1,结果可能会稍微好的……
你的T0中断里面重新送初值-------你想当然的认为TL0是0,其实是错误的.
如果要定时准确:
1. 把T0停下来
2. 给(TL0 TH0)这个 16-BIT 加上一个16-BIT常数(比你的那个0x4c00要稍大些-----要把暂停的时间考虑进去)
3. 重新启动T0
时间慢主要原因:
1、中断延迟
2、定时器用了软重赋值
头像被屏蔽
提示: 作者被禁止或删除 内容自动屏蔽
同意20楼 定时器初值改成:
TH0=()/256; //0X4C
TL0=()%256; //0XD0
TL0不赋值 每次多计数208 所以你的时间会变慢
首先感谢楼上各个楼层的回答。
回复17楼和20楼,
因为我计算出来的常数是0x4C00,TL0是从0开始的,所以就不用重装了。(不重装应该就是从0开始吧?)
我这样做的目的就是为了避免修正中断开始到定时器赋值这段时间。我的想法是:中断开始的时候,我只给TH0重装赋值,而TL0还是让它继续走,这样只要能保证在TH0的赋值过程能在TL0从0走到255之间完成,那么定时器就应该是准的。
我不知道这个想法正确否?
大家指正一下。
======================
回复【20楼】bbs2009&&
& &本人愚见:
& & 5 分钟就差1秒 绝对是程序有问题。 俺 n年前 c 做的 沙盘配解说的显示控制 15 分 也不会差 1秒。
& & 有二点供你参考:
& & 一:11.0592 m&&是否可得到 精确 的 20ms&&延时 值得 商榷,需要修正。
& & 二:c 可以写出精确的定时器程序, 但你要修正按公式计算的 tho tl0 数值,考虑进入中断到给
& && &&&定时器赋值的延时。
-----------------------------------------------------------------------
回复【17楼】gwdong&&
你的t0中断里面重新送初值-------你想当然的认为tl0是0,其实是错误的.
如果要定时准确:
1. 把t0停下来
2. 给(tl0 th0)这个 16-bit 加上一个16-bit常数(比你的那个0x4c00要稍大些-----要把暂停的时间考虑进去)
3. 重新启动t0
-----------------------------------------------------------------------
回复【21楼】yao1&&
同意20楼 定时器初值改成:
th0=()/256; //0x4c
tl0=()%256; //0xd0
tl0不赋值 每次多计数208 所以你的时间会变慢
-----------------------------------------------------------------------
难道是我的常数计算错了?!!
0x4C00就是19456,
而 ()*12/.05s=50ms 这个好像没问题吧
我当时特意找了一个低8为0的常数。我想这样就可以不用给TL0赋值了。
yao1能否说一下你这个0x4cd0是怎么算出来的?我没看明白。
我是这么算定时器初值的:
& &12个时钟周期=1个机器周期=12*(1/.09us (晶振11.0592)
&&若t=50ms 那么N==45872&&要计数45872 TH0 TL0应该装入总数为=19664
&&把1求模(十六进制4C) 装入TH0
&&对256求余8(十六进制D0) 装入TL0
定时器初值改成:
TH0=()/256; //0X4C
TL0=()%256; //0XD0
我四舍五入误差问题& &
12个时钟周期=1个机器周期=12*(1/.085us (晶振11.0592)
若t=50ms 那么N==45872&&要计数46080 TH0 TL0应该装入总数为=19456
&&把1求模(十六进制4C) 装入TH0&&
&&对256求余(十六进制0) 装入TL0
你的算法正确
回复【24楼】yao1&&
& &我是这么算定时器初值的:
& &12个时钟周期=1个机器周期=12*(1/.09us (晶振11.0592)
&&若t=50ms 那么n==45872&&要计数45872 th0 tl0应该装入总数为=19664
&&把1求模(十六进制4c) 装入th0
&&对256求余8(十六进制d0) 装入tl0
-----------------------------------------------------------------------
“12个时钟周期=1个机器周期=12*(1/.09us ”&&这个1.09是约数,要准确的话,下面这样算:
0.05/12*80,初值为=C00 跟我算的一样,对不对?
回复【15楼】huayuliang&&花生
咋不见读取温度的部分?
既然你自己都怀疑了,干脆去掉读取温湿度部分,发送假数据看看时间还准不准。
话说这么长的时间间隔,如果不采用rtc的话,还不如由上位机发送请求呢。。
-----------------------------------------------------------------------
温度读取部分无关,我就没放上来干扰视线了。
我手头有块12c887的RTC,一个小时要慢几分钟,也不知道为何。
我认为5分钟间隔不算太长,应该可以做到精确的。
看看这篇文章 用c51语言实现单片机高精度定时的新算法 (原文件名:用C51语言实现单片机高精度定时的新算法.pdf)
头像被屏蔽
提示: 作者被禁止或删除 内容自动屏蔽
回复【16楼】Dalong357&&
看你程序中计数器判断的时候改为21和senddatainterval+1,结果可能会稍微好的……
-----------------------------------------------------------------------
这样就在毫秒和秒级别都多了一次循环出来,不是吗?这样会更慢吧?
回复【31楼】bbs2009&&
还是愚见:
1. 必须给tl0& &赋值&&。
2. 必须修正& & 0x4c00。不然一定慢 。
-----------------------------------------------------------------------
感谢您的回复。
能否解释一下第一点的原因?或者说如果不赋值给TL0会怎样? (千万别说定时会慢哦&&呵呵)
我想当然的认为不重新赋值计数器还是从0开始计数的。
另外,怎么没有18楼和25楼? 奇怪&&呵呵
回复【33楼】haozi007
-----------------------------------------------------------------------
18 25 是我发的贴 发现发出来有问题就删除了
看看30楼我发的那篇文章看来你只能修正TH0 TL0了
回复【34楼】yao1&&
18 25 是我发的贴 发现发出来有问题就删除了
-----------------------------------------------------------------------
呵呵 谢谢& &其实这个问题不用回答,我写出来供大家娱乐一下的 :)
看你的实验现象是大概5分钟慢1S 那50ms大概慢0.2ms 你让计数器计数到49.8ms进位看看
我大概算下修正:TH0=0X4C; TL0=0XB4;
回复【37楼】yao1&&
看你的实验现象是大概5分钟慢1s 那50ms大概慢0.2ms 你让计数器计数到49.8ms进位看看
我大概算下修正:th0=0x4c; tl0=0xb4;
-----------------------------------------------------------------------
这样肯定不行,误差不到1秒,按0.2ms每50ms算误差肯定更大。
我读了你上面付的文章,我觉得应该是每次中断都延迟了中断转移指令周期的时间(T0),但是文章里面提到的T2和T3我就不是很理解了。有朋友出来指点一下吗?
另外,现在这个延时每次慢的时间是随机的,不是一直5分钟慢1秒。有时候有是准的,有时候又会慢。
所以我觉得还是要找出慢的原因来才能最终解决这个问题。
当然,我也很感谢前面回帖的各位网友,给我指点了很多应该怎么做来解决的这个问题的办法和方向。但是到目前位置,还是没人能回答一下我这样做为什么会慢的问题。
回复【30楼】yao1&&
&&看看这篇文章 用c51语言实现单片机高精度定时的新算法 (原文件名:用c51语言实现单片机高精度定时的新算法.pdf)
-----------------------------------------------------------------------
感谢您这么费心。我看了文章,有几个问题,大家指点一下:
【1】T0 中断转移指令周期,这个如何找到?技术手册吗? (我单片机才入门3个月不到,希望大家能用我可以懂的语言来回答)
【2】T2 中断返回指令的执行周期&&(为什么这个指令会影响定时精度?)
【3】T3 中断返回断点后执行下一条指令的周期 (为什么这个指令会影响定时精度?)
若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用2个机器周期)。
  在实际应用中,定时常采用中断方式,如进行适当的循环可实现几秒甚至更长时间的延时。使用定时器/计数器延时从程序的执行效率和稳定性两方面考虑都是最佳的方案。但应该注意,C51编写的中断服务程序编译后会自动加上PUSH ACC、PUSH PSW、POP PSW和POP ACC语句,执行时占用了4个机器周期;如程序中还有计数值加1语句,则又会占用1个机器周期。这些语句所消耗的时间在计算定时初值时要考虑进去,从初值中减去以达到最小误差的目的。
汗! 我学了5个月了也是很多不明白 所以混论坛提高下自己
高手一般都懒的回答我们的问题的 一般都是水平差不多的回答
用C语言写的,定时器工作在手动重装初值模式下,定时时间是不能精确的预测的。
建议用自动重装初值的工作模式。
回复【42楼】jing43&&
用c语言写的,定时器工作在手动重装初值模式下,定时时间是不能精确的预测的。
建议用自动重装初值的工作模式。
-----------------------------------------------------------------------
感谢您的回复,恕我太愚,我想追问一下:为什么“用c语言写的,定时器工作在手动重装初值模式下,定时时间是不能精确的预测的”?
特别是在我的这个特定例子,我觉得中断跳转、压栈和重装时间没有超过256个机器周期,应该是准确的呀?我这样想错在哪里呢?
不过顺便说明一下,从我观察到的现象来看,误差确实是随机的(至少我还没发现规律),这个比较复合您说的“不能精确的预测”。
回复【41楼】yao1&&
& &汗! 我学了5个月了也是很多不明白 所以混论坛提高下自己
高手一般都懒的回答我们的问题的 一般都是水平差不多的回答
-----------------------------------------------------------------------
不要汗 我学了3个月,但又没说是零基础开始学的 呵呵。和您交流非常愉快,感谢您花这么多时间在我这个问题上,希望您自己也有所收获。
高手们比较忙吧&&呵呵&&开个玩笑。 说实话,我觉得这个问题要说清楚还是要花点时间的,他们有更重要的事情要做,这个我可以理解的。
我看程序已经彻底凌乱了 呵呵,下面这个截图是最新的数据,居然还有4分钟的间隔。
在没人人回答我的问题之前,我打算先暂时放一放了, 今天耗了大家太多时间,我比较过意不去
你上位机不会有问题吧
回复【46楼】packer&&
你上位机不会有问题吧
-----------------------------------------------------------------------
在您的提示下,我检查了一番,没有看出明显问题。
我觉得我们可以暂时排除上位机有问题的可能性。
今天头已经彻底晕了,等明天我重新搭个电路,就只做定时和串口通信,试验过后再来跟大家汇报。
再次感谢楼上各位的帮忙,祝大家晚安!
LZ你把你T0中断服务程序中开始的“TH0 = 0x4C;”改成如下这样试试:
TH0 = 0x4C-TH0;
如果还不行,用方式2吧。
回复【15楼】huayuliang 花生
咋不见读取温度的部分?
既然你自己都怀疑了,干脆去掉读取温湿度部分,发送假数据看看时间还准不准。
话说这么长的时间间隔,如果不采用rtc的话,还不如由上位机发送请求呢。。
-----------------------------------------------------------------------
回复【48楼】eduhf_123&&经历
lz你把你t0中断服务程序中开始的“th0 = 0x4c;”改成如下这样试试:
th0 = 0x4c-th0;
如果还不行,用方式2吧。
-----------------------------------------------------------------------
感谢回复&&不过我试了一下,误差比原来的还大。据我分析,应该是定时器被关闭后,没有补偿这3行代码执行时间所致。
不过我受你这个启发,把关闭、打开定时器代码去掉,只重装了th0,下面是执行的效果:(这是logger里面出来的数据,可以看到毫秒)
11:54:07.500 data received: ID 100 1 - 50 0 22 6, Length:5.
11:59:11.734 data received: ID 100 1 - 50 0 22 4, Length:5.
12:04:13.890 data received: ID 100 1 - 49 0 22 5, Length:5.
12:09:14.906 data received: ID 100 1 - 49 0 22 4, Length:5.
12:14:15.062 data received: ID 100 1 - 49 0 22 5, Length:5.
12:19:15.625 data received: ID 100 1 - 49 0 22 5, Length:5.
12:24:15.781 data received: ID 100 1 - 49 0 22 4, Length:5.
12:29:16.250 data received: ID 100 1 - 49 0 22 4, Length:5.
奇怪的是5分钟的定时飘忽不定,再次印证了42楼说的,但是为什么会这样呢?
来跟大家汇报一下今天晚上的测试结果,貌似准确了。
方法就是受48楼的朋友启发,重装TH0时考虑已有的计数进位,只是我没有关计数器。
我很惊讶,为什么中断跳转过程难道需要这么长时间?
下面是刚刚出炉的测试数据:
这是我很不喜欢用c的原因,尤其在对延时有较高要求的情况,我都要查看下汇编,是否有隐患
回复【51楼】haozi007&&
来跟大家汇报一下今天晚上的测试结果,貌似准确了。
方法就是受48楼的朋友启发,重装th0时考虑已有的计数进位,只是我没有关计数器。
我很惊讶,为什么中断跳转过程难道需要这么长时间?
下面是刚刚出炉的测试数据:
-----------------------------------------------------------------------
这个数据现在只能说定时看起来准确了,其实问题很严重:看你在50楼发上来的数据就知道了,每两次收到数据的时间都比5分钟略长一点(头两行间隔的4秒多认为是上位机的问题,其他时间间隔最长的也有2.156秒,2156ms/300s≈72ms/s,快到1%了)。
不是说“中断跳转过程”有这么长,而在于在中断跳转之前还有“中断响应时间”存在(比如有很长一段关中断的时间、比如更高优先级或同级的中断服务程序在运行)。
如果一定要时间很准确,就一定要解决上面两个问题:
1、要减小关中断引起的中断响应延迟,就要尽量减少关中断、及时要关也尽量晚关并尽量早开(关中断过程中只处理临界区代码)。
2、要解决更高级中断服务程序或同优先级中断服务程序引起的中断响应延迟,就只能把T0的中断单独设为高优先级。这时候就只剩低优先级可以用了,如果其余中断服务程序还要区分优先级怎么办呢?
  这时候可以通过类似Linux中对中断服务程序的“上半段+下半段”处理方式给最低优先级的中断服务程序加个“壳”,让它们在主程序优先级上运行。
  具体的实现方式就是,把“中优先级”中断跟“低优先级”中断在IP中的对应位都设为0,但在“低优先级”中断服务程序中只把
实际的中断服务程序的入口地址给压入堆栈就返回,实际的中断服务程序写成一般子程序的形式(函数头部后面不带“interrupt N”),最后禁止这个子程序与其他子程序进行覆盖分析就好(或者把它的局部变量都定义成static的)。
  原理在于,“低优先级”中断服务程序中把实际入口压入堆栈后返回,编译器生成的是RETI指令,这时候就把51的“优先级锁”给复位了,CPU运行在主程序级别上,可以响应任何新的中断请求,但由于我们的压栈操作,这里的“返回”并没有回到主程序中的“断点”,而是“返回”到了实际的中断服务程序入口,在实际的中断服务程序返回的时候才真正返回到原来“断点”——这样就实现了在主程序级别上运行的“低优先级”中断服务程序,当然了,实际的中断服务程序中还是要保护“现场”。
回复【52楼】packer&&
这是我很不喜欢用c的原因,尤其在对延时有较高要求的情况,我都要查看下汇编,是否有隐患
-----------------------------------------------------------------------
C与汇编混合编程就好。
感谢您的回复。
首先我强调一下,没有其它中断了,这个定时器是唯一的中断。
其次,我是没有关中断的,我就是想避免由此带来的延迟。
现在的问题在于每次定时的误差表现出来是随机的。同样的程序,有时候快,有时候慢,有时误差大,有时误差小,有时又准了(或没有可测量的误差)
不知道各位是否能解其详?
回复【53楼】eduhf_123&&经历
回复【51楼】haozi007&&
来跟大家汇报一下今天晚上的测试结果,貌似准确了。
方法就是受48楼的朋友启发,重装th0时考虑已有的计数进位,只是我没有关计数器。
我很惊讶,为什么中断跳转过程难道需要这么长时间?
下面是刚刚出炉的测试数据:
-----------------------------------------------------------------------
这个数据现在只能说定时看起来准确了,其实问题很严重:看你在50楼发上来的数据就知道了,每两次收到数据的时间都比5分钟略长一点(头两行间隔的4秒多认为是上位机的问题,其他时间间隔最长的也有2.156秒,2156ms/300s≈72ms/s,快到1%了)。
不是说“中断跳转过程”有这么长,而在于在中断跳转之前还有“中断响应时间”存在(比如有很长一段关中断的时间、比如更高优先级或同级的中断服务程序在运行)。
-----------------------------------------------------------------------
回复【50楼】haozi007
-----------------------------------------------------------------------
用C写好程序后编译,再反汇编成汇编代码,就可以看到问题。
定时器中断响应后,最先执行的不是你装初值的代码!
而是先很多的PUSH ***,它叫保护现场,你来的地方(中断产生的时机)不同,会导致保护现场所执行的代码不同。
还有如果有其他的中断正被执行,那你的定时器的中断还可能挂起一阵子才能得到执行,这时你装初值的操作显然被延迟了。
学习气氛浓哇…路过!
阿莫电子论坛, 原"中国电子开发网"
, 原www.ourdev.cn, 原www.ouravr.com

我要回帖

更多关于 excel的if函数怎么用 的文章

 

随机推荐