单片机中的状态机理解

:

转载大佬的链接为:https://blog.csdn.net/huohongpeng/article/details/51489049

第1章 单片机初试牛刀

1.1 一个LED闪烁的故事

   用单片机实现1个LED闪烁功能,要求LED亮500ms, 灭300ms。这个问题对于学过单片机的人来说是一个入门级的东西,实现起来简单的不能再简单了,就像C语言入门时的“HelloWorld”。好让我们来实现以下这个功能。


   
   
  1. int main()
  2. {
  3. while( 1)
  4. {
  5.           LedOn();
  6.           DelayMs( 500);
  7.           LedOff();
  8.           DelayMs( 300);
  9. }
  10. }

1.2 两个LED同时闪烁的故事

   根据上一节内容我们让LED完成了闪烁功能,在这一节当中,我们来让两个LED完成同时闪烁的功能,这对于一些工程来讲,还是一样入门级的东西,好,让我们来一起实现它。


   
   
  1. int main()
  2. {
  3. while( 1)
  4. {
  5.           Led1On();
  6.           Led2On();
  7.           DelayMs( 500);
  8.           Led1Off();
  9.           Led2Off();
  10.           DelayMs( 300);
  11. }
  12. }

1.3 两个LED不同时闪烁的故事

   上面两个例子,看起来实际上是一个故事,因为他们只是在延时的前后加上了LED的开关动作。这一节我们来尝试一下,让两个LED不同时闪烁,比如,LED1开200ms,关500ms,

LED2开300ms,关400ms。乍得一听,不知如何下手。对,有的小伙伴可能想起来了,用定时器来实现啊,嗯,没错可以这样做。那好我们来试试吧。在看下面的代码之前建议看到的小伙伴,想一想如果让你来自己实现这一功能你会怎么实现。


   
   
  1. #define LED_ON (unsigned char)(0x01)
  2. #define LED_OFF (unsigned char)(0x00)
  3. #define LED1_ON_TIME_MS (unsigned short)(200)
  4. #define LED1_OFF_TIME_MS (unsigned short)(500)
  5. #define LED2_ON_TIME_MS (unsigned short)(300)
  6. #define LED2_OFF_TIME_MS (unsigned short)(400)
  7. int main()
  8. {
  9. /*初始化定时器中断间隔为*/
  10. TimerMsInit( 1);
  11. while( 1);
  12. }
  13. /*定时器中断函数*/
  14. void TimerMsInterrupt(void)
  15. {
  16. if(Led1Flag == LED_ON)
  17. {
  18. if(Led1Count > LED1_ON_TIME_MS)
  19. {
  20. Led1Count = 0;
  21. Led1Off();
  22. Led1Flag = LED_OFF;
  23. }
  24. }
  25. else
  26. {
  27. if(Led1Count > LED1_OFF_TIME_MS)
  28. {
  29. Led1Count = 0;
  30. Led1On();
  31. Led1Flag = LED_ON;
  32. }
  33. }
  34. if(Led2Flag == LED_ON)
  35. {
  36. if(Led2Count > LED2_ON_TIME_MS)
  37. {
  38. Led2Count = 0;
  39. Led2Off();
  40. Led2Flag = LED_OFF;
  41. }
  42. }
  43. else
  44. {
  45. if(Led2Count > LED2_OFF_TIME_MS)
  46. {
  47. Led2Count = 0;
  48. Led2On();
  49. Led2Flag = LED_ON;
  50. }
  51. }
  52. Led1Count++;
  53. Led2Count++;
  54. }

    好,到这里我们已经把两个LED不同时闪烁的代码实现了,所有小伙伴都是想这么实现吗?或者还是在看到这段段码的时候根本没有想到怎么实现?其实在中断函数中已经有了“状态机”的模型,只是不太容易看出来。很多写单片机程序的人不太知道状态机是干什么的,不要着急,我们在下一个章节会详细介绍。其实到这里还是没有引出我们的重点内容,好吧,只能给聪明的小伙伴留一个思考题了。如果思考题没有想出来可以带着疑问去看第2章内容。

1.4 思考题

  单片机有串口1个,灯2个分别为LED1和LED2,按键2个分别为KEY1和KEY2。要求如下:

1 在KEY1按下的一瞬间,串口发送”KEY1 DOWN”
2 在KEY1 按下时,LED1亮起,KEY1按下的时间长短任意。如果KEY1一直处于按下状态那么LED1一直亮起。
3 在KEY1抬起的一瞬间,串口发送”KEY1 UP”
4 在KEY1抬起时,LED1熄灭
5 在KEY2按下的一瞬间,串口发送”KEY2 DOWN”
6 在KEY2 按下时,LED2亮起,KEY2按下的时间长短任意。如果KEY2一直处于按下状态那么LED2一直亮起。
7 在KEY2抬起的一瞬间,串口发送”KEY2 UP”
8 在KEY2抬起时,LED2熄灭
9 两个按键按下抬起,互不影响,且能立即反映做出动作。(最重要的要求)
10 为了简化问题,这里不考虑按键去抖。

   小伙伴们,脑洞大开想一想这个问题,几个很简单的外设,这样的要求是不是在你们买的开发板的示例程序中从来没有见到过?不要每天沉溺于高级外设蓝牙、USB等等,单片机的逻辑还是很重要滴!

第2章 状态机的通俗解释

2.1 状态机概念  

    按照最标准的概念介绍状态机可能很多人会不理解,所以想来想去还是用最通俗的语言来解释这一概念,配合一个简单的例子来介绍。

    其实,状态机就是把一件事情分为几个过程来实现,每个过程对应一个状态。比如一个人一天的生活吧,当然人每天的生活非常复杂,这里我只举几个比较常见的事情,以吃饭为主,这样对于像我这样爱吃的小伙伴可能更容易理解。好了,来大致介绍一下吧,比如生活包括做饭、吃饭、洗碗、睡觉、看电视、散步。其中这些都是生活中的某一状态那么我们画一个状态图来理解一下吧。

                                                   图2.1

   通过上图可以看到,椭圆中就代表一个状态,饿了、吃饱了等代表进入到下一个状态的条件,也就是说满足一个条件就可以进入到下一个状态。

2.2 状态机具体化

     好了,有了上一节的描述,小伙伴们对状态机应该有了一个模糊的概念,那么下面我们来将上一章的思考题,具体的变为几个状态,根据实际情况来画一下状态图。

    对于上一节的思考题,LED1,KEY1和LED2,KEY2可以看做相同的情况,那么我们就用其中一个来说明。

                                                    图2.2

    根据上图我们可以看出,一共将整个过程分为了四个状态,分别为检测按键是否按下、LED打开、检测按键是否抬起、串口输出LED关闭。而触发进入到下一状态的条件包括按键按下、处理完成、按键抬起,其中处理完成实际上就是无条件执行的,也就是说,不管怎样,LED打开后就是要进入到等待按键抬起状态。

    状态图有什么要求呢?总结以下几点:1 每个状态中不可以有延时。2 必须能够从上一个状态进入到下一个状态,也就是不能永远停留在一个状态。

    好了,这一章就说这么多吧,下一章,我们将用代码来实现上面的例子。

第3章 状态机在单片机上的应用

3.1 代码实现步骤

   根据上一章,我们可以看到状态机的状态图,而这一章我们将状态图进一步转化为实际的代码示例。转化的过程实际上只需要定义一个变量来指示整个状态就可以了。另一方面,从状态图中可以看到,如果把整个状态当成一个模块,那么这么模块应该在while(1)中无限循环下去。好了,来看具体的程序代码吧。

3.2 应用代码详解


   
   
  1. #define KEY_STAT_CHECK_DOWN (unsigned char)(0x00) /*检测按键是否按下状态*/
  2. #define KEY_STAT_CHECK_UP (unsigned char)(0x01) /*检测按键是否抬起状态*/
  3. #define KEY_STAT_DOWN_HANDLE (unsigned char)(0x02) /*按键按下处理*/
  4. #define KEY_STAT_UP_HANDLE (unsigned char)(0x03) /*按键抬起处理*/
  5. unsigned char Key1Stat; /*定义 KEY1 模块的状态变量用于记录状态*/
  6. unsigned char key2stat; /*定义 KEY2 模块的状态变量用于记录状态*/
  7. void Key1Moudle(unsigned char *pstat); /*KEY1 模块处理函数*/
  8. void Key2Moudle(unsigned char *pstat); /*KEY2 模块处理函数*/
  9. void Key1StatCheckDown(unsigned char *pstat); /*KEY1 的按键按下检测函数*/
  10. void Key1StatCheckUp(unsigned char *pstat); /*KEY1 的按键抬起检测函数*/
  11. void Key1StatDownHandle(unsigned char *pstat); /*KEY1 的按键按下处理函数*/
  12. void Key1StatUpHandle(unsigned char *pstat); /*KEY1 的按键抬起处理函数*/
  13. void Key2StatCheckDown(unsigned char *pstat); /*KEY2 的按键按下检测函数*/
  14. void Key2StatCheckUp(unsigned char *pstat); /*KEY2 的按键抬起检测函数*/
  15. void Key2StatDownHandle(unsigned char *pstat); /*KEY2 的按键按下处理函数*/
  16. void Key2StatUpHandle(unsigned char *pstat); /*KEY2 的按键抬起处理函数*/
  17. int main()
  18. {
  19. while( 1)
  20. {
  21. /*按键 1 模块处理*/
  22. Key1Moudle(&Key1Stat);
  23. /*按键 2 模块处理*/
  24. Key2Moudle(&Key1Stat);
  25. }
  26. }
  27. void Key1Moudle(unsigned char *pstat)
  28. {
  29. /*根据当前状态判断执行哪一个状态处理函数*/
  30. switch(*stat)
  31. {
  32. case KEY_STAT_CHECK_DOWN : Key1StatCheckDown(pstat); break;
  33. case KEY_STAT_DOWN_HANDLE : Key1StatDownHandle(pstat); break;
  34. case KEY_STAT_CHECK_UP : Key1StatCheckUp(pstat); break;
  35. case KEY_STAT_UP_HANDLE : Key1StatUpHandle(pstat); break;
  36. /*当没有此状态,默认设置为检测按键是否按下状态*/
  37. default :
  38. *pstat = KEY_STAT_CHECK_DOWN;
  39. break;
  40. }
  41. return;
  42. }
  43. void Key2Moudle(unsigned char *pstat)
  44. {
  45. /*根据当前状态判断执行哪一个状态处理函数*/
  46. switch(*stat)
  47. {
  48. case KEY_STAT_CHECK_DOWN : Key2StatCheckDown(pstat); break;
  49. case KEY_STAT_DOWN_HANDLE : Key2StatDownHandle(pstat); break;
  50. case KEY_STAT_CHECK_UP : Key2StatCheckUp(pstat); break;
  51. case KEY_STAT_UP_HANDLE : Key2StatUpHandle(pstat); break;
  52. /*当没有此状态,默认设置为检测按键是否按下状态*/
  53. default :
  54. *pstat = KEY_STAT_CHECK_DOWN;
  55. break;
  56. }
  57. return;
  58. }
  59. void Key1StatCheckDown(unsigned char *pstat)
  60. {
  61. /*判断按键是否按下*/
  62. if( ReadKey1() == 0x00)
  63. { /*将状态设置为 按键按下处理状态*/
  64. *pstat = KEY_STAT_DOWN_HANDLE;
  65. }
  66. return;
  67. }
  68. void Key1StatDownHandle(unsigned char *pstat)
  69. {
  70. /*KEY1 按下状态处理*/
  71. UartSend( "KEY1 DOWN");
  72. Led1On();
  73. /*处理完成后,设置到 检测按键是否抬起状态*/
  74. *pstat = KEY_STAT_CHECK_UP;
  75. return;
  76. }
  77. void Key1StatCheckUp(unsigned char *pstat)
  78. {
  79. /*判断按键是否抬起*/
  80. if( ReadKey1() != 0x00)
  81. { /*将状态设置为 按键抬起处理状态*/
  82. *pstat = KEY_STAT_UP_HANDLE;
  83. }
  84. return;
  85. }
  86. void Key1StatUpHandle(unsigned char *pstat)
  87. {
  88. /*KEY1 按下状态处理*/
  89. UartSend( "KEY1 UP");
  90. Led1Off();
  91. /*处理完成后,设置到 检测按键是否按下状态*/
  92. *pstat = KEY_STAT_CHECK_DOWN;
  93. return;
  94. }
  95. void Key2StatCheckDown(unsigned char *pstat)
  96. {
  97. /*判断按键是否按下*/
  98. if( ReadKey2() == 0x00)
  99. { /*将状态设置为 按键按下处理状态*/
  100. *pstat = KEY_STAT_DOWN_HANDLE;
  101. }
  102. return;
  103. }
  104. void Key1StatDownHandle(unsigned char *pstat)
  105. {
  106. /*KEY2 按下状态处理*/
  107. UartSend( "KEY2 DOWN");
  108. Led2On();
  109. /*处理完成后,设置到 检测按键是否抬起状态*/
  110. *pstat = KEY_STAT_CHECK_UP;
  111. return;
  112. }
  113. void Key2StatCheckUp(unsigned char *pstat)
  114. {
  115. /*判断按键是否抬起*/
  116. if( ReadKey2() != 0x00)
  117. { /*将状态设置为 按键抬起处理状态*/
  118. *pstat = KEY_STAT_UP_HANDLE;
  119. }
  120. return;
  121. }
  122. void Key1StatUpHandle(unsigned char *pstat)
  123. {
  124. /*KEY2 按下状态处理*/
  125. UartSend( "KEY2 UP");
  126. Led2Off();
  127. /*处理完成后,设置到 检测按键是否抬起状态*/
  128. *pstat = KEY_STAT_CHECK_DOWN;
  129. return;
  130. }

第4章 简单的举例

4.1 实例概述

     这一章我们来一个实战的练习,以片外ADC为例子。那么现在来介绍一下片外ADC的采集过程。通常片外单芯片ADC采集。大致过程为:空闲状态->设置ADC开始采集->等待ADC采集完成->读取ADC采集数据,这里需要说明,片外这些ADC不会采集的特别快,采集一次需要的时间远比片上ADC的时间要长,如果单片机单纯的等待ADC采集完成,那么单片机的效率会变极低。所以采用状态机的方式,将ADC作为1个模块来完成。为了体现状态机

方式的编程技巧,在第3章讲述的例子上,加上ADC功能,加上ADC后系统按键反映必须还是非常灵敏,不能出现迟钝等现象,这就要求,ADC模块中不能添加延时。

    下面描述一下ADC需要实现功能。ADC需要1s采集一次,采集后的数值保存到变量中。当然,请各位一定要明白,通篇文章中的程序代码都是功能示意性代码,并非完整代码。

4.2 实例状态图

                                                图4.1

4.3 ADC部分实现


   
   
  1. #define ADC_ACQUISITION_PERIOD_MS (unsigned short)(1000)/*ADC 采集周期*/
  2. #define ADC_STAT_CHECK_TIME (unsigned char)(0x00) /*检查是否到达 ADC 采集时间*/
  3. #define ADC_STAT_START (unsigned char)(0x01) /*启动 ADC 采集*/
  4. #define ADC_STAT_CHECK_COMPLETE (unsigned char)(0x02) /*检查 ADC 是否采集完成*/
  5. #define ADC_STAT_CHECK_READ_DATA (unsigned char)(0x03) /*读取 ADC 采集的数据*/
  6. typedef struct
  7. {
  8. unsigned short CountMs; /*ADC 采集周期计时*/
  9. unsigned short AdcData; /*ADC 采集的数据*/
  10. unsigned char stat; /*ADC 模块状态变量*/
  11. }AdcStructTypeDef;
  12. AdcStrcutTypeDef AdcStruct;
  13. /*将第 3 章的 main 函数增加 1 条 ADC 模块*/
  14. int main()
  15. {
  16. while( 1)
  17. {
  18. /*按键 1 模块处理*/
  19. Key1Moudle(&Key1Stat);
  20. /*按键 2 模块处理*/
  21. Key2Moudle(&Key1Stat);
  22. /*ADC 模块采集*/
  23. AdcModule(&AdcStruct);
  24. }
  25. }
  26. /*定时器 1ms 中断函数*/
  27. void TimerInterruptMs(void)
  28. {
  29. /*在定时器中, 改变 ADC 的计数变量*/
  30. pAdcStruct->CountMs++;
  31. }
  32. void AdcMoudle(AdcStrcutTypeDef *pAdcStruct)
  33. {
  34. /*根据当前状态判断执行哪一个状态处理函数*/
  35. switch(pAdcStrcut->stat)
  36. {
  37. case ADC_STAT_CHECK_TIME : AdcStatCheckTime(pAdcStruct);
  38. case ADC_STAT_START : AdcStatStart(pAdcStruct);
  39. case ADC_STAT_CHECK_COMPLETE : AdcStatCheckComplete(pAdcStruct);
  40. case ADC_STAT_CHECK_READ_DATA : AdcStatCheckReadData(pAdcStruct);
  41. /*默认情况下设置状态为 ADC 检查是否到采集时间*/
  42. default :
  43. pAdcStruct->stat = ADC_STAT_CHECK_TIME;
  44. break;
  45. }
  46. }
  47. void AdcStatCheckTime(AdcStrcutTypeDef *pAdcStruct)
  48. {
  49. if(pAdcStruct->CountMs < ADC_ACQUISITION_PERIOD_MS)
  50. {
  51. /*采集周期没有到达直接返回*/
  52. return;
  53. }
  54. /*清零计时器*/
  55. pAdcStruct->CountMs = 0;
  56. /*设置状态为 启动 ADC 采集*/
  57. pAdcStruct->stat = ADC_STAT_START;
  58. return;
  59. }
  60. void AdcStatStart(AdcStrcutTypeDef *pAdcStruct)
  61. {
  62. /*设置 ADC 开始转换*/
  63. AdcStartCmd();
  64. /*设置状态为 检查 ADC 是否采集完成*/
  65. pAdcStruct->stat = ADC_STAT_CHECK_COMPLETE;
  66. return;
  67. }
  68. void AdcStatCheckComplete(AdcStrcutTypeDef *pAdcStruct)
  69. {
  70. /*读取 ADC 状态,判断是否采集完成*/
  71. if( AdcReadCompleteStat() == 0x00)
  72. {
  73. /*没有采集完成直接返回*/
  74. return;
  75. }
  76. /*设置状态为 检查 ADC 是否采集完成*/
  77. pAdcStruct->stat = ADC_STAT_CHECK_READ_DATA;
  78. }
  79. void AdcStatCheckReadData(AdcStrcutTypeDef *pAdcStruct)
  80. {
  81. /*读取 ADC 采集的数据到变量*/
  82. pAdcStruct->AdcData = AdcReadData();
  83. /*设置状态为 检查是否到达 ADC 采集时间*/
  84. pAdcStruct->stat = ADC_STAT_CHECK_TIME;
  85. }

4.4 总结

    

 以上内容仅供参考,如有错误请批评指正。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
单片机控制直流电动机——课程设计 单片机控制直流电动机——课程设计全文共17页,当前为第1页。单片机控制直流电动机——课程设计全文共17页,当前为第1页。目录 单片机控制直流电动机——课程设计全文共17页,当前为第1页。 单片机控制直流电动机——课程设计全文共17页,当前为第1页。 设计目的 设计任务和要求 设计原理分析 硬件资源及原理 硬件图 程序框图 程序 调试运行 仿真截图 设计心得体会 单片机控制直流电动机——课程设计全文共17页,当前为第2页。单片机控制直流电动机——课程设计全文共17页,当前为第2页。 单片机控制直流电动机——课程设计全文共17页,当前为第2页。 单片机控制直流电动机——课程设计全文共17页,当前为第2页。 一、设计目的 1、通过单片机课程设计,熟练掌握C语言的编程方法,将理论联系到实践,提高我们的动脑和动手的能力。 2、通过对单片机控制直流电动机控制系统的设计,掌握A/D转换、D/A转换的有关原理,加深对PWM波的理解和使用,同时对单片机的使用更加熟练,通过对简单程序的编写提高我们的逻辑抽象能力。 二、设计任务和要求 任务:采用单片机设计一个控制直流电动机并测量转速的装置。 要求: 1、通过改变A/D输入端的可变电阻来改变A/D输入电压,D/A输入检测量大小,进而改变直流电机的转速。 2、手动控制。在键盘上设置两个按键——直流电动机加速键和直流电机减速键。在手动状态下,每按一次键,电机的转速按照约定的速率改变。 3、键盘列扫描(4*6)。 三、设计原理分析 1. 设计思路 本文设计的直流PWM调速系统采用的是调压调速。系统主电路采用大功率GTR为开关器件、H桥单极式电路为功率放大电路的结构。PWM调制部分是在单片机开发平台之上,运用汇编语言编程控制。由定时器来产生宽度可调的矩形波。通过调节波形的宽度来控制H电路的GTR通断时间,以达到调节电机速度的目的。增加了系统的灵活性和精确性,使整个PWM脉冲的产生过程得到了大大的简化。设计以AT89C51单片机为核心,以键盘作为输入达到控制直流电机的启停、速度和方向,完成了基本要求和发挥部分的要求。在设计,采用了PWM技术对电机进行控制,通过对占空比的计算达到精确调速的目的。本文介绍了直流电机的工作原理和数学模型、脉宽调制控制原理和H桥电路基本原理设计了驱动电路的总体结构,根据模型,利用PROTEUS软件对各个子电路及整体电路进行了仿真,确保设计的电路能够满足性能指标要求,并给出了仿真结果。 2、 基本原理 单片机控制直流电动机——课程设计全文共17页,当前为第3页。单片机控制直流电动机——课程设计全文共17页,当前为第3页。主体电路:即直流电机PWM控制模块。PWM(脉冲宽度调制)是通过控制固定电压的直流电源开关频率,改变负载两端的电压,从而达到控制要求的一种电压调整方法。这部分电路主要由80C51单片机的I/O端口、定时计数器、外部断扩展等控制直流电机的加速、减速,并且可以调整电机的转速,还可以方便的读出电机转速的大小和了解电机的转向,能够很方便的实现电机的智能控制。其间是通过80C51单片机产生脉宽可调的脉冲信号并输入到L298驱动芯片来控制直流电机工作的。 单片机控制直流电动机——课程设计全文共17页,当前为第3页。 单片机控制直流电动机——课程设计全文共17页,当前为第3页。 四、硬件资源及原理 1.1直流电机调速原理 直流电动机根据励磁方式不同,直流电动机分为自励和他励两种类型。不同励磁方式的直流电动机机械特性曲线有所不同。但是对于直流电动机的转速有以下公式: n=U/Cc-TR内/CrCc 其:U—电压;—励磁绕组本身的电阻;—每极磁通(Wb);Cc—电势常数;Cr—转矩常量。由上式可知,直流电机的速度控制既可采用电枢控制法,也可采用磁场控制法。磁场控制法控制磁通,其控制功率虽然较小,但低速时受到磁极饱和的限制,高速时受到换向火花和换向器结构强度的限制,而且由于励磁线圈电感较大,动态响应较差。所以在工业生产过程常用的方法是电枢控制法。 图1-1 直流电机的工作原理图 单片机控制直流电动机——课程设计全文共17页,当前为第4页。单片机控制直流电动机——课程设计全文共17页,当前为第4页。电枢控制是在励磁电压不变的情况下,把控制电压信号加到电机的电枢上,以控制电机的转速。在工业生产广泛使用其脉宽调制(PWM)应用更为广泛。脉宽调速利用一个固定的频率来控制电源的接通或断开,并通过改变一个周期内"接通"和"断开"时间的长短,即改变直流电机电枢上电压的"占空比"来改变平均电压的大小,从而控制电动机的转速,因此,PWM又被称为"开关驱动装置"。 单片机控制直流电动机——课程设计全文共17页,当前为第4页。 单片机控制直流电动机——课程设计
单片机原理及系统课程设计 评语: 考勤10分 守纪10分 过程30分 设计报告30分 答辩20分 总成绩(100分) 专 业: 自动控制 班 级: 姓 名: 学 号: 指导教师: 兰州交通大学自动化与电气工程学院 2014 年 1 月 12 日 基于单片机的洗衣机设计全文共19页,当前为第1页。 基于单片机的洗衣机设计全文共19页,当前为第1页。 基于AT89C51单片机的全自动洗衣机设计 1 设计目的及要求 1.1设计目的 洗衣机已成为人们日常生活必不可少的一部分,但是传统的基于继电器的控制,已不能满足人们对洗衣机的要求。因此设计了基于单片机的洗衣机控制电路系统,由单片机控制实现洗衣机的各项功能。单片机的体积小,控制功能灵活,因此,设计出基于单片机的全自动洗衣机控制电路系统具有很强的实用性。由于个人能力有限,所设计的洗衣机比前沿科技产品要差很远。所以这次课程设计的主要目的在于通过亲手操作,查找资料,培养自己的分析设计能力,把这学期课程零散的知识进行整合,将理论的知识联系到实际的生活,在实例深入理解一些理论知识,并从有所收获。 1.2设计要求 模拟全自动洗衣机工作过程。以电机替代洗衣机电机。显示洗衣机工作的状态(进水、浸泡、洗衣、脱水、结束)。显示工作剩余时间(洗衣程序可自定义,时间精度:秒)。洗衣时交替正、反转。 2 设计方案及原理 2.1设计方案 利用AT89C51单片机的P0,P1,P2,P3串行口的输入输出功能,控制数码管、电动机、发光二极管的工作状态,进而模拟洗衣机的基本工作过程。 洗衣机的主要工作过程是:进水—洗涤—漂洗—换水—漂洗—换水—漂洗—换水—脱水—结束。上述工作过程,包含三个过程:洗涤过程、漂洗过程、脱水过程。 (1) 洗涤过程:放好待洗物,启动开关,进水阀通电,向洗衣机供水,供水结束后,洗涤电动机接通电源,通过电机不停的正转、反转,形成洗涤水对洗涤物产生强烈的翻滚作用;同时衣物之间、衣物与四周桶壁之间产生互相摩擦和撞击力,达到洗涤衣物的目的。 (2) 漂洗过程:漂洗的目的在于清除衣物上的洗涤液,因此,漂洗过程与洗涤过程的电机动作是完全相同的。 (3) 脱水过程:漂洗过程结束后,电动机停止转动,排水阀通电,打开排水阀门排水。当排水到一定程度,满足安全条件时,脱水电动机接通,电机带动脱水桶高速旋转,利用离心力把衣服上的水从桶壁的小眼里甩出。 基于单片机的洗衣机设计全文共19页,当前为第2页。全部洗衣工作完成后,结束指示的LED灯点亮,表示衣物已经洗好,洗衣机就会自动停止工作。 基于单片机的洗衣机设计全文共19页,当前为第2页。 2.2 设计原理 系统设计包括晶振和复位模块,电机驱动模块,LED显示模块,按键控制模块以及数码管显示模块五部分。利用AT89C51单片机芯片,芯片左排引脚外接晶振和复位电路,通过74LS245锁存器连接至数码管,控制数码管稳定显示。右排引脚外接电机驱动电路和各开关以及LED灯。通过人工按压相应的开关,接通电机驱动电路相应的接线端子,实现电机正反转以及LED显示。总体设计原理框图如图1所示。 图1 系统原理框图 通过对开关的操作实现选择想要进行的任何操作。当选择好模式后进入该模式。该模式的参数已装入在单片机,在单片机程序的控制下进行工作。 程序实现的主要功能是洗涤,漂洗和脱水的控制。其洗涤时间设初值为136s,由于洗衣过程电机要不停的正反转,所以用P3.2和P3.3控制。通过流经电机两端电平的高低控制电流的流向,从而改变电机的转向,实现正反转。漂洗过程和洗涤过程较为相似,由于漂洗要多次进行,所以用进水次数标志位flag1控制,当flag1为2,3,4时为漂洗过程。脱水过程是在出水次数flag2的控制下进行。当flag2为4时脱水,当脱水时间到达0后,脱水结束,洗衣结束。上述三个过程电机工作利用晶体管组成的驱动电路进行驱动。 3 硬件设计 3.1主要元器件 在本设计主要使用了以下元器件:AT89C51单片机芯片、74LS245芯片 、晶体振荡器、数码管、发光二极管、直流电动机、三极管。 3.2 硬件连接图 基于单片机的洗衣机设计全文共19页,当前为第3页。该设计主要应用80C51单片机,外接一些必要的扩展电路,构成系统电路原理图,如图2所示。 基于单片机的洗衣机设计全文共19页,当前为第3页。 图2 硬件连接图 3.3 系统设计原理 该设计采用模块化的方法,系统原理图分为五个模块,分别为晶振和复位模块,电机驱动模块,LED显示模块,按键控制模块以及数码管显示模块。 晶振和复位模块主要通过51单片机的内部振荡方式,产生原始的时钟频率。电机驱动模块主要包含电阻、三极管放大器和一个电机,通过与51单片机的P3.0-P3.3引脚连接,用于驱动相应的洗衣、漂洗和脱水程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值