搜索
bottom↓
回复: 47

如何写出好的代码(疑问)

[复制链接]

出0入0汤圆

发表于 2017-3-27 10:18:17 | 显示全部楼层 |阅读模式
      我不知道大家有没有这个想法,这种想法已经在我心里好久了,其实一直不敢去面对,如何写出好的代码。  程序一般写出来能用那是必须的,一定要满足客户的需求(这是第一条件)。其次我现在的思想是我为什么写出的代码自己总感觉不好呢,可能是我见识的太少了,刚刚毕业一年。

比如1:
   一个100us的中断TIM1去读取ADC的数据(这里没有DMA功能的单片机)。理论上在中断里面不能去读取ADC的数值,并做运算,(这里大概需要5us)。一次差5us    1秒钟差就很大了,这个和我的设计有很大的出入
  因为我需要尽可能的保证100us一次时间间隔的准确度,中断里面尽可能不要去做数据运算。那我需要开一个更快的中断比如20us一次的TIM2 来判断100us的标志位,用这个TIM2来处理数据,这样能保证100us的准确性。
但是这个势必会带来很大的资源浪费。而且单片机会处于高调度的。


比如2:
   源码在不优化的情况下,调用结构体数组比调用普通的数组慢。这个从反汇编可以看到,调用结构体的反汇编比数组长很多(stm32 用的是IAR编译器)。但是在最高优化下 你定义的结构体和全局数组就差不多了,因为结构体已经被优化成全局变量了。那我是使用结构体呢还是全局变量,结构体的优点是程序很明了,简单。这里的慢建立在大数据流的情况下,几个数是看不出来的。

以上有说的不对的地方欢迎修正(PS:肯定有不对的地方)

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2017-3-27 10:25:58 来自手机 | 显示全部楼层
只要在100us内做完就不会差

出0入0汤圆

发表于 2017-3-27 10:27:58 | 显示全部楼层
本帖最后由 qq854149876 于 2017-3-27 10:29 编辑

个人见解,
1. 进了中断后别关TIM,TIM自动重装,中断里运算20us,出来后80us又会进TIM中断,这100us还一直都是准的啊
2. 我一般不纠结这个,最多注意下对齐、以及成员摆放顺序问题。程序的可靠性不应该建立在这种基础上啊。

出0入0汤圆

发表于 2017-3-27 10:29:02 | 显示全部楼层
中断里面只要重载了初值就重新计数了,不管你中断处理需要多少时间,只要在下次中断来之前处理就不会有差,难道你的重装初值在中断处理的最后面?

出0入0汤圆

 楼主| 发表于 2017-3-27 10:29:47 | 显示全部楼层
本帖最后由 -佛听- 于 2017-3-27 13:05 编辑
dz46316740 发表于 2017-3-27 10:25
只要在100us内做完就不会差


void TIM4Isr(void)
{
  if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)  
  {
    TimingSamplingADCValue();  
    TIM_ClearITPendingBit(TIM4 , TIM_IT_Update);    //清除在后面
  }
}

出0入0汤圆

 楼主| 发表于 2017-3-27 10:36:11 | 显示全部楼层
本帖最后由 -佛听- 于 2017-3-27 11:12 编辑

sorry 我弄错了  我的定时器是自动重装载的

出0入0汤圆

发表于 2017-3-27 11:09:52 | 显示全部楼层
少年,你中断里接个IO,接个逻辑分析仪看看时序就知道了,你这属于概念不清,跑马灯都没跑熟。。。别看跑马灯程序简单。

出0入0汤圆

 楼主| 发表于 2017-3-27 11:15:02 | 显示全部楼层
JnzGoto 发表于 2017-3-27 11:09
少年,你中断里接个IO,接个逻辑分析仪看看时序就知道了,你这属于概念不清,跑马灯都没跑熟。。。别看跑马 ...

哦,我从来没觉得如何东西是简单的。其实我的本意是多个中断里面跑着任务,在交错中断期间。怎么来保证中断任务的实时性。只是我表达的不清楚(ps:其实我表达错误了,我把中断清除标志和定时器的自动重装载弄错了)

出0入0汤圆

发表于 2017-3-27 11:22:34 | 显示全部楼层
第二条:
1. 可读性最重要,效率不那么重要,因为现在都是计算能力过剩。
2. 高可靠性场合,尽量少用指针。

出0入0汤圆

发表于 2017-3-27 11:23:59 | 显示全部楼层
只要不累计就好,一般没有精度要求不用特殊处理,高精度的可能要用FPGA/CLPD之类的,MCU进入中断的时间不好确定;

出0入0汤圆

发表于 2017-3-27 11:31:09 | 显示全部楼层
建议多看看别人的代码,另外建议玩一下ucos,还有一本嵌入式系统构件,可以学一下

出0入0汤圆

发表于 2017-3-27 11:34:20 | 显示全部楼层
你使用和設計INTERRUPT的概念和方法有誤
要從基本再看一次

出0入0汤圆

 楼主| 发表于 2017-3-27 11:53:38 | 显示全部楼层
xiaolaba 发表于 2017-3-27 11:34
你使用和設計INTERRUPT的概念和方法有誤
要從基本再看一次

是哪里有误的,麻烦指教下。按照我的理解 中断里面就是置标志位的。里面不去做数据的处理和运算。因为里面做数据运算会影响 其他中断的及时性和准确性。不知道哪里有问题,我是真心想请教的

出0入0汤圆

发表于 2017-3-27 12:04:55 | 显示全部楼层
1,第一反应就是楼主认为跳出中断是定时器才重新开始;看上面楼层,楼主已经知道这个问题了;
2,千万不要认为代码长执行时间就长;

出0入0汤圆

发表于 2017-3-27 12:15:50 | 显示全部楼层
-佛听- 发表于 2017-3-27 11:53
是哪里有误的,麻烦指教下。按照我的理解 中断里面就是置标志位的。里面不去做数据的处理和运算。因为里 ...

你的ADC轉換完畢用INT就好了
啟動ADC設FLAG就好了
在INT響應常式裡面等待ADC完成, 不合適, 但是慢速可用

試試看

  1. bit flag;

  2. #pragma interrupt_handler ISR

  3. void ISR(void)
  4. {
  5.    flag=1;
  6. }

  7. void main()
  8. {
  9.    --
  10.    --
  11.    while(1)
  12.    {
  13.       --
  14.       --
  15.       /* Wait for the ISR to set the
  16.       * flag; reset it before
  17.       * taking any action. */
  18.       if (flag)
  19.       {
  20.          flag = 0;
  21.          /* Perform the required action here */
  22.       }
  23.    }
  24. }
复制代码



出0入0汤圆

发表于 2017-3-27 12:28:03 | 显示全部楼层
只能说多看,多读,多写了

出0入0汤圆

发表于 2017-3-27 12:39:10 来自手机 | 显示全部楼层
TBG3 发表于 2017-3-27 11:22
第二条:
1. 可读性最重要,效率不那么重要,因为现在都是计算能力过剩。
2. 高可靠性场合,尽量少用指针。 ...

为何高可靠性场合少用指针呢

出0入0汤圆

 楼主| 发表于 2017-3-27 13:03:15 | 显示全部楼层
xiaowu191 发表于 2017-3-27 12:04
1,第一反应就是楼主认为跳出中断是定时器才重新开始;看上面楼层,楼主已经知道这个问题了;
2,千万不要 ...

  是我搞错了,我早知道是那样的 最近是事情太多了,把自己给搞懵逼了 。我的意思是在执行那中断服务程序的5us      怎么保证其他中断的实时性

出0入0汤圆

 楼主| 发表于 2017-3-27 13:11:55 | 显示全部楼层
xiaolaba 发表于 2017-3-27 12:15
你的ADC轉換完畢用INT就好了
啟動ADC設FLAG就好了
在INT響應常式裡面等待ADC完成, 不合適, 但是慢速可用

谢谢你耐心的恢复,但是我的意思是多个中断任务在 切换的时候怎么保证中断的实时性。麻烦您了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入93汤圆

发表于 2017-3-27 13:56:24 | 显示全部楼层
-佛听- 发表于 2017-3-27 13:11
谢谢你耐心的恢复,但是我的意思是多个中断任务在 切换的时候怎么保证中断的实时性。麻烦您了 ...

请问哪个理论说了中断在执行过程中不会被打断?
最好能精确到架构、MCU型号、理论名称,让我们大家一起来鄙视它。

出0入0汤圆

发表于 2017-3-27 14:05:11 | 显示全部楼层
我也是工作不到一年的新手,看了楼主的标题,第一反应是楼主应该是有代码框架方面的疑问,或者是非阻塞编程方面的疑问。
解决方案就是时钟节拍+状态机,可以解决好多问题,如果用OS的话,可以看看周慈航那本书,虽然是讲ucos的,但是对裸机编程也有很大启发。

下面楼主举的两个中断的例子,你那种中断里面置标志位的方式,不是已经解决了自己的问题了吗?那5us的计算,是在while里面进行的,并不影响中断发生呀。

出0入0汤圆

 楼主| 发表于 2017-3-27 14:29:10 | 显示全部楼层
takashiki 发表于 2017-3-27 13:56
请问哪个理论说了中断在执行过程中不会被打断?
最好能精确到架构、MCU型号、理论名称,让我们大家一起来 ...

stm32  是不是只有高优先级的中断可以打断地优先级的    难道我错了

出0入0汤圆

 楼主| 发表于 2017-3-27 14:32:43 | 显示全部楼层
东北小灰灰 发表于 2017-3-27 14:05
我也是工作不到一年的新手,看了楼主的标题,第一反应是楼主应该是有代码框架方面的疑问,或者是非阻塞编程 ...

在while里面执行怎么保证我要的实时性呢??  如果是其他任务呗打断进的中断,那么中断返回必然是原来被打断的任务。那我在中断里面置的标志位,要等到循环任务进行到while中断的判断标志位,早不知道过时多少时候了。其实我早想过这些问题了  ,我既要保证中断的准确性 又要保证 数据更新的及时性   无奈脑子太笨实在想不到好的办法

出0入0汤圆

 楼主| 发表于 2017-3-27 14:35:01 | 显示全部楼层
takashiki 发表于 2017-3-27 13:56
请问哪个理论说了中断在执行过程中不会被打断?
最好能精确到架构、MCU型号、理论名称,让我们大家一起来 ...

如果我错了,请尽情的批判我   我发现我越来越糊涂了

出0入8汤圆

发表于 2017-3-27 15:01:51 | 显示全部楼层
不是老鸟,个人见解:

1.实时性的满足大多时候不是靠“更快的中断”或“更高优先级的中断”来实现的,原因你是知道的——“势必会带来很大的资源浪费。而且单片机会处于高调度的”
   常用的解法是继续细分耗时较长的任务。 另,我一直觉得实时性很多时候满足大周期上准确就可以了。

2.这个我觉得没必要回答,但是为了呈现出与楼主位问题的一致美……还是简单说下,在满足实时性的情况下,最先考虑的是程序的可读性,高内聚低耦合,全局的能少用就少用。

以上都不是绝对的。

出0入0汤圆

 楼主| 发表于 2017-3-27 15:13:04 | 显示全部楼层
Jmhh247 发表于 2017-3-27 15:01
不是老鸟,个人见解:

1.实时性的满足大多时候不是靠“更快的中断”或“更高优先级的中断”来实现的,原因 ...

还是你看懂了我问的问题,谢谢    那麻烦问下,如果是您遇到和我一样的问题你会怎么解决呢??? 我一直在纠结这个问题

出0入0汤圆

发表于 2017-3-27 15:13:52 | 显示全部楼层
-佛听- 发表于 2017-3-27 14:32
在while里面执行怎么保证我要的实时性呢??  如果是其他任务呗打断进的中断,那么中断返回必然是原来被 ...

哦,大概明白楼主的意思了,我认为还是非阻塞编程的问题。
可以用状态机把耗时长的任务“切碎”,这样while(1)一次循环执行的只是这个长任务的一步,程序中没有阻塞,这样一次while(1)的运行时间就会缩短很多,就会马上运行到判断标志位的地方。
楼主如果没有这方面的知识的话,可以参考一本《单片机编程魔法师》和《8051时间触发设计模式》这两本书,都是入门书籍。
我也是新手,如有错误也请指出,共同进步。

出0入8汤圆

发表于 2017-3-27 15:37:04 | 显示全部楼层
-佛听- 发表于 2017-3-27 15:13
还是你看懂了我问的问题,谢谢    那麻烦问下,如果是您遇到和我一样的问题你会怎么解决呢??? 我一直 ...

啊啊,已经说了我的做法就是“细分任务”,再具体我也说不上来了呀……你问题的本质就是多任务下的“任务划分”和“任务设计”,
你多多看这方面吧,再自己练习吧……时间久了你的感觉肯定会好起来,心里有底了会很欣赏自己的代码,哈哈,加油!

出0入0汤圆

 楼主| 发表于 2017-3-27 16:07:50 | 显示全部楼层
Jmhh247 发表于 2017-3-27 15:37
啊啊,已经说了我的做法就是“细分任务”,再具体我也说不上来了呀……你问题的本质就是多任务下的“任务 ...

我现在遇到的问题就是两通道的AD采样,然后滤波  关键是这个滤波算法没法细分 卡尔曼滤波算法  搞我的头大     

出0入0汤圆

发表于 2017-3-27 16:19:43 | 显示全部楼层
真必要卡尔曼滤波 ? 啥項目呀, 單憑幾句描述, 很難理解, STM32 有DMA的
如果8位機就靠你的算法功力了

出0入0汤圆

发表于 2017-3-27 16:20:21 | 显示全部楼层
-佛听- 发表于 2017-3-27 13:11
谢谢你耐心的恢复,但是我的意思是多个中断任务在 切换的时候怎么保证中断的实时性。麻烦您了 ...

真必要卡尔曼滤波 ? 啥項目呀, 單憑幾句描述, 很難理解, STM32 有DMA的
如果8位機就靠你的算法功力了

出0入0汤圆

发表于 2017-3-27 16:22:59 | 显示全部楼层
Ray______ 发表于 2017-3-27 12:39
为何高可靠性场合少用指针呢

指针容易出问题

出0入0汤圆

 楼主| 发表于 2017-3-27 16:42:49 | 显示全部楼层
xiaolaba 发表于 2017-3-27 16:20
真必要卡尔曼滤波 ? 啥項目呀, 單憑幾句描述, 很難理解, STM32 有DMA的
如果8位機就靠你的算法功力了 ...

我想用DMA   他使用的是ADC2  没有接在DMA总线上   硬件又不能修改  所以我在想办法

出0入0汤圆

 楼主| 发表于 2017-3-27 16:44:10 | 显示全部楼层
TBG3 发表于 2017-3-27 16:22
指针容易出问题

不一定的  指针还是要看用的人  ,在会用的人手里确实是个好东西  ,在不会用的人手里反而适得其反  我以前就吃了很多亏 确实用指针要小心 没把握就不要用

出0入0汤圆

 楼主| 发表于 2017-3-27 16:45:24 | 显示全部楼层
xiaolaba 发表于 2017-3-27 16:20
真必要卡尔曼滤波 ? 啥項目呀, 單憑幾句描述, 很難理解, STM32 有DMA的
如果8位機就靠你的算法功力了 ...

而且卡尔曼已经被我修改成最优版本的了     (当然还可以再优化,我的意思是我无法再对算法进行优化了)

出0入0汤圆

发表于 2017-3-27 17:01:53 | 显示全部楼层
本帖最后由 xiaolaba 于 2017-3-27 17:05 编辑
-佛听- 发表于 2017-3-27 16:42
我想用DMA   他使用的是ADC2  没有接在DMA总线上   硬件又不能修改  所以我在想办法  ...


http://www.st.com/content/ccc/re ... s/en.CD00258017.pdf

dual mode ADC

以前玩過這個, 沒仔細看, 也忘的差不多, IQ解調用DUAL MODE,  DMA 的, ARM Radio
http://www.weaksignals.com/

出0入0汤圆

 楼主| 发表于 2017-3-27 17:08:22 | 显示全部楼层
xiaolaba 发表于 2017-3-27 17:01
http://www.st.com/content/ccc/resource/technical/document/application_note/c4/63/a9/f4/ae/f2/48/5d ...

我看过双通道绑定   他的DMA1已经拿来ADC1的读取了  读取速度还不一样         本来直接双通道绑定 这样只要读取高16位就是ADC2的数据,低16位就是ADC1的数据    我发现这些糟心的事情都让我碰上了

出0入0汤圆

发表于 2017-3-27 17:27:25 | 显示全部楼层
-佛听- 发表于 2017-3-27 17:08
我看过双通道绑定   他的DMA1已经拿来ADC1的读取了  读取速度还不一样         本来直接双通道绑定 这样 ...

看來真不簡單
加油

出0入0汤圆

发表于 2017-3-27 17:56:32 | 显示全部楼层
TBG3 发表于 2017-3-27 11:22
第二条:
1. 可读性最重要,效率不那么重要,因为现在都是计算能力过剩。
2. 高可靠性场合,尽量少用指针。 ...

请问少用指针是要防止哪些问题?

出0入0汤圆

发表于 2017-3-27 18:27:10 | 显示全部楼层
这种情况最简单的不是采用ring buffer吗, 中断只往ring里面写, 普通程序从ring读出然后处理。如果是一读一写,ringbuff稍微处理一下连临界区都不需要。

出0入0汤圆

发表于 2017-3-28 08:54:45 | 显示全部楼层
myxiaonia 发表于 2017-3-27 17:56
请问少用指针是要防止哪些问题?

指针越界。数组还好处理,判断下标即可,如果是结构体,那就比较难办。

出0入0汤圆

发表于 2017-3-29 01:59:00 | 显示全部楼层
TBG3 发表于 2017-3-27 16:22
指针容易出问题

我感觉还好。现在已经不知不觉怎么都会用到指针。
唯一会出问题的时候经常是写完一部分的时候没验证,一次性全写了,有时会出现粗心的情况.....

出0入0汤圆

发表于 2017-3-29 06:48:12 | 显示全部楼层
TBG3 发表于 2017-3-27 16:22
指针容易出问题

只想回你,概念混淆!误导别人。
是你用指针的时候容易出错,不是指针本身的问题,更和你的应用场合无关。

出0入0汤圆

发表于 2017-3-29 10:22:46 | 显示全部楼层
zyw19987 发表于 2017-3-29 06:48
只想回你,概念混淆!误导别人。
是你用指针的时候容易出错,不是指针本身的问题,更和你的应用场合无关 ...

无知无畏。

指针是很方便,但是一旦出问题,就会导致系统崩溃。

跟应用场合无关? 在大多数时候,就是因为对应用场合的不了解,导致指针溢出的。 跟应用场合的关系大了。以丰田刹车为例,就是因为几个小的bug凑到一起,导致出现的大问题,这是在设计时想不到的。

所以微软专门出了一个新的C语言,叫做checked C, 这个check,指的就是边界检查。

出0入0汤圆

发表于 2017-3-29 11:14:58 | 显示全部楼层
顺带说一句:在不要求高可靠性的场合,可以用指针。因为即使是系统崩溃,也没有关系。普通用户的电脑或手机死机会导致很大问题吗? 不会。

出0入0汤圆

发表于 2017-3-29 13:03:11 | 显示全部楼层
TBG3 发表于 2017-3-29 10:22
无知无畏。

指针是很方便,但是一旦出问题,就会导致系统崩溃。

呵呵
字数补丁

出0入0汤圆

发表于 2017-3-29 13:14:44 | 显示全部楼层
TBG3 发表于 2017-3-29 10:22
无知无畏。

指针是很方便,但是一旦出问题,就会导致系统崩溃。

因噎废食。C语言的强大就是在它的指针使用,只要仔细使用,指针造成错误的可能性很小。还要求不高的场合才使用指针?在高要求的环境使用最多的实时操作系统vxworks还不是到处都是指针?C语言最容易出错的是越界的内存访问,这个确实是指针有可能会造成,但哪怕不用指针,还是有很多方法可以造成缓存区溢出,尤其是嵌入式的环境,参数传递不用指针造成栈溢出的危害远远大于使用指针,而且更难排除。

出0入0汤圆

发表于 2017-3-29 13:52:22 | 显示全部楼层
flamma 发表于 2017-3-29 13:14
因噎废食。C语言的强大就是在它的指针使用,只要仔细使用,指针造成错误的可能性很小。还要求不高的场合 ...

这个讨论是从我的答复开始的,我的答复是:

1. 程序可读性非常重要。这句话是鼓励使用结构,即指针。
2. 高可靠性场合慎用指针。

作为一个程序员或者工程师,要明白一件事情,就是凡事有一利必有一弊,而工程就是一个妥协的过程。

所以,作为一个好的程序员(我就不说合格的了),必须在一个场合评估到底用不用指针。一段程序,必须即可以用指针来完成功能,也可以不用指针来完成功能。然后评估二者的区别和后果。

其他的,就不多说了。中国作为制造大国,要升级到智造大国,还有很长的路要走。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 03:22

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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