搜索
bottom↓
回复: 82

从今天起全面放弃GCC AVR做IAR AVR菜鸟

[复制链接]

出0入0汤圆

发表于 2007-7-12 01:30:19 | 显示全部楼层 |阅读模式
现在也只敢用2004/2005的WINAVR,盼了一个又一个的新版本~~~



几乎都让人发晕~~~



即使最近的不错,可惜优化的代码显然不如2005以前的...



虽然至今没用C编一个程序,清一色的C++, 不过对GCC的C++确实感到满意.



这次准备将过去的程序全部移植为IAR AVR的C++.



不过它在不初始化类时不运行构造函数实在是倒塌~~~



还好,优点大于缺点,而且其他MCU/ARM支持的类型也很多,这样程序移植将更方便.

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

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2007-7-12 02:01:13 | 显示全部楼层
IAR的确做得全面,不过用51的基本上都是KEIL,不知道IAR-8051做得怎么样。

最近也准备全面转向IAR。

C++倒是很少用,总觉得它太占资源,太慢了。

出0入0汤圆

发表于 2007-7-12 02:17:14 | 显示全部楼层
IAR,贵...

出0入0汤圆

 楼主| 发表于 2007-7-12 03:01:20 | 显示全部楼层
哈哈~~~C++的代码不比C差~~~

差的只是启动部分...



倒塌了,做菜鸟的第一课就是"狗论"~~~



软狗仅在中断喂,看来是不行啊.死机不复位啊



int main(void)

{

    __disable_interrupt ();//关闭总中断

    System.Init ();//系统初始化

    Timer.Init ();//定时器初始化

    Uart.Init ();//串口初始化

    __watchdog_enable ();//内部硬件看门狗shineng使能并复位

    __enable_interrupt ();//开中断

    Wdt ^= 1;//外部硬件看门狗706复位

    while (1)

    {

        System.MainExecFlag = 1;//软件看门狗复位(主循环运行成功标志)

       __sleep ();//休眠

    }

}



#pragma vector=TIMER1_OVF_vect

extern "C" __interrupt void Timer1ISR(void)

{

    System.Timer1ExecFlag = 1;//设置定时器T1运行成功标志

}



#pragma vector=TIMER2_OVF_vect

extern "C" __interrupt void Timer2ISR(void)//RTC定时1S中断服务程序

{

    if (System.MainExecFlag  //主循环运行成功标志

     && System.Timer0ExecFlag//定时器T0运行成功标志

     && System.Timer1ExecFlag//定时器T1运行成功标志

       )

    {//1S内主循环和定时器都在正常工作才真的喂狗

        Wdt ^= 1;//外部硬件看门狗706复位

        __watchdog_reset ();//内部硬件看门狗复位

        //软件看门狗复位(清除标志)

        System.SystemFlag &= ~((1 << MainExecFlag)//清除主循环运行成功标志

                             | (1 << Timer0ExecFlag)//清除定时器T0运行成功标志

                             | (1 << Timer1ExecFlag));//清除定时器T1运行成功标志

    }

//    Uart.puts ("0123456789ABCDEF");

//    LED ^= 1;

//    System.Timer2ExecFlag = 1;

}

出0入0汤圆

 楼主| 发表于 2007-7-12 03:14:24 | 显示全部楼层
转向它的另一个原因是要用TI的ZigBee CC2430,它必须用IAR-8051,

因为TI免费提供了的协议包是用IAR-8051作的.



粗看它的软仿真肯定不如Keil,不过Keil估计不会再在51上下工夫了,



8.06估计到了终结版了~~~



用它实际上是看中了它的C++...

出0入0汤圆

发表于 2007-7-12 06:50:13 | 显示全部楼层
没看得出有啥必要用c++,代码量又不是很大(基本flash达到4K,有些达到14K)

出0入0汤圆

发表于 2007-7-12 08:29:54 | 显示全部楼层
C++大程序用用还好

出0入0汤圆

发表于 2007-7-12 08:56:50 | 显示全部楼层
就单片机那点程序,还用C++啊.....

出0入0汤圆

发表于 2007-7-12 09:17:23 | 显示全部楼层
当初 也 是  HOT POWER   游说  站长   用 GCC  的 。

出0入0汤圆

发表于 2007-7-12 09:58:54 | 显示全部楼层
个人觉得就51来讲用c++没必要。

出0入0汤圆

发表于 2007-7-12 10:08:36 | 显示全部楼层
IAR的确为很多单片机编写了编译系统。

不过不是每一个都是最好的。51的还是KELL好。PIC单片机用PICC和CCS好。

其实编译器是为单片机服务的,应该免费,收费也应该向单片机商收费。不过现在搞成了向使用单片机的人收费了,所以只好盗版了,哈哈。

出0入0汤圆

发表于 2007-7-12 10:15:37 | 显示全部楼层
楼上可能没用过IAR for 51吧. 可以负责任点告诉你,IAR比keil要好得多. 不信你下载个iar试试.

出0入0汤圆

发表于 2007-7-12 10:31:08 | 显示全部楼层
用过,不过个人感觉比KEIL差,毕竟是专门为51量身做的嘛。不过我想楼上的如此肯定,那就是我还没有用透彻吧了。

出0入0汤圆

发表于 2007-7-12 11:01:57 | 显示全部楼层
【4楼】



好象KEIL C51现在是V8.08

出0入0汤圆

发表于 2007-7-12 11:18:01 | 显示全部楼层
IAR主要缺陷是中间代码与OMF51不兼容,国内找不到支持这种格式的仿真器。

出0入0汤圆

发表于 2007-7-12 12:01:46 | 显示全部楼层
引领时尚了又~!

出0入0汤圆

 楼主| 发表于 2007-7-12 13:18:02 | 显示全部楼层
哈哈~~~当初忽悠阿莫到现在也没错~~~



不过现在玩腻了~~~想采点"野花"...

出0入0汤圆

发表于 2007-7-12 13:29:17 | 显示全部楼层
就像练毛笔字的人固然对毛笔很挑剔,但不是有好的笔就能写好字一样。追究外在的东西是因为不自信,软件编程说到底是靠思维的周密。中国的软件产业为什么不如国外,甚至不如印度,这也可见一斑。

出0入0汤圆

发表于 2007-7-12 16:58:14 | 显示全部楼层
Keil C对代码的优化很差,相同的子程序就是不去优化调用.也许我没有设置正确?

IAR就做得很好.

出0入0汤圆

发表于 2007-7-12 17:30:19 | 显示全部楼层
之所以这么肯定,因为以前就已经用IAR 开发51了.同样的C代码, IAR生成的code比keil小.也曾看生成的汇编代码,比较之后觉得iar比keil精. 不过keil的软件调试环境好, 所以在code没有太大压力下我还是用keil, flash空间不用白不用嘛.

出0入0汤圆

发表于 2007-7-12 17:49:43 | 显示全部楼层
那为何要全面放弃呢 ?

出0入0汤圆

发表于 2007-7-12 17:56:12 | 显示全部楼层
欢迎加入到IAR中来..........



以后交流IAR 的人又多了几个了...

出0入0汤圆

发表于 2007-7-12 18:20:07 | 显示全部楼层
IAR欢迎您!

出0入0汤圆

发表于 2007-7-12 19:06:57 | 显示全部楼层
各有各的优点,现在的AVR编译器没有完美的,对C的支持都多多少少有点问题,尤其是比较"邪门"的编程技巧,虽然好用但是并不是所有编译器都支持的,所以现在用什么编译器都无所谓了,好用便宜就行了,所以GCC还是不错的.至少不能给公司带来麻烦,树大招风啊,最近公司被AUTODESK钉上了,以前怎么没人找呢,看来公司大了后就麻烦事多了,这回可要破财了,所以大家用D版的还是小心的好了,不要正高兴呢对方的律师函就来了..........

出0入0汤圆

发表于 2007-7-12 20:15:07 | 显示全部楼层
改用angle吧.

出0入0汤圆

 楼主| 发表于 2007-7-12 20:17:02 | 显示全部楼层
关于C++/C代码效率之争,自己体验后自会有结果.

本人曾因为T26的容量不够而被迫将已经用了很久的C++程序改为C程序,

可结果比C++大了100个字节,无奈又改回了C++并全面优化后达到了预期的效果.



至于在MCU上C++是否有用,那只能找用过C++的人说话了~~~



因为我从未在AVR上编过一个正式的C程序.



这个只有用过C++的且不会再回到C编程思路的人才会体验到的...

出0入0汤圆

发表于 2007-7-13 11:33:16 | 显示全部楼层
不懂哦,只会用ICCAVR,至于代码效率也没感觉,至于空间选芯片的时候注意点,一般都会有余量,如果加功能也遇到写不下的时候,不过总能够压缩再压缩,上次mega16就编译到

99%,然后把一个用于除法的变量从long 变成int结果一下编译到93%,暂时还没有遇到写不下的,我想做单片机的没必要象做PC软件的人那么注重效率和空间,至少对于我们这些初级开发人员,应该把注意力放在基本功上面比如,硬件电路的设计(我说的是设计能力,不是copy 能力)和全面和精通并举的能力,精通一个方面然后又能从低层做到上位机,才是我们大部分的开发人员努力的方向,如果你软件超好,代码风格也超好,电路上面出了问题你查不出来,没有很强的分析能力,你的软件在哪里跑,你知道是软件还是硬件的问题吗?做这个行业,个人觉得还是重在硬件的设计,软件没有什么有难度的算法,说了这么多,我的看法就是,楼主很厉害,但我们还不到那个程度,盲目跟您学,只能让大家找不到重点,c++也好,c也好管它呢,至少在我这个阶段,我离"这个只有用过C++的且不会再回到C编程思路的人才会体验到的... "这个程度还差的太远,楼住是个高人,可惜不是我师傅,呵呵,一点小女人的浅薄的言论.论坛嘛,就随口说说了:)

出0入0汤圆

发表于 2007-7-13 11:49:29 | 显示全部楼层
楼上的是MM 啊?   好漂亮哦~!

出0入0汤圆

发表于 2007-7-14 15:13:05 | 显示全部楼层
c++只有一些复杂的特性才会导致代码加大效率降低(比如运行时编译),否则和c差不了多少。而且oop容易让逻辑更清晰。

不过菜农放弃gcc太可惜了。看看gcc的cpu支持列表,学好gcc,以后用新的mcu都不用为编译器发愁。

出0入0汤圆

发表于 2007-7-14 22:59:57 | 显示全部楼层
对象是要有额外的对象信息的.多态也需要这些信息.

如果不用对象,就是c了.

区别就在这里.所以C++不可能和c差不多,实际是差很多,只是编译器处理了很多

出0入0汤圆

发表于 2007-7-14 23:13:44 | 显示全部楼层
C++结构的确很好。

比起C来说,主要多了一些初始化工作。

对于普通CPP函数,和C函数差不多;对于虚函数就比较复杂了,多了很多工作。

出0入0汤圆

发表于 2007-7-14 23:54:11 | 显示全部楼层
gcc强大而优秀的内嵌汇编语法,放弃了岂不可惜。(没用过IAR,不知它的内嵌汇编是否比得上gcc)



而且,国外的很多AVR技术论坛和网站,特别是开源的,基本上都用gcc(比如avrfreaks,AVRUSB等),其它编译器反而较少(没具体统计过,说错了别扔砖头哈),放弃了岂不可惜。



hotpower三思。

出0入0汤圆

发表于 2007-7-15 09:10:27 | 显示全部楼层
问一个问题,单片机的C++可以用STL吗?可以用乏型吗?可以用纯虚基类吗?

出0入0汤圆

发表于 2007-7-15 14:45:21 | 显示全部楼层
用其他方法没有错,没有必要全面放弃某种方法。

出0入0汤圆

 楼主| 发表于 2007-7-15 15:06:33 | 显示全部楼层
用过一阵IAR后,新鲜感有点弱了~~~和GCC比确实有些问题.



可能是我当IAR菜鸟没当好的缘故吧.



像内部看门狗的函数也要自己编,它只带__watchdog_reset().



没__watchdog_enable()和__watchdog_disable(),那么__watchdog_reset()有什么用???



好象它的中断程序和gcc也有很大的差异.



问题众多,还要继续学习.



转向IAR的原因只是为了追求它传说中的优化效率,还有待于实验证明.



由于我需要做多种MCU的程序,而IAR可以说支持的很多,所以用它也不应该后悔~~~



不过全面放弃,现在看来还为时过早~~~

出0入0汤圆

发表于 2007-7-15 16:39:02 | 显示全部楼层
哈,总算没有少掉一个GCC的网友。因为我的C 很菜,只会摆弄GCC。

出0入0汤圆

发表于 2007-12-24 23:56:45 | 显示全部楼层
搞个单片机还用C++?
你这样不是脱裤子放屁多吃一举,
但单片机用到的程序是很简单的,全部都是根据外围的硬件来设计程序的,

用C++根本就没有意义,说白了 单片机就是控制IO,简单的处理数据,

更注重的是控制和操作外围元件和芯片的,要控制外围和芯片,首先你要了解元件,了解芯片和操作,基本上芯片,在资料上都做了多程序控制编写案例,你只要看懂了就可以了,完全可以根据资料上的控制思路来完成,单片机程序设计,

你这样其就是大才小用

跟叫一个本科生去扫大街的性质一样,

还有如果你只会C++,不会C语言,你这样肯定会很落后,或者学得很慢,
因为现在基本都是用C语言来编单片机程序,人家好的设计作品,你肯定看不懂,这样就看不懂人家设计的作品,学不到人家的设计思路,
即使你可以不去看人家的作品,而达到这个水平,我相信,这历程是很艰难的也是漫长,

出0入0汤圆

发表于 2007-12-25 01:23:49 | 显示全部楼层
【36楼】 mugangqin


实在看不下去了,不懂得时候不要乱说!!!可以保留意见,看看别人为什么使用。

非常讨厌这样的人在这里影响大家的正常讨论。

出0入0汤圆

发表于 2007-12-25 07:16:23 | 显示全部楼层
36楼太牛了

出0入0汤圆

发表于 2007-12-25 07:28:57 | 显示全部楼层
不知菜农还来不来这里了。很怀念啊

出0入0汤圆

发表于 2009-4-22 10:14:20 | 显示全部楼层
菜农的c++基本上属于耍花枪,用c++外壳包装了的c

出0入0汤圆

发表于 2009-4-22 10:26:51 | 显示全部楼层
其实用C++很好。

不过C++最大不方便在于C++语法不兼容C99语法。
只好弃用C++。

出0入0汤圆

发表于 2009-4-23 07:45:50 | 显示全部楼层
C++有什么?流操作?类? 友元?


对于单片机这样天天要想把让每CLK 用于操作一个IO的设计,搞些花花架子有什么意思.

其实用结构就能实现类操作的基本功能,用命名方式就能实现C++的基本语言形式.

有人认为升级了就是上高等级了.

洋鸡蛋升级了草鸡蛋.我就没觉得好吃

出0入0汤圆

发表于 2009-4-23 08:36:04 | 显示全部楼层
C++有什么?
C有什么,C++就有什么(C99新特性除外)。

楼上认为类的效率一定比结构体差?
楼上真的试过?
楼上拿出实例来。

出0入0汤圆

发表于 2009-4-23 08:37:06 | 显示全部楼层
老hot搞的基本上是花架子。

出0入0汤圆

发表于 2009-4-23 09:45:39 | 显示全部楼层
我也喜欢用C++,虽然我对C语言更熟悉.
主要原因是C语言变量必须在开头定义, C++则可以在用的时候定义.
同样, 不喜欢很多全局变量, 喜欢用C++封装起来.

说C++效率比C低是不准确的, 因为C++也可以用C的方式来用.
我比较倾向于把C++当作C来用, 再多个class. 对于C++的很多高级特性,
我一般是比较谨慎的. 比如: 模板等.

之前在DSP平台上是用的C++, 现在学一下AVR, 也想选C++.

ps:

Arduino控制板的库也都是C++写的, 但是还是C语言的风格.
用起来简单多了.

出0入0汤圆

发表于 2009-4-23 10:57:12 | 显示全部楼层
LS高手

出0入0汤圆

发表于 2009-4-23 11:15:05 | 显示全部楼层
不管是C 还是C++都是少用全局变量好.

曾经因为 RAM不够.做过 FOR 变量全局化.但也没省几个char .

说到C++的封装.除了多几个操作外.不见得比C强

个人觉得C模块化很好了了..

C++ 本来就是C 的增强版.其主要的变化就是类.而类与结构的重合点太多了.

为了实现图型操作系统N多时间片下N多的 属性.方法.消息.利用C++对结构的扩展:类 来独立封装类


C是实现代码的模块化.而C++实现的是黑盒化,

问题是:把单片机的代码黑盒化.除了增加调试的时间 和代码长度.还有多少实际意义?

出0入0汤圆

发表于 2009-4-23 14:48:48 | 显示全部楼层
楼上能不能举个例子?

出0入0汤圆

发表于 2009-4-23 15:47:01 | 显示全部楼层
偶做Windows NTDDK,连Windows的驱动都是C的,而不是C++
一个MCU而已,用C++??
有容器?泛型?抽象类之类的不?
没的话,何必呢~
连MS的驱动也是C而已

出0入0汤圆

发表于 2009-4-23 15:48:44 | 显示全部楼层
C++也是模块化.
C++的类与C的结构相差很大, 不是一般的差别.

另外, 我觉得代码长短和编译后的文件大小不是绝对的关系.
而且用C++, 代码结构更好, 总的代码量不会相差太大, 但是更容易维护.

至于黑盒化和模块化的区别不是很明白.

出0入0汤圆

发表于 2009-4-23 15:52:11 | 显示全部楼层
喜欢GCC

最近在做ATTINT13用在RFID项目 1K的FLASH

用GCC代码刚好够大

出0入0汤圆

发表于 2009-4-23 15:55:37 | 显示全部楼层
/****************************************************************************
O B J:主程初始化
Input: void
Out  :void
*****************************************************************************/
void MAIN_init(void)
{
        SET_IO_ALL;
        TIME1_init();
        UART_init();
        SPI_init();
        UART_put_char(SD_init());
        DISK_init();
        WORK_init();
        UART_put_str("system init OK!",15);
        sei();

}


/****************************************************************************
O B J:主程序
Input: void
Out  :void
*****************************************************************************/

int main(void)
{
        int i;

        MAIN_init();

        while (1)
        {

                if (UART_IN == 1)
                {

                        if (UART_RX == 'g')
                                WORK_go(0, 0, 8);
                        UART_IN = 0;
                }

        }

}



同样的东东.用C实现有什么不同?

突然发现 他的main() 在最上面..我不明白.他就不会出现函数未定义的 error?..难道为 main.c也做了个 .h?

还有 他不是用C++了??

为啥不用C++经典的">>" 

而用:uart.puts(XXX) ??

如上一位楼主所说 "花架子"

其实对于编程时间长了.用啥都行.但这样有误导初学者之嫌

我也是从C51转过来的.为了一个IDE 绕了几个月 什么UE editplus,VC 都用过.(VC 还吃了我一个1K字的C源代码).最后发现 还是PN最好...

出0入0汤圆

发表于 2009-4-23 16:12:22 | 显示全部楼层
个人认为:

所谓黑盒化.就是你调用一个程序时不用了解其内部实现的手段,这就叫"面向对象的编程语言" 比如你在VC 中写程序.你放了一个对话框.要知道实现放这个对话框的代码好长好长.但你没有必要了解.直接调用就得了,这个对话框对你来说就是一个黑盒.

基本上WIN中编程实现的全是黑盒化.除了驱动..而这个驱动...大多数都是用C实现的..

为什么呢?

C++为了强制封装一个模块,有时采用一些破坏模块的做法

比如:变量不在在程序首部定义,流操作的一部分之类的.

C++ 主要是用在WIN程序的编制中.

在MCU上不是说不好搞 ,但不能说在MCU上用C++就是等级进了一大步..

出0入0汤圆

发表于 2009-4-24 09:52:53 | 显示全部楼层
把C++当作C来用, 可以省去很多C的语法限制.
再说, 用C++也没有必要非得用"<<"; 用C++也没有强制封装一个模块.

摘一段arduino的例子(C++的):

/*
* Dimmer
* by David A. Mellis
*
* Demonstrates the sending data from the computer to the Arduino board,
* in this case to control the brightness of an LED.  The data is sent
* in individual bytes, each of which ranges from 0 to 255.  Arduino
* reads these bytes and uses them to set the brightness of the LED.
*
* http://www.arduino.cc/en/Tutorial/Dimmer
*/

int ledPin = 9;

void setup()
{
  // begin the serial communication
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  // check if data has been sent from the computer
  if (Serial.available()) {
    // read the most recent byte (which will be from 0 to 255)
    byte val = Serial.read();
    // set the brightness of the LED
    analogWrite(ledPin, val);
  }
}

很简单吧. C++能把一个模块封装的更简单, 这就是优势!

出0入0汤圆

发表于 2009-4-24 10:01:08 | 显示全部楼层
to nops

PN是什么东东?

出0入0汤圆

发表于 2009-4-24 10:27:10 | 显示全部楼层
C++最不好的地方时与C99标准不兼容。

C,C++不能并存,只好放弃C++。

出0入0汤圆

发表于 2009-4-24 10:49:56 | 显示全部楼层
用C的话一般还是用C89比较好. 如果从C99和C++选其一的话, 我肯定会选C++.
如果只用C的话建议用C89和C++的子集, 那移植的话就更没有障碍了.

出0入0汤圆

发表于 2009-4-24 23:09:06 | 显示全部楼层
C89不习惯。

比如循环:
for(unsigned char i=0;i<100;i++)
多好。

C89非得:
unsigned char i;
for(i=0;i<100;i++)

数组初始化:
unsigned char tab[]={[9]=100};
多好。

C89非得:
unsigned char tab[]={0,0,0,0,0,0,0,0,0,100};

出0入0汤圆

发表于 2009-4-24 23:52:47 | 显示全部楼层
说实话,

    unsigned char tab[]={[9]=100};

   这样的语句看着才非常的不舒服。



    总体感觉 GCC 还是不错的,用C时,都用它。

出0入0汤圆

发表于 2009-4-25 08:13:50 | 显示全部楼层
再说一遍..在函数内部定义变量是一个对模块化破坏很大的做法.首部定义变量是约定俗成的模块化做法

如果变量都能定义到内部.那直接把.c 改叫.h  头文件也省了吧

所谓省去C++的语法限制的实质是什么? 对C模块化变通?

那个程序简单? 你的类声明.初始化部分那去了?

C 可以不要..但C++不可以不要吧.



PN:和WINAVR 一起装的那个.如果装好了.和VC的IDE 差不了太多的(少多文件 tags 功能)


另外再说下. C 也可以用结构实现OPP的做法.

在C ++中.结构和类基本相同

在C 中.结构体内不能有函数.但可以有函数指针.

实现方式只是表达上有点不同而已.

C++:

Serial.begin(9600);

C:
(* Serial).begin(9600); 或: Serial-> begin(9600);

出0入0汤圆

发表于 2009-4-27 12:53:59 | 显示全部楼层
再说一遍..在函数内部定义变量是一个对模块化破坏很大的做法.首部定义变量是约定俗成的模块化做法

>> 无论C或C++, 一般都要避免在函数内部定义变量(应该是static变量).

如果变量都能定义到内部.那直接把.c 改叫.h  头文件也省了吧

>> 不明白.

所谓省去C++的语法限制的实质是什么? 对C模块化变通?

那个程序简单? 你的类声明.初始化部分那去了?

C 可以不要..但C++不可以不要吧.

>> 类的声明在头文件中. C语言可以不要头文件, 但是这种做法绝对是不提倡的.
>> 一般的建议是: 谁实现了*.c/*.cpp, 谁就应该提供一个对应的*.h文件.



PN:和WINAVR 一起装的那个.如果装好了.和VC的IDE 差不了太多的(少多文件 tags 功能)


另外再说下. C 也可以用结构实现OPP的做法.

>> 用汇编也能实现OOP, 但是很麻烦...

在C ++中.结构和类基本相同

在C 中.结构体内不能有函数.但可以有函数指针.

>> 但是函数指针占用了结构体的空间. 而且函数指针需要初始化.

实现方式只是表达上有点不同而已.

C++:

Serial.begin(9600);  

>> 这里的begin是对Serial对象进行操作. 数据是核心, 函数依附于数据存在.

C:
(* Serial).begin(9600); 或: Serial-> begin(9600);

>> 1. 这里的begin和 Serial有关系吗? 它只是一个函数, 甚至连Serial结构体
>>    都不能访问. 这里函数还是独立于数据之外.
>> 2. 这里的begin函数指针缺少初始化代码.
>>

出0入0汤圆

发表于 2009-4-28 09:00:56 | 显示全部楼层
两位高手

出0入0汤圆

发表于 2009-5-1 14:30:55 | 显示全部楼层
首先说明一下,本人没用过IAR,只是用过两年的keil做过几个c51的c程序开发(不会汇编)。另外,有一多半的时间在用vc++做上位机程序。对于在单片机中是否用c++的,我的观点是:用c++更强的语法检查功能来写c程序,换言之,用c++中c的子集。理由如下:
1、在keil中c的语法检查实在是很弱(不知道下面所举的例子在IAR中是否存在),体会颇深,比如:
一、对于static修饰的函数,竟然还可以在其他文件中调用,只是给出一个警告而已。在标准c语言中,static修饰的函数只能在本文件中调用,不可在其他文件中调用。
二、函数无需声明,只要在调用之前实现即可。这样其实破坏了模块化的思想,因为不声明函数那么在头文件中就没有了“接口”的概念,这样从头文件中就得不到什么有用的信息了。使用者如果从头文件得不到什么信息,那就只能从原文件中去寻找,这显然破坏了“封装”的概念。
2、c++的出现是因为c语言在做大项目(大于10万行)的时候会出现全局变量满天飞、模块化结构难于组织等难题。也就是说,当程序代码量较小(比如单片机,也就三五千行)的时候,c++的优势并不明显,甚至可能会更差。因为,c++相对于c的难度可不只2个加号那么简单,光是关键字就多出了不少,更别说构造函数、析构函数、拷贝构造函数、运算符重载、继承、多态等等概念。面向对象也不是万能的,并非所有的项目都合适,对于单片机系统我倒觉得“封装”更有用,更能体现模块化的思想。
3、无论c++还是c都只是解决问题的手段,用c并非一定得“纯”到不用一点点面向对象的思想。编程思想是相同的,不必拘泥于某一种思维,这样反而束缚了自己、禁锢了自己。

出0入0汤圆

发表于 2009-5-1 14:55:40 | 显示全部楼层
61楼 chai2010 的一些观点不敢苟同:
1、在C ++中.结构和类基本相同  

在C 中.结构体内不能有函数.但可以有函数指针.  

>> 但是函数指针占用了结构体的空间. 而且函数指针需要初始化.

mynameis:函数指针确实占用了结构体的空间,也需要初始化。但是c++中的对象调用成员函数并非就没有指针,只不过是编译器添加进去的,还记得this指针吗?所以,用c或用c++实现对象的调用几乎是一样的,没有哪个比哪个更节省空间。


2、C++:  
Serial.begin(9600);   

>> 这里的begin是对Serial对象进行操作. 数据是核心, 函数依附于数据存在.

C:  
(* Serial).begin(9600); 或: Serial-> begin(9600);  

>> 1. 这里的begin和 Serial有关系吗? 它只是一个函数, 甚至连Serial结构体
>>    都不能访问. 这里函数还是独立于数据之外.
>> 2. 这里的begin函数指针缺少初始化代码.

mynameis:若是非想用c来模拟c++的对象封装,那么上面的代码大概应该是这样的:
struct SERIAL
{
//结构体的数据变量
......

void (*Begin)(struct ERIAL* pThis, UINT nBaudRate);
};
SERIAL serial;
serial.Begin(&serial, 9600);

"甚至连Serial结构体都不能访问",这句论断不知道是什么意思。为什么不能访问呢?

出0入0汤圆

发表于 2009-5-1 15:00:37 | 显示全部楼层
【58楼】 void_c 上官先生,
“c89非得unsigned char tab[]={0,0,0,0,0,0,0,0,0,100};”并非“非得”这样初始化,其实c89也有比较简单的方法:
unsigned char tab[10] = {0};
tab[9] = 100;
也只需要两句就可以解决了

出0入0汤圆

发表于 2009-5-1 22:32:40 | 显示全部楼层
to: mynameis

比较认同你63楼的观点. 关于64楼的问题:


1、在C ++中.结构和类基本相同   

在C 中.结构体内不能有函数.但可以有函数指针.   

>> 但是函数指针占用了结构体的空间. 而且函数指针需要初始化.  

mynameis:函数指针确实占用了结构体的空间,也需要初始化。但是c++中的对象调用成员函数并非就没有指针

,只不过是编译器添加进去的,还记得this指针吗?所以,用c或用c++实现对象的调用几乎是一样的,没有哪

个比哪个更节省空间。

chai2010: C语言是结构体中函数指针占用空间; C++中class函数本身并没有占用空间, 只是在
使用函数的时候多传递了一个this指针而已, 如果不需要可以将函数定义为static(和C函数一样).


2、C++:   
Serial.begin(9600);   

>> 这里的begin是对Serial对象进行操作. 数据是核心, 函数依附于数据存在.  

C:   
(* Serial).begin(9600); 或: Serial-> begin(9600);   

>> 1. 这里的begin和 Serial有关系吗? 它只是一个函数, 甚至连Serial结构体  
>>    都不能访问. 这里函数还是独立于数据之外.  
>> 2. 这里的begin函数指针缺少初始化代码.  

mynameis:若是非想用c来模拟c++的对象封装,那么上面的代码大概应该是这样的:
struct SERIAL
{
//结构体的数据变量
......

void (*Begin)(struct ERIAL* pThis, UINT nBaudRate);
};
SERIAL serial;
serial.Begin(&serial, 9600);

"甚至连Serial结构体都不能访问",这句论断不知道是什么意思。为什么不能访问呢?

chai2010:

我说"甚至连Serial结构体都不能访问", 是针对60楼nops 的Serial->begin(9600); 代码.

因为这里的begin是Serial结构体中的函数指针, 但是begin指向的函数本身并不知道自己
被Serial结构体中的begin函数指针保存了, 那函数怎么访问Serial呢??

就好比, Serial认识begin, 但是begin并不知道自己被Serial认识. 指针同样是不能逆向
跟踪的!

如果确实想用C来模拟C++的封装, 那也不需要保存函数指针(因为函数都是固定地址的):

struct SERIAL
{
//结构体的数据变量
......

// 去掉Begin
// void (*Begin)(struct ERIAL* pThis, UINT nBaudRate);
};
SERIAL serial;

// 在外面定义begin

void SERIAL_begin(struct ERIAL* pThis, UINT nBaudRate)
{
   ...
}

// 使用

SERIAL serial;
SERIAL_begin(&serial, 9600);

但是, 这样的封装代码有必要吗? 本来是为了将问题简化, 现在却搞的更复杂了.

出0入0汤圆

发表于 2009-5-2 00:37:26 | 显示全部楼层
回【66楼】 chai2010:
其实
struct SERIAL
{
//结构体的数据变量
......

void (*Begin)(struct ERIAL* pThis, UINT nBaudRate);
};
中的函数指针纯粹是为了模拟"对象.成员函数或对象->成员函数"这种形式的调用方式,显得更面向对象一些而已。


用c来完全模拟c++在实际中没有必要,显然是把问题搞复杂了。不过有一个顺便的好处,那就是对c++封装的理解更清晰了,如果再加上虚函数的话,那用c来模拟c++的多态就更有意思了^_^。


另:强烈推荐《深度探索c++对象模型》这本书,书中对于c++对象,尤其是对于编译器处理各种对象的“暗中动作”都作了详细的讲解,颇有深度的一本书。

出0入0汤圆

发表于 2009-5-2 09:28:23 | 显示全部楼层
说实话,

    unsigned char tab[]={[9]=100};  

   这样的语句看着才非常的不舒服。



    总体感觉 GCC 还是不错的,用C时,都用它。

出0入0汤圆

发表于 2009-5-2 09:40:31 | 显示全部楼层
to mynameis:

struct SERIAL  
{  
//结构体的数据变量  
......  

void (*Begin)(struct ERIAL* pThis, UINT nBaudRate);  
};
  
中的函数指针纯粹是为了模拟"对象.成员函数或对象->成员函数"这种形式的调用方式,显得更面向对象一些而

已。


用c来完全模拟c++在实际中没有必要,显然是把问题搞复杂了。不过有一个顺便的好处,那就是对c++封装的

理解更清晰了,如果再加上虚函数的话,那用c来模拟c++的多态就更有意思了^_^。

chai2010:

这里的函数指针和C++的虚函数的内部实现是一致的. 因此, 用函数指针模拟多态是很容易的,
而且语法和C++很相似. 不过在嵌入式环境中, C++的虚函数用得不多(但是Arduino中用了一些,
如基类Print中write为虚函数).

关于C语言模拟C++中class特性的应用有不少, 成员函数/从基类继承/异常, 都可以实现,
但是这些技巧本身比class难多了(这里就不展开了).


另:强烈推荐《深度探索c++对象模型》这本书,书中对于c++对象,尤其是对于编译器处理各种对象的“暗中

动作”都作了详细的讲解,颇有深度的一本书。

chai2010:

现在已经基本没有看编程语言和基础算法方面的书的兴趣了 :)

出0入0汤圆

发表于 2009-5-2 15:31:57 | 显示全部楼层
unsigned char tab[]={[9]=100};   

   这样的语句看着才非常的不舒服。   

   unsigned char tab[10] = {0};
   tab[9] = 100;
   也只需要两句就可以解决了

-------------------------------------------

不得不承认,C99新特性确实比原先的定义方法方便。

如果数组元素较多的稀松数组,C99显然方便多了。

后面的方法显然有局限性,如果是定义常量数组就不行了。

出0入0汤圆

发表于 2009-5-2 21:34:31 | 显示全部楼层
回楼上:

现在似乎只有gcc和衍生系列在支持c99,都十年了不知道为什么支持c99的编译器如此之少啊!反观c++,新的标准也马上出台了,什么模板元编程、函数式编程等新潮的编程范式也一个个被加了进来,让人目不暇接。学c++真是有些累啊,很是怀念c的单纯与直接。现在突然觉得单片机程序是那么小巧玲珑,所有的行为都在自己的掌控之内,有一种成竹在胸的感觉。

另:最近在调试一个云台解码器的小程序,串口中断中接收到的数据时不时会出现问题。听说仿真器是个不错的东西,从来没用过,不知道老板忍心不忍心“斥巨资”买一个

出0入0汤圆

发表于 2009-5-2 22:22:42 | 显示全部楼层
C语言编译器(PC平台)主要有VC,BCB,TC,和GCC。
其中VC和BCB主要是C++,C只能算C++附属品,由于C99语法与C++并不兼容,可能会抵制C99新特性的引入。
(VC和BCB是否支持C99不清楚)
TC应该是很老的编译器,不支持C99理所当然。
GCC是支持C99的,GCC一般非常符合标准。(GCC是否支持所有C99特性不清楚)

反而嵌入式方面,比较有名的编译器如GCC,KEIL MDK,IAR都是支持C99的(或者支持C99部分特性)(是否支持所有C99特性不清楚)

出0入0汤圆

发表于 2009-5-3 00:11:10 | 显示全部楼层
keil支持c99? keil可是标准的c89

现在唯一希望的就是keil提供更强的类似于c++的语法检查功能(不仅仅是warning一下,往往甚至连warning都没有)

出0入0汤圆

发表于 2009-5-3 07:20:01 | 显示全部楼层

(原文件名:Image0032.JPG)

出0入0汤圆

发表于 2011-5-5 15:42:03 | 显示全部楼层
无论是免费的gcc还是收费的iar,各有各的受众人群,不必争论孰好孰坏。存在即合理是个永恒不变的真理。c和c++就像一对兄弟。也无孰好孰坏之分。正如linux源码使用c写一样。水平高的人也能写出优美的模块化的代码。水平低的人即使用c++也扯蛋。

出0入0汤圆

发表于 2011-11-19 19:03:21 | 显示全部楼层
旁听!没有最好的,只有最合适的。

出0入0汤圆

发表于 2014-12-1 01:14:47 | 显示全部楼层
So, as long as it works, IAR or GCC, they both are good.

出0入0汤圆

发表于 2014-12-3 10:02:39 | 显示全部楼层
IAR的优化级别貌似不要设置太高

出0入0汤圆

发表于 2014-12-4 05:24:49 | 显示全部楼层
>IAR的优化级别貌似不要设置太高
So far, it works. Almost all RAM are used by IAR.

出0入0汤圆

发表于 2014-12-5 11:23:45 | 显示全部楼层
NB 先MARK,有空再研究

出0入0汤圆

发表于 2014-12-7 09:42:36 | 显示全部楼层
我是菜鸟中的菜鸟,不懂这些。
搬个板凳坐在一边看,(*^__^*) 嘻嘻……

出0入0汤圆

发表于 2014-12-12 05:37:49 | 显示全部楼层
The latest GCC AVR release (2010-01-20) are matured, it easily beat IAR AVR (6.40.3) and ICC AVR "V7.22, V8.14.01" on a project for Attiny26 :

The following is the correct link to get the latest GCC release (2010-01-20):
http://sourceforge.net/projects/winavr/files/?source=navbar
AVR GNU Compiler Collection (GCC) 4.3.3
AVR GNU Binutils 2.19
avr-libc 1.6.7cvs
AVRDUDE 5.8cvs
AVR GNU Debugger (GDB) / Insight 6.8
AVaRICE 2.9
SimulAVR 0.9cvs

AVR32 GNU Binutils 2.19
AVR32 GNU Compiler Collection (GCC) 4.3.2
Newlib (for AVR32) 1.16.0
AVR32 GNU Debugger (GDB) / Insight 6.7.1
Splint 3.1.2
SRecord 1.47
Programmers Notepad 2.0.8.718
LibUSB 0.1.12.1 and device drivers
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-8-26 05:14

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

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