在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
芯片精品文章合集(500篇!)    创芯人才网--重磅上线啦!
查看: 11380|回复: 42

[原创] 资深工程师单片机实战项目精讲(连载),由易到难连续分享

[复制链接]
发表于 2014-6-14 13:52:59 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

x
本帖最后由 吴鉴鹰 于 2014-6-14 14:06 编辑

   资深工程师单片机实战项目精讲(连载),由易到难连续分享

俄罗斯方块.gif


Hi!大家好,我叫吴鉴鹰,100%中国制造,长181cm,净重70kg。采用人工智能,各部分零件齐全,软硬件运转稳定,经二十多年的运行,属质量信得过产品。是一名从业10多年的单片机工程师,长年从事单机、dspFPGA、PLC以及触摸屏的项目开发,自信比牛顿更懂单片机、比诸葛亮更会玩DSP、比汉武大帝懂得什么是指针,这年头就得玩一个综合实力。


闻得EETOP论坛上有一批志同道合之士,愿意一道交流技术,于是花以时日浏览之,果然不乏卧虎藏龙之辈,鉴鹰深感钦佩,感谢这些前辈同行能够分享自己的项目经验和学习心得。也通过这些有技术含量的帖子博客获益不少。


face8.gif


回想当年鉴鹰刚刚大学本科毕业不久,进入一家大型国企,保守传统思想——“教会徒弟,饿死师傅”这种陋习的影响,只能靠自己死磕书本,硬啃项目慢慢才取得一点进步。所以后来干脆辞职再次回到电子科技大学读了三年研究生!为了让现在毕业的毕业的年轻人不要重蹈鉴鹰当年的覆辙,我也愿意将自己多年积累的一点经验分享给大家,想让更多的年轻人看到,获得一点点帮助就足矣!


091741qiuu8qbquuj7aq6p.gif


鉴鹰将会逐步分享自己的一点项目经验和学习心得,由于水平能力有限,纰漏之处,还望各位同行指出。


每一个项目会提供原理图、源程序还有仿真图。


现在来开始详细解析如何完成各种项目的具体的方法和软硬件,提供详细的硬件原理图和软件程序,欢迎大家来畅所欲言!


温馨提示:点击相关标题下面的链接即可到相关的项目

 楼主| 发表于 2014-6-14 14:07:53 | 显示全部楼层
本帖最后由 吴鉴鹰 于 2014-6-18 14:17 编辑

                         1、吴鉴鹰单片机实战项目精讲(连载)之基于单片机的数字电子钟设计


相关原理图请点击下载:
吴鉴鹰单片机项目详细解析系列之基于单片机的数字时钟设计原理图.pdf (173.91 KB, 下载次数: 57 )

现在来第一讲,详细解析如何制作基于单片机的数字时钟,提供详细的硬件原理图和软件程序。
      开关K1K1 = 0时,时钟正常运行,此时不允许调整时钟。数码管的高两位显示小时,后两位显示分钟,led每闪一次表示时钟运行一次,在调整的过程中,led是停止发亮的。
一、 按键、开关功能说明:
      *  按键RESET:按下能复位程序。
      *  按键PULSE:提供单脉冲,从而实现单片机对外部脉冲的计数,利用单脉冲实现相应的位加一。
      *  开关K0K0 = 0能调整分位,K0 = 1能调整时位。
      *  开关K2:k2为高电平时,使单脉冲输入至INT1,通过外中断实现相应值的加一功能。

二、地址分配和链接
      *  P2.7:  和写信号一起组成字位口的片选信号,字位口的对应地址为8000H
      *  P2.6:  和写信号一起组成字位口的片选信号,字位口的对应地址为4000H
      *  D0~D7: 单片机的数据总线,LED显示的内容通过D0~D7数据线从单片机传到LED
      *  P2.0~P2.5:单片机的P2口,和2764的高位地址线相连,决定2764中的存储单元的地址。
      *  P1.4~P1.7: 单片机的P1端口,和发光二极管L1~L4相连,通过单片机的P1.4~P1.7控制,所以显示秒表和时钟的时间变化。
      *  P1.0: 和开关K0相连,决定时间调整的字位。
      *  P1.1 :  和开关K1相连,决定时间运行的模式。
      *  P1.2: 和开关K2相连,决定外中断的模式选择。

三、整体功能简介
      LED显示模块与单片机的链接中,对LED显示模块的读写和字位、段码的选择通过口P2.6\P2.7完成的。
      外部存储器2764是通过锁存器373和单片机相连,并且通过P2端口的相关信号线进行地址的分配。地址范围是0000H~1FFFH

四、程序设计




  1. *程序:吴鉴鹰数字电子钟的设计                                                           
  2. ** 这一讲的主要内容: 数字电子钟的设计原理和程序                                                                                
  3. ** 功能描述:  
  4. ** 输 入:         
  5. ** 内容:     
  6. ** 输 出:
  7. **         
  8. ** 全局变量:
  9. ** 调用模块:
  10. **
  11. ** 作 者:    吴鉴鹰
  12. ** 日 期:     14.02.17


  13. 备注:有什么错误的地方,欢迎各大同仁指正


  14. O(∩_∩)O~
  15. *******************************************************/
  16. //变量定义和头文件的调用
  17. //定义头文件和各个输入管脚以及变量声明
  18. #include<reg52.h>
  19. #include<absacc.h>
  20. #define  uint unsigned int
  21. #define  uchar  unsigned char




  22. /*定义字型字位口*/
  23. #define  DIGPORT  XBYTE  [0X8000]
  24. #define  WORDPORT  XBYTE [0X4000]


  25. /*定义P1口各管脚*/
  26. sbit  K0 = P1^0;
  27. sbit  K1 = P1^1;
  28. sbit  K2 = P1^2;
  29. sbit  BEEP = P1^3;
  30. sbit  L0 = P1^4;
  31. sbit  L1 = P1^5
  32. sbit  L2 = P1^6;
  33. sbit  L3 = P1^7;


  34. uchar  data  BUFFER[2]  = {0,0};  //显示的缓存数组,依次为低位、高位
  35. uchar  data  CLOCK[4] = {0,0,0,0};
  36. uchar  data  SECOND[2] = {0,0};


  37. /*定义运行状态*/
  38. uchar  data  STATE = 0;
  39. /*STATE = 0;秒表*/
  40. /*STATE = 4,或者7,时钟运行*/
  41. /* STATE = 6,时钟时调整 */


  42. bit  bdata  SND = 0;    /*  秒表START(开始)  */
  43. bit  bdata  RST = 0;     /*秒表RESET(复位)*/


  44. /*数码管显示编码“0”-“9”,"A","-"*/
  45. uchar  code  TABLE[] = {0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,0X77,0X40};


  46. /******************************************************
  47. *程序:主程序                                                                                                                        
  48. ** 功能描述: 主干程序
  49. ** 输 入:         
  50. ** 内容:     
  51. ** 输 出:
  52. **         
  53. ** 全局变量:
  54. ** 调用模块:
  55. **
  56. ** 作 者:    吴鉴鹰
  57. ** 日 期:     14.02.17


  58. 备注:有什么错误的地方,欢迎各大同仁指正


  59. O(∩_∩)O~
  60. *******************************************************/
  61. void  main()
  62. {
  63.       uchar   stabak;
  64.           P1 = 0X0F;
  65.       EA = 1;
  66.       IT1 = 1;
  67.       ET0 = 1;
  68.       TMOD = 0X61;
  69.       TH0 = -5000/256;
  70.       TL0 = -5000%256;
  71.       TH1 = 0XFF;
  72.       TL1 = 0XFF;
  73.       T2CON = 0;
  74.       TH2 = -5000/256;
  75.       TL2 = -5000%256;


  76.        K0 = 1;
  77.        K1 = 1;
  78.        K2 = 1;
  79.        STATE = P1&0X07;
  80.        stabak = STATE;


  81.       for(;;)
  82.     {
  83.            switch()
  84.         {
  85.                 case 0:
  86.                 {
  87.                     EX1 = 0;
  88.                     ET1 = 1;
  89.                     ET2 = 1;
  90.                     TR1 = 1;
  91.                     SND = 1;
  92.                     L1 = 1;   
  93.                     L0 = 0;
  94.                     L2 = 0;
  95.                     SECOND[0] = 0;
  96.                     SECOND[1] = 0;
  97.                 }break;


  98.                  case   5:
  99.                 {
  100.                           IE1 = 0;
  101.                           EX1 = 1;
  102.                           ET1 = 0;
  103.                           ET2 = 0;
  104.                           TR0 = 0;
  105.                           L0 = 1;
  106.                           L1 = 0;
  107.                           L2 = 0;
  108.                 }break;


  109.                 case  6:
  110.                {
  111.                     IE1 = 0;
  112.                     EX1 = 1;
  113.                     ET1 = 0;
  114.                     ET2 = 1;
  115.                     TR0 = 0;
  116.                }break;


  117.                   default:
  118.                {
  119.                    EX1 = 0;
  120.                    ET1 = 0;
  121.                    ET2 = 1;
  122.                    L1 = 0;
  123.                                    L2 = 0;
  124.                }


  125.         }
  126.          while(STATE == stabak)
  127.      {
  128.          switch(STATE)
  129.       {
  130.          case 0:
  131.       {
  132.          BUFFER[0] = SECOND[0];
  133.          BUFFER[1] = SECOND[1];
  134.       }break;
  135.       
  136.       case 5:
  137.       {
  138.           BUFFER[0] = CLOCK[2];
  139.           BUFFER[1] = 101;/*A-*/
  140.       }break;
  141.       
  142.       case 6:
  143.       {
  144.           BUFFER[0] = 110;/*A-*/
  145.           BUFFER[1] = CLOCK[3];
  146.       }break;
  147.       
  148.       default:
  149.       {
  150.           BUFFER[0] = CLOCK[2];
  151.           BUFFER[1] = CLOCK[3];
  152.       }break;
  153.       
  154.       default:
  155.       {
  156.           BUFFER[0] = CLOCK[2];
  157.           BUFFER[1] = CLOCK[3];
  158.       }
  159.       
  160.       }
  161.       
  162.      //显示函数
  163.      display();
  164.      K0 = 1;
  165.      K1 = 1;
  166.      K2 = 1;
  167.      STATE = P1&0X07;   
  168.      }
  169.      stabak = STATE;
  170.     }
  171. }


  172. /******************************************************
  173. *程序:子函数(1):timer0(void)                                                                                                                        
  174. ** 功能描述:  用定时器0实现24小时的时钟显示
  175. ** 输 入:         
  176. ** 内容:     
  177. ** 输 出:
  178. **         
  179. ** 全局变量:
  180. ** 调用模块:
  181. **
  182. ** 作 者:    吴鉴鹰
  183. ** 日 期:     14.02.17


  184. 备注:有什么错误的地方,欢迎各大同仁指正


  185. O(∩_∩)O~
  186. *******************************************************/
  187. void  timer0(void)   interrupt  1  using 1
  188. {
  189.     /*重置定时器初值*/
  190. TH0 = -5000/256;
  191. TL0 = -5000%256;




  192. /*定时器处理*/
  193. CLOCK[0] = CLOCK[0]+1;
  194. if((CLOCK[0] == 50) && (STATE >= 4))
  195. {
  196.     L0 = !L0;
  197. }


  198. if(CLOCK[0] == 100)
  199. {
  200.     if(STATE >= 4)  L0 = !L0;
  201.     CLOCK[0] = 0;
  202.     CLOCK[1] = CLOCK[1] + 1;
  203.    
  204.     if(CLOCK[1] == 60)
  205.     {
  206.        CLOCK[1] = 0;
  207.     CLOCK[2] = CLOCK[2] + 1;
  208.     if(CLOCK[2] == 60)
  209.     {
  210.         CLOCK[2] == 0;
  211.      CLOCK[3] == CLOCK[3] + 1;
  212.      if(CLOCK[3] == 24)
  213.      {
  214.         CLOCK[3] = 0;
  215.      }
  216.     }
  217.     }
  218. }
  219. }


  220. /******************************************************
  221. *程序:子函数(2):intsvr1(void)                                                                                                                        
  222. ** 功能描述:  对外中断1的按键脉冲进行判断和计数,并完成对应的时间调整功能。
  223. ** 输 入:         
  224. ** 内容:     
  225. ** 输 出:
  226. **         
  227. ** 全局变量:
  228. ** 调用模块:
  229. **
  230. ** 作 者:    吴鉴鹰
  231. ** 日 期:     14.02.17


  232. 备注:有什么错误的地方,欢迎各大同仁指正


  233. O(∩_∩)O~
  234. *******************************************************/
  235. void intsvr1(void) interrupt  2  using 2  
  236. {
  237.    if(STATE == 5)
  238.    {
  239.        CLOCK[2] == CLOCK[2] + 1;
  240.     if(CLOCK[2] == 60)  CLOCK[2] == 0;
  241.    }
  242.    if(STATE == 6)
  243.    {
  244.        CLOCK[3] == CLOCK[3] + 1;
  245.     if(CLOCK[3] == 24)  CLOCK[3] = 0;
  246.    }
  247. }


  248. /******************************************************
  249. *程序:子函数(3):display(void)                                                                                                                        
  250. ** 功能描述:  用动态显示的方法,将当前的时间或秒表内容通过数码管显示。
  251. ** 输 入:         
  252. ** 内容:     
  253. ** 输 出:
  254. **         
  255. ** 全局变量:
  256. ** 调用模块:
  257. **
  258. ** 作 者:    吴鉴鹰
  259. ** 日 期:     14.02.17


  260. 备注:有什么错误的地方,欢迎各大同仁指正


  261. O(∩_∩)O~
  262. *******************************************************/
  263. void diplay(void)
  264. {
  265.    uchar i;
  266.    uchar delay;
  267.    uchar disp;
  268.    uchar digit;
  269.    digit = 0x08;
  270.    for(i = 0;i < 2; i++)
  271.    {
  272.       if(BUFFET> 100)  
  273. {
  274.    disp = BUFFER%10 + 10;
  275. }
  276.    else  disp = BUFFER%10;
  277.    
  278.    DIGPORT = digit;
  279.    WORDPORT = TABLE[disp];
  280.    
  281.    for(delay = 0;delay <= 200;delay ++);
  282.    digit = digit >> 1;
  283.    disp = BUFFER/10;
  284.    
  285.    DIGPORT = digit;
  286.    WORDPORT = TABLE[disp];
  287.    
  288.    for(delay = 0;delay <= 200;delay ++);
  289.    digit = digit >> 1;
  290.    }
  291. }




复制代码
发表于 2014-6-14 14:16:29 | 显示全部楼层
点赞!!
 楼主| 发表于 2014-6-14 14:26:43 | 显示全部楼层
回复 3# EIEfans


   谢谢,刚刚发布了几讲,还在审核中!
发表于 2014-6-15 10:17:08 | 显示全部楼层
赞!LZ威武!
发表于 2014-7-3 21:10:01 | 显示全部楼层
好厉害!
发表于 2014-7-11 14:21:47 | 显示全部楼层
赞!支持楼主
发表于 2014-7-16 12:31:30 | 显示全部楼层
貌似很不错啊
发表于 2014-7-16 12:32:09 | 显示全部楼层
非常感谢楼主
发表于 2014-7-21 03:34:06 | 显示全部楼层
非常感谢楼主
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-5-1 08:30 , Processed in 0.032321 second(s), 11 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表