3535|12

7815

帖子

56

TA的资源

裸片初长成(中级)

楼主
 

【手机DIY】辛昕4.开始写程序 [复制链接]

在我今晚开始写程序之前。
昨天晚上,我简单想了想整个程序的框架

如上一个帖子所说,由于我最近的工作,我在无意中,事实上已经 拥有了 多级菜单(的实现方案),拥有了队列,至于用于GPRS模块的串口收发,不管是我此前的 超时机制,还是熟悉了队列后我想到的一个实际上可能更好的 方案——实际上这就是大家经常说的 环形缓冲。

所以我很快的就简单设计了整体的程序框架和实现过程。

当然,当时我只用了半个小时,所以写的很粗糙,基本上没什么意义。
而后我开始从如何实现,集成 和 测试各个部分的时候,我突然想到了。

我最好还是首先实现 LCD12864,矩阵按键 的底层驱动,因为有了这个,我可以省去许多测试中层,上层的功能时需要的 桩。
而如果我没有实际实现这些 输入 / 输出 的基本部件,我要用软件桩模拟来测试的时候,所费的劲恐怕也不少。

考虑到这个东西本身就是一个不很复杂,规模不大的项目,所以,我决定,首先 实现(移植)这些底层驱动再说。

第一步我实现 12864,我此前已经做好了一个,并且发布在论坛里。
经过这次换用在 stm32f030上,这个过程非常简单,我真的就只是修改了 几个io绑定函数,这也算是对这个驱动的一个考验,对这个结果我比较满意。

因为我把源代码一个一个添加上去,然后编译,每一步,我都没有遇到编译错误,一步都不用修改。
而且,这个时候,我发现,实际上,即使我把所有源码编译成一个库,只把IO绑定函数 留给调用者 就可以了。

好,就这么干,这样可以省了许多事!

先上个图哈~~







最新回复

这两天比较忙,都没看论坛,楼主都回了这么多,真的非常感谢!版主如此尽心解答,精神值得学习!让我来好好研读以下楼主的文章。  详情 回复 发表于 2014-7-7 10:25
点赞 关注
个人签名

强者为尊,弱者,死无葬身之地

 

回复
举报

7815

帖子

56

TA的资源

裸片初长成(中级)

沙发
 
库已经编好了。
对于库,目前来说,我还有一个很大很大的问题没有彻底解决,那就是不知道如何应付一次编译,多次(不同编译器使用)。

所以,我只能提供一个我自己使用的iar的编译出来的库。

我的IAR 是 EWARM 7.1
按道理,除了 老版本 无法兼容 新版本,按道理IAR之间是可以互相兼容的。

在这里,我这样做的目的,意义还不算特别明确,我只是不想看到太多代码。
所以想了想,我就把我编译库的 project发上来吧。

没有太多的特殊设置,只是option里 c/c++ 那一项的output选择 library 而不是 executeable 就可以了。

LCD12864-lib.rar (171.14 KB, 下载次数: 6)
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

147

帖子

0

TA的资源

一粒金砂(高级)

板凳
 
想请教下楼主,大成库的IO管脚怎么设置?比如不同的芯片,他们调用管脚的方式不同。使用宏定义么?
 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

4
 
youyou_hu111 发表于 2014-7-5 08:14
想请教下楼主,大成库的IO管脚怎么设置?比如不同的芯片,他们调用管脚的方式不同。使用宏定义么?

我不用宏

因为我觉得这种方式很蹩脚,虽然我在有的地方,而且不少的地方看到类似的做法。
而且这会造成库写的很辛苦。

我的方法是通过 函数指针 实现。

具体思路是,把 封装底层操作,比如IO口高低操作 的 函数,在库里的时候,实际上并未实现,只通过函数指针来实现调用。
然后,在写应用程序时,再根据具体IO,单片机的情况,把这些IO操作写在函数里,然后把这个函数 初始化入 库里。

这样的话,你改变了引脚,改变了不同的芯片,写法完全不一样,都无所谓,你只需要改写应用层的这个 IO操作函数就可以了。
对于库的接口 是完全不影响的。

个人签名

强者为尊,弱者,死无葬身之地

 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

5
 
昨晚到今天,发现硬件一个地方做得不好。
我发现12864那个地方经常接触不良。
一开始,我想到莫非是因为我用的是普通的排针排母,不是镀金的,所以插拔多了,就接触不好?
话虽如此,可我一时半会要买东西却是实在不方便。

另一方面,以前我也这么用,也没见我出啥问题。
后来想了想,12864这个地方,因为我用的是 串行方式,实际上我只用了其中8个引脚,所以焊接时,我去头去尾,会不会是因为这样造成接触不良?
又或者,我需要找点铜柱子撑起来会好一些?

不管如何,看起来我今天回宿舍后必须重新焊接一番来试试了~~

真扫兴~~
个人签名

强者为尊,弱者,死无葬身之地

 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

6
 
youyou_hu111 发表于 2014-7-5 08:14
想请教下楼主,大成库的IO管脚怎么设置?比如不同的芯片,他们调用管脚的方式不同。使用宏定义么?

具体的例子,我以前写过的一个关于 程序库 的帖子 在这里,你可以参考一下。


https://bbs.eeworld.com.cn/thread-375424-1-1.html



个人签名

强者为尊,弱者,死无葬身之地

 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

7
 
晚上回来,把板子重新焊了焊,又正常了。
看来下次要好好考虑这些问题才行。

下面先贴上 显示整屏ascii 函数

  1. void WriteAsciiFullScreen(Op12864 *op,const U8 *string)
  2. {
  3.      U8 temp[5];
  4.      U8 len,Length;
  5.      U8 TotalLength;
  6.      U8 line;
  7.      
  8.      if(string == NULL)
  9.          return;
  10.      
  11.      TotalLength = strlen((char *)string);
  12.      
  13.      line = 0;
  14.      len = 0;
  15.      Length = 0;
  16.      
  17.      do
  18.      {   
  19.          if(checkAsciiCode(string[Length],temp) != -1)
  20.             WriteAscii(op,line,len,temp);
  21.          
  22.          len++;
  23.          Length++;

  24.          if(len >= 25)
  25.          {
  26.             line++;
  27.             len = 0;
  28.          }
  29.          
  30.          if(string[Length] == '\n')
  31.          {
  32.             line++;
  33.             len = 0;
  34.             Length++;
  35.          }         
  36.          
  37.          if(Length >= TotalLength)
  38.             break;
  39.          
  40.      }while(line < 8);
  41. }
复制代码
个人签名

强者为尊,弱者,死无葬身之地

 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

8
 
同时,每次编译时,整个stm32f0的 外设库,还要重新编译,实在太慢了,老办法,再一次编译成库。

这里同样贴上 iar for ARM 的7.1版本
我发现它有个好处。
ARM的stm32,有许多麻烦的头文件和系统文件,每次刚开始弄的时候,确实让人不胜其烦。
而编译这个库的时候我发现它们也要一并加进去否则是无法编译的。

这恰好有一个好处,这样一编译,以后就永久不用烦这些东西了。

stm32f030-lib.rar (3.67 MB, 下载次数: 0)
个人签名

强者为尊,弱者,死无葬身之地

 
 
 

回复

147

帖子

0

TA的资源

一粒金砂(高级)

9
 
这两天比较忙,都没看论坛,楼主都回了这么多,真的非常感谢!版主如此尽心解答,精神值得学习!让我来好好研读以下楼主的文章。
 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

10
 
这个矩阵键盘有点小纠结。
此前的问题主要在于 脑袋有点糊涂了,居然有一些条件写反了。
另外就是读键,没有完善考虑,测试的时候也不仔细想想 消抖 这些事情,白白浪费了一些时间。

另外就是对于 矩阵键盘 这种 IO口线不定的情况,我经常希望可以通过一定手段,让它的驱动部分可以独立出去,同时可以不受注册时实际数量的限制。

如果可以用malloc的情况下,我想怎么玩就可以怎么玩,包括最简单的 链表。

而实际上,对于不方便到处用malloc这个限制的情况下,最近我无意学会了一种稍加变形的方法来实现 不malloc的链表,它在很大程度上简化了我工作的一个任务,但这个地方,我发现考虑上一些矩阵键盘的其他东西,我发现这个方法在这里,几乎没有太大优势。

所以,我还是决定放弃了,犯不着用上那么复杂的手段。

另外就是,刚和kdy聊了几句,他跟我说到的东西,项目管理的内容,其实我不是不懂,只是我还是很容易陷在实现的细节,因为我对代码有洁癖,而且对实现的完美程度也有很疯魔的固执......

这经常导致我做事情实际上很慢,赶不上进度~~

今晚就不说了,很晚了,最近要好好休息,晚安~~~

不管怎么说,这个本来就不难的东西,很快我就能搞定,而且,其实最后我将让你看到,即使不用什么链表,只是在初始化时稍微有点点麻烦,我一样可以把这个部分像12864那样做成完全独立的库~~
个人签名

强者为尊,弱者,死无葬身之地

 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

11
 
矩阵键盘

矩阵键盘 确实 是很简单的东西,我的纠结......其实与它的关系已经不太大,虽然我偶尔老是因为忘了调用这个,调用那个,或者直接把 逻辑条件写反诸如此类......

不过最后,我发现,什么链表,什么malloc在这里都不重要。
反正按键,不管是查询键值 还是 映射键值,都可以按顺序,也就是说,数组在这里其实是很好的选择:相当简单又恰当。

而且,确实,一般情况下,至少在单片机上C,我还是没试过malloc会遇到什么问题。
百度搜索过一下,发现问题还挺麻烦,除了heap大小的设置,居然还有不少相关问题......

闲话少说,上这一部分的代码。

我最后的组织思路如下:

按键可以有很多种,矩阵形式,独立按键形式,甚至可能其他更加奇怪的方式——我以前遇到过另一种 矩阵的变形......
但是,凡此种种,区别仅在底层IO的组织和读键方式。

因为任何按键,最终都可以,或者说需要映射到一个 表上,这个表记录着 键码 和 键的状态。

但大多数情况下,我们可以靠 数组的下标 来 记录键码,因此实际上,只需记录键的状态。
另外,考虑到大多数时候我们,对键的处理方式有可能很不一样,比如消抖用计次,比如也许还要考虑连键等的识别。

所以,其实我们可以提供的最底层输出,其实就仅仅是 按键的实时状态映射到 那个表就可以了。

下一楼是源码。
个人签名

强者为尊,弱者,死无葬身之地

 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

12
 
类似于 12864 分 Driver 和 Api两层

按键也是

Api的输入是 按键的表。 即 这些键的状态值;
Api 用于对键的识别。
一般情况下,我们都是 单键, 偶尔还有 多键,长键,短键。
一些讲究体验的场合,还有 连键。

这些就是Api干的事情。
它不关心 按键硬件上的组织形式,只关心映射到的 按键实时值,对其处理得到的结果。

至于 MatrixKey,它是针对 矩阵按键 这种硬件组织形式的抽象。

  1. // MatrixKey.h
  2. #ifndef _MATRIX_KEY_
  3. #define _MATRIX_KEY_

  4. #include "typedef.h"
  5. #include "CommonMacro.h"

  6. typedef void (*fDrv)(U8 logic);
  7. typedef U8 (*fSam)(void);

  8. typedef struct
  9. {
  10.     fDrv *DriverList;
  11.     fSam *SamplerList;
  12.     U8 DrvCount;
  13.     U8 SamCount;
  14. }MatrixKeyDriver;

  15. typedef struct
  16. {
  17.     MatrixKeyDriver *KeyDriver;
  18.     U8 *PressCount;
  19. }Key;


  20. void getMatrixKey(Key *key);

  21. #endif

  22. // end of file ------------------

  23. // MatrixKey.c
  24. #include "MatrixKey.h"
  25. #include <stdlib.h>

  26. int isMatrixKeyDriverReg(MatrixKeyDriver key)
  27. {
  28.     U8 item;
  29.    
  30.     if(key.DriverList == NULL)
  31.         return False;
  32.     if(key.SamplerList == NULL)
  33.         return False;
  34.    
  35.     for(item = 0;item < key.DrvCount;item++)
  36.     {
  37.         if(key.DriverList[item] == NULL)
  38.             return False;
  39.     }

  40.     for(item = 0;item < key.SamCount;item++)
  41.     {
  42.         if(key.SamplerList[item] == NULL)
  43.             return False;
  44.     }  
  45.    
  46.     return True;
  47. }

  48. void freeAllDrivers(fDrv *driver,U8 count)
  49. {
  50.     U8 item;
  51.    
  52.     for(item = 0;item < count;item++)
  53.           (*driver[item])(HIGH);
  54. }


  55. void getMatrixKey(Key *key)
  56. {
  57.     int drv,sam;
  58.     int keymask = 0;
  59.    
  60.    
  61.     if(isMatrixKeyDriverReg(*(key->KeyDriver)) == False)
  62.         return;
  63.    
  64.     for(drv = 0;drv < key->KeyDriver->DrvCount;drv++)
  65.     {
  66.         freeAllDrivers(key->KeyDriver->DriverList,key->KeyDriver->DrvCount);
  67.         (*key->KeyDriver->DriverList[drv])(LOW);
  68.         
  69.         for(sam = 0;sam < key->KeyDriver->SamCount;sam++)
  70.         {

  71.             if( (*key->KeyDriver->SamplerList[sam])() == LOW)
  72.                 (key->PressCount[keymask])++;
  73.             else
  74.                 key->PressCount[keymask] = 0;
  75.             
  76.             keymask++;  
  77.         }
  78.     }
  79. }

  80. // end of file -------------------

复制代码


  1. // 当前的 KeyApi 还很简单,只是一个 单键识别

  2. #include "KeyApi.h"

  3. U8 SingleKeyPress(U8 *PressCounter,U8 Size)
  4. {
  5.     U8 i;
  6.     U8 key = 0xff;
  7.    
  8.     for(i = 0;i < Size;i++)
  9.     {
  10.         if(PressCounter[i] >= 30)
  11.             key = i;
  12.     }
  13.    
  14.     return key;
  15. }

  16. // 因为很简单,所以就不上头文件了。
复制代码


个人签名

强者为尊,弱者,死无葬身之地

 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

13
 
  1. // 这是 针对我stm32f030板子上的 硬件接法 // 的 驱动写法。
  2. /*
  3.          --
  4.       --  OK --      OK PB1
  5.          --        PB10

  6.     --   --   --   PB0
  7.     --   --   --   PA7
  8.     --   --   --   PC4
  9.     --   --   --   PC5
  10.    PB12  PB11 PB2

  11.          OK =  PB1 PA7  (0)
  12.        (8)
  13.    (9)     (10)
  14.        (11)

  15.      17     13     5
  16.      16     12     4
  17.      18     14     6
  18.      19     15     7
  19. */

  20. #include "DriverMatrixKey.h"

  21. #include "stm32f0xx_gpio.h"
  22. #include "stm32f0xx_rcc.h"

  23. #include <stdlib.h>

  24. void MatrixKey_IO_Initial(void)
  25. {
  26.     GPIO_InitTypeDef gpio;
  27.    
  28.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  29.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
  30.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
  31.    
  32.    
  33.     // PB1 PB2 PB10 PB11 PB12 ----------
  34.     gpio.GPIO_Pin   = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
  35.     gpio.GPIO_Mode  = GPIO_Mode_OUT;
  36.     gpio.GPIO_OType = GPIO_OType_PP;
  37.     gpio.GPIO_Speed = GPIO_Speed_50MHz;
  38.     gpio.GPIO_PuPd  = GPIO_PuPd_UP;
  39.     GPIO_Init(GPIOB,&gpio);
  40.    
  41.     // PA7 PB0 PC4 PC5 -----------------
  42.    
  43.     gpio.GPIO_Mode = GPIO_Mode_IN;
  44.     gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
  45.    
  46.     gpio.GPIO_Pin = GPIO_Pin_7;
  47.     GPIO_Init(GPIOA,&gpio);  
  48.    
  49.     gpio.GPIO_Pin = GPIO_Pin_0;
  50.     GPIO_Init(GPIOB,&gpio);
  51.    
  52.     gpio.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
  53.     GPIO_Init(GPIOC,&gpio);   
  54. }

  55. void drv1(U8 logic)
  56. {
  57.      if(logic == HIGH)
  58.         GPIOB->BSRR = GPIO_Pin_1;
  59.      else
  60.         GPIOB->BRR = GPIO_Pin_1;     
  61. }

  62. void drv2(U8 logic)
  63. {
  64.      if(logic == HIGH)
  65.         GPIOB->BSRR = GPIO_Pin_2;
  66.      else
  67.         GPIOB->BRR = GPIO_Pin_2;   
  68. }

  69. void drv3(U8 logic)
  70. {
  71.      if(logic == HIGH)
  72.         GPIOB->BSRR = GPIO_Pin_10;
  73.      else
  74.         GPIOB->BRR = GPIO_Pin_10;   
  75. }


  76. void drv4(U8 logic)
  77. {
  78.      if(logic == HIGH)
  79.         GPIOB->BSRR = GPIO_Pin_11;
  80.      else
  81.         GPIOB->BRR = GPIO_Pin_11;   
  82. }


  83. void drv5(U8 logic)
  84. {
  85.      if(logic == HIGH)
  86.         GPIOB->BSRR = GPIO_Pin_12;
  87.      else
  88.         GPIOB->BRR = GPIO_Pin_12;   
  89. }


  90. U8 sam1(void)
  91. {
  92.     if(GPIOA->IDR & GPIO_Pin_7)
  93.         return HIGH;
  94.     else
  95.         return LOW;
  96. }

  97. U8 sam2(void)
  98. {
  99.     if(GPIOB->IDR & GPIO_Pin_0)
  100.         return HIGH;
  101.     else
  102.         return LOW;
  103. }

  104. U8 sam3(void)
  105. {
  106.     if(GPIOC->IDR & GPIO_Pin_4)
  107.         return HIGH;
  108.     else
  109.         return LOW;
  110. }

  111. U8 sam4(void)
  112. {
  113.     if(GPIOC->IDR & GPIO_Pin_5)
  114.         return HIGH;
  115.     else
  116.         return LOW;
  117. }

  118. static fDrv Drv[5];
  119. static fSam Sam[4];

  120. void MatrixKey_DriverReg(MatrixKeyDriver *matrix)
  121. {
  122.     Drv[0] = drv1;
  123.     Drv[1] = drv2;
  124.     Drv[2] = drv3;
  125.     Drv[3] = drv4;
  126.     Drv[4] = drv5;
  127.    
  128.     Sam[0] = sam1;
  129.     Sam[1] = sam2;
  130.     Sam[2] = sam3;
  131.     Sam[3] = sam4;
  132.    
  133.     matrix->DriverList = Drv;
  134.     matrix->SamplerList = Sam;
  135.     matrix->DrvCount = 5;
  136.     matrix->SamCount = 4;
  137.    
  138.     MatrixKey_IO_Initial();   
  139. }



  140. // end of file -------------------

复制代码
个人签名

强者为尊,弱者,死无葬身之地

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表