查看: 6078|回复: 19

[CodeWarrior] CW使用中的一些小总结

[复制链接]
  • TA的每日心情

    2018-3-21 13:20
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    16

    主题

    124

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    249
    最后登录
    2023-10-24
    发表于 2015-3-20 16:35:14 | 显示全部楼层 |阅读模式
    本帖最后由 zico1998 于 2015-4-1 20:34 编辑

    不对的请指正。
    小目录
    (1)分割上下文
    (2)CW里使用结构体
    (3)找中断
    (4)传参小测试
    (5)第一个串口程序
    (6)利用条件编译在同一工程下不同的测试
    (7)关于MKL25z4.H
    (8)WORD边栏分层
    (9)查看内存
    (10)联合体的应用(一)不同数据类型转换
    (11)按照状态来分析按键程序
    (12)FLASH操作要关中断
    (13)联合体的应用(二)制作位段/域
    (14)CW里结构体成员函数的使用



    (1)分割上下文
    提示框为我们带来不少的便利。如图001。
    但是你在标注时候,可能会出现大片非本函数或本变量的提示,这是因为与上面的连在一起了。比如:

    //注释1
    //AAA
    //BBB
    //CCC
    //注释2
    void xxx(void)
    ...

    这时候,你可以采用宏定义,将上下文分割,这样以后提示xxx时,就不会出现大量无关信息了。
    //注释1
    //AAA
    //BBB
    //CCC
    #define M_XXXXXXXXXXXXX0   0   //分割上下文
    //注释2
    void xxx(void)
    ...


    我知道答案 目前已有19人回答

    001

    001
    我今天最想说
    回复

    使用道具 举报

  • TA的每日心情

    2018-3-21 13:20
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    16

    主题

    124

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    249
    最后登录
    2023-10-24
     楼主| 发表于 2015-3-20 16:44:18 | 显示全部楼层
    (2)CW里使用结构体
    KEIL MDK5里,能够弹出函数名、变量搜索,但是我用的CW10.5里似乎没有,如果有,请教教我怎么弄。
    不过我发现CW下使用结构体、联合体,你输入完变量名后,“.”或“->”时,会弹出体内包含的元素来。

    所以可以考虑尽量用结构体。比如把某个模块的相关事件、变量集合到一处。
    typedef struct _stulcd
    {
         uint8 status; //状态量
        uint8 flag;   //标志
        uint8 step; //步骤量
        uint32 count; //计数量
        ....   
    }stulcd;

    stulcd m_stulcd1;
    002.JPG
    我今天最想说
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2018-3-21 13:20
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    16

    主题

    124

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    249
    最后登录
    2023-10-24
     楼主| 发表于 2015-3-20 16:58:10 | 显示全部楼层
    (3)找中断
    这里提供 一种写中断的方式:

    如项目名称为test001,则中断所在文件的路径为:
    test001/Project_Settings/Startup_Code/kinetis_sysinit.c

    在这里,第一步,将
    void UART0_IRQHandler() __attribute__ ((weak, alias("Default_Handler")));
    修改为你要的中断名,如:
    void UART0_IRQHandler() __attribute__ ((weak, alias("UART0_ISR")));

    第二步,在源文件前面,写代码如下:
    void UART0_ISR(void)
    {
    ...中断程序
    }

    也可以你把中断程序写在别的文件里,用h声明引用过来。
    如:
    /****myuart.c****/
    void uart0_isr(void)
    {
    ...
    }

    /****myuart.h****/
    void uart0_isr(void);

    /****kinetis_sysinit.c****/
    #include"myuart.h"
    void UART0_ISR(void)
    {
        uart0_isr();
    }


    我今天最想说
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2018-3-21 13:20
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    16

    主题

    124

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    249
    最后登录
    2023-10-24
     楼主| 发表于 2015-3-20 17:15:43 | 显示全部楼层
    (4)传参小测试
    个人认为,比较理想的函数的一种格式是
    uint8  m_xxxx(uint32 *t_data)
    {
        statci uint32 t_step; //步骤
        uint8 t_state;    //状态
        if(0==t_step)
        {...}
        else if(1==t_step)
        {...}
        ...
        return t_state;
    }

    返回值代表该函数运行到什么状态了,比如0完成、1未完成、2模块应答失败、3...
    而入参做传参,使用时候前面引用符即可。如:
    uint32  m_aaa=0x12;
    m_xxx(&m_aaa);

    如果是容量小的单片机,使用指针传参是很耗空间时间的,但对于KL25来说,多数应用里是可以忍受的。

    例如下面的代码:
    //传参测试
    //例:uint32 zzz=0; m_demo2(&zzz);
    uchar m_demo2(uint32 *pt)
    {
        (*pt)++;
        if(100<=*pt)
        {
            (*pt)=0;     
        }
        return 1; //函数返回值0或1,用来表示函数是否完成,或者返回状态值   
    }
    //传参测试
    //例:uint32 zzz=0; m_demo3(&zzz);
    uchar m_demo3(uint32 *pt)
    {
    m_demo2(pt);
    m_demo2(pt);  //加2
        return(1);   
    }

    我今天最想说
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2018-3-21 13:20
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    16

    主题

    124

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    249
    最后登录
    2023-10-24
     楼主| 发表于 2015-3-20 17:24:38 | 显示全部楼层
    本帖最后由 zico1998 于 2015-3-20 17:25 编辑

    (5)第一个串口程序
    书本、网络上有很多了。不过建议第一个程序,主程序什么都不做,就是发0x55或0xAA,然后利用示波器,测试波形,计算是否准确。
        while(1)
        {
            if(UART_S1_TC_MASK==(UART1_S1 & UART_S1_TC_MASK))
            {
                UART1_D=0x55;   
            }
            //可加或不加指示灯
        }

    其实,其他模块第一步测试,也可以这样,比如   
            while(!(SPI0_S & SPI_S_SPTEF_MASK))  //等待发送缓冲区空闲
            {
                t_i++;
                if(4000<=t_i)
                {
                    return; //超时退出           
                }        
            }
            SPI0_D=0x11;    //测试不同数值

    我今天最想说
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2018-3-21 13:20
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    16

    主题

    124

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    249
    最后登录
    2023-10-24
     楼主| 发表于 2015-3-20 17:35:28 | 显示全部楼层
    (6)关于测试
    一个项目里,涉及不少的测试,正式程序里,这些事用不到的。如果建立若干工程去测试,比较麻烦。我采用了条件编译的方式,在一个工程里解决测试、正式。同时,条件编译时,未编译的部分会阴影覆盖。用户一目了然。

    比如:
    /****main.c****/
    ...
    int main(void)
    {
    #if(0==M_DEBUG)   
    //正式程序
        main_post();  //开机自检
        main_init();  //初始化  
        while(1)
        {
            main_wait();   //待机阶段
            main_start();  //启动阶段
            main_run();    //运行阶段
            main_over();   //结束阶段
            main_test();   //扫描和检测阶段
            main_error();  //报错      
        }
    //    return 0;  //在结尾   
    #elif(1==M_DEBUG) //测试10秒定时翻转
        m_demo();    //语法测试
        m_test01();     
    #elif(2==M_DEBUG) //直接翻转,6.34us一次,一个脉冲12.68us,78.86KHz
        m_test02();   
    #elif(3==M_DEBUG)  //轮询计数400步大约1ms后翻转,1.89ms一次,一个脉冲3.780ms,264.5Hz
        m_test03();   
    #elif(4==M_DEBUG) //UART0、1、2不停的发送0x55
        m_test04();
    #elif(5==M_DEBUG)  //测试UART1的迪文屏幕
        m_test05();
    #elif(6==M_DEBUG) //测试UART1的迪文屏幕,显示连续数字
        m_test06();
    #elif(7==M_DEBUG) //测试SPI0
        m_test07();
    #elif(8==M_DEBUG) //测试ADS1282的复位、/DRDY
        m_test08();
    #elif(9==M_DEBUG)  //测试ADS1282发送读连续指令  
        m_test09();   
    #elif(10==M_DEBUG)  //测试UART1的迪文屏幕
        m_test10();   
    #elif(11==M_DEBUG) //FLASH测试
        m_test11();   
    #elif(12==M_DEBUG)
        m_test12();
    #elif(13==M_DEBUG)
        m_test13();   
    #else
            
    #endif
        return 0;     
    }

    /****main.h****/
    #define M_DEBUG 11  //调试项目
    //0.正式程序
    //1.PTI定时中断10秒翻转
    //2.74HC541端口不断翻转
    //3.74HC54端口按照轮询方式,400步大约1ms翻转一次,实际250步1ms
    //4.UART0、1、2不停的发送0x55
    //5.测试UART1的迪文屏幕
    //6.测试UART1的迪文屏幕,显示连续数字
    //7.测试SPI0
    //8.测试ADS1282的复位、/DRDY
    //9.测试ADS1282发送读连续指令
    //10.测试UART1的迪文屏幕
    //11.测试UART1接收、UART0的接收和FLASH测试

    我今天最想说
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2018-3-21 13:20
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    16

    主题

    124

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    249
    最后登录
    2023-10-24
     楼主| 发表于 2015-3-20 18:00:43 | 显示全部楼层
    (7)关于MKL25z4.H

    通过这个头文件,了解KL25内部的资源。
    其中,_REG是对寄存器。
    _MASK、_SHIFT是对位,可以进行XXX & yyy_MASK  或XXX | (1<<_SHIFT)操作
    (x),是多位的操作,你可以考虑其对应值。


    分析完这些后,可以直接自己对寄存器各位操作,而不用别人的库函数了。
    比如:
    PORTC_PCR4 |= (PORT_PCR_MUX(1) | PORT_PCR_SRE_MASK);
    我今天最想说
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2018-3-21 13:20
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    16

    主题

    124

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    249
    最后登录
    2023-10-24
     楼主| 发表于 2015-3-26 09:59:47 | 显示全部楼层
    本帖最后由 zico1998 于 2015-3-26 10:11 编辑

    (8)WORD边栏分层
    在侧边栏,点哪条目录,对应正文就跳到哪里。这个功能让DOC文档文件更容易查找。
    其实这个制作很简单:
    视图文档结构图
    在正文处,右键/格式段落大纲级别
    (嗯,不忙了,再介绍下CHM电子书的使用,很棒的软件)
    222.JPG
    我今天最想说
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2018-3-21 13:20
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    16

    主题

    124

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    249
    最后登录
    2023-10-24
     楼主| 发表于 2015-3-26 10:10:13 | 显示全部楼层
    (9)查看内存
    比如我FLASH写入第11扇区内容,字符串123,那么怎么知道写进去没有呢?
    硬件仿真,然后如图,点那个绿色+号,输入你的扇区地址。
    比如我KL25Z4的128的,大小0-0x0001FFFF(131071),分128个扇区,一个扇区就是131072/128=1024。注意,前5扇区存程序的,不能用。
    我第11扇区就是0x2c00(11264)首地址的。
    222.JPG
    我今天最想说
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2018-3-21 13:20
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    16

    主题

    124

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    249
    最后登录
    2023-10-24
     楼主| 发表于 2015-3-26 10:18:47 | 显示全部楼层
    (10)联合体的应用
    联合体在数据类型变换时很有用。比如uint32变成uint8、uchar的,或者反之。
    而且,CW平台对联合体、结构体提示显示很好(KEIL MDK5就不能),何乐而不为?

    在.h头文件里
    typedef union _undemo0
    {
    uint32 un32;
    uint16 un16[2];
        uint8 un8[4];
    }undemo0;
    extern undemo0 m_undemo0;

    在.c文件里
    undemo0 m_undemo0;

    m_undemo0.un32=0x876544321;   

    观察un16、un8的变化,当.un32=0x87654321,则.un16[0]=0x4321,un16[1]=0x8765,则.un8[0]=0x21,un8[1]=0x43,un8[2]=0x65,un8[3]=0x87
    我今天最想说
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2018-3-21 13:20
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    16

    主题

    124

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    249
    最后登录
    2023-10-24
     楼主| 发表于 2015-3-26 10:41:15 | 显示全部楼层
    (11)按照状态来分析按键程序
       按下按键,可以分四个步骤:之前没按且现在没按,之前没按且现在按下,之前按下且现在也按下,之前按下且现在松开。然后按照不同阶段,分配不同任务。
       这就是单片机里一个很重要的思想:过程与步骤量。几乎所有的单片机项目都可以按照这个思路去编程。

       static key.scan t_key;   //定义一个静态的结构体对象,含flag、port。。。也可以直接定义这两变量
        t_key.port=... //读端口状态
        if(t_key.flag==0 && t_key.port==0)  //之前没按下,现在也没按下
        {
            _nop_();
        }
        else if(t_key.flag==0 && t_key.port==1) //之前没按下,现在按下
        {
            t_key.flag=1;
        }   
        else if(t_key.flag==1 && t_key.port==1) //之前按下,现在也按下
        {
            _nop_();
        }
        else if(t_key.flag==1 && t_key.port==0)  //之前按下,现在没按下
        {
            t_key.flag=0;
        }   
    我今天最想说
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-9-17 17:18
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    26

    主题

    394

    帖子

    0

    高级会员

    Rank: 4

    积分
    970
    最后登录
    2019-10-9
    发表于 2015-3-30 15:32:27 | 显示全部楼层
    很不错,占一个
    回复 支持 1 反对 0

    使用道具 举报

  • TA的每日心情
    开心
    2017-1-24 09:50
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    654

    主题

    3262

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    13275
    最后登录
    2019-1-27
    发表于 2015-3-30 15:02:19 | 显示全部楼层
    发现楼主又更新了
    回复 支持 1 反对 0

    使用道具 举报

    该用户从未签到

    145

    主题

    4926

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    9267
    最后登录
    1970-1-1
    发表于 2015-3-23 09:23:59 | 显示全部楼层
    非常感谢你关于IDE的经验分享!
    回复 支持 1 反对 0

    使用道具 举报

  • TA的每日心情
    难过
    2021-12-15 16:01
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    305

    主题

    4701

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    377
    最后登录
    2023-8-16
    发表于 2015-3-20 16:40:00 | 显示全部楼层
    谢谢楼主分享经验。
    该会员没有填写今日想说内容.
    回复 支持 1 反对 0

    使用道具 举报

  • TA的每日心情
    开心
    2017-1-24 09:50
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    654

    主题

    3262

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    13275
    最后登录
    2019-1-27
    发表于 2015-3-25 13:18:15 | 显示全部楼层
    很不错啊
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-9-12 12:38 , Processed in 0.143988 second(s), 39 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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