找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3140|回复: 3
收起左侧

单片机控制实验程序 中断扩展+流水灯+直流电机+舵机+全彩LED+MAX7219

[复制链接]
ID:808939 发表于 2021-8-13 20:48 | 显示全部楼层 |阅读模式
中断扩展+流水灯+直流电机+舵机+全彩LED+蜂鸣器+温湿度+8 位锁存数码管:
通过 74HC595 或其他芯片的扩展技术,实现将 INT0 扩展为 16 个中断按键,按下后立即响应。
按键1.控制流水灯的方向,向左、向右。
按键2.控制流水灯的速度,高速、低速。
按键3.控制直流电机的方向,顺时针、逆时针。
按键4.控制直流电机的开关,启动、停止。
按键5.切换舵机的角度,每次增加 30°,到了+90°再增大,则变成-90°。
按键6.切换全彩 LED(RGBLED)的颜色,从灭到白共 8 种情况。
按键7.切换蜂鸣器的嘀嗒声的频率,低频、高频,且要保持响两三秒时间。
采用硬件定时器计时,每隔 3 秒,通过 DHT11 采集温湿度,温湿度数值通过串口发送到上位机(虚拟终端),波特率 9600bps(注意单 片机的晶振设置为 11.0592MHz),温湿度数值通过 8 位锁存数码管例如 MAX7219 显示。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.png 51hei.png

单片机源程序如下:
  1. #include "reg51.h"
  2. #include "intrins.h"
  3. #include "m7219.h"
  4. #include "dht11.h"
  5. #define u8 unsigned char
  6. #define u16 unsigned int

  7. u8 code LEDcode[12]={0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b,0x00,0x01}; //0,1,2,3,4,5,6,7,8,9,全灭,-
  8. /* 0x77,0x1f,0x4e,0x3d,0x4f,0x47,0x67,0x3e,0xff, */      /*A,B,C,D,E,F,P,U,全亮*/
  9. sbit A=P2^5;
  10. sbit D=P2^6;
  11. sbit C=P2^7;
  12. sbit P10=P1^0;
  13. sbit P11=P1^1;
  14. sbit P12=P1^2;
  15. sbit P13=P1^3;
  16. sbit pwm1=P1^4;
  17. sbit pwm2=P1^5;
  18. sbit pwm3=P1^6;
  19. sbit beep=P1^7;
  20. sbit B1=P0^2;
  21. sbit G1=P0^1;
  22. sbit R1=P0^0;
  23. sbit GS1=P2^0;
  24. sbit GS2=P2^1;

  25. u8 i,j,k=0,jiao=0,fang1=0,t=0,time,fang2=0,run=0,color=0,pinlv=0;
  26. u16 ms50=0,tms50=0;

  27. void delay(u16 i){while(i--);}

  28. void T0_init(void)
  29. {
  30.     TMOD = 0x01;
  31.     TH0 = 0x3C;
  32.     TL0 = 0xB0;
  33.     EA = 1;
  34.     ET0 = 1;
  35.     TR0 = 1;
  36. }
  37. void UART1_init(void)
  38. {
  39.         TMOD=0x20;          //定时器T1使用工作方式2
  40.         TH1=253;TL1=253;// 设置初值
  41.         TR1=1;          // 开始计时
  42.         SCON=0x50;          //工作方式1,波特率9600bps,允许接收   
  43.         ES=1;
  44.         EA=1;           // 打开所以中断   
  45.         TI=0;
  46.         RI=0;
  47. }
  48. void UART1_Send(u8 dat)
  49. {
  50.         ES=0;//关串口中断
  51.         SBUF=dat;                        
  52.         while(TI!=1);//等待发送成功
  53.         TI=0;//清除发送中断标志
  54.         ES=1;//开串口中断
  55. }
  56. void Buzzer_Delay500us()                //@12.000MHz
  57. {
  58.         u8 i;
  59.         _nop_();
  60.         i = 247;
  61.         while (--i);
  62. }
  63. void UART1_Sends(char *s)
  64. {
  65.     while(*s)UART1_Send(*s++);
  66. }
  67. void deng()
  68. {
  69.   if(t==0)
  70. {
  71.         if(fang1==0)
  72.         {P10=1;
  73.         delay(10000);
  74.                 P10=0;
  75.         P11=1;
  76.         delay(10000);
  77.                         P11=0;
  78.         P12=1;
  79.         delay(10000);
  80.                 P12=0;
  81.         P13=1;
  82.         delay(10000);
  83.         P13=0;}
  84.         if(fang1==1)
  85.         {P13=1;
  86.         delay(10000);
  87.                 P13=0;
  88.         P12=1;
  89.         delay(10000);
  90.         P12=0;
  91.         P11=1;
  92.         delay(10000);
  93.         P11=0;
  94.         P10=1;
  95.         delay(10000);
  96.         P10=0;}
  97. }
  98.         if(t==1)
  99. {
  100.         if(fang1==0)
  101.         {P10=1;
  102.         delay(30000);
  103.                 P10=0;
  104.         P11=1;
  105.         delay(30000);
  106.                         P11=0;
  107.         P12=1;
  108.         delay(30000);
  109.                 P12=0;
  110.         P13=1;
  111.         delay(30000);
  112.         P13=0;}
  113.         if(fang1==1)
  114.         {P13=1;
  115.         delay(30000);
  116.                 P13=0;
  117.         P12=1;
  118.         delay(30000);
  119.         P12=0;
  120.         P11=1;
  121.         delay(30000);
  122.         P11=0;
  123.         P10=1;
  124.         delay(30000);
  125.         P10=0;}
  126. }
  127. }
  128. void dianji()
  129. {
  130.         if(run==0)
  131.         {pwm1=1;pwm2=1;}
  132.         if(run==1)
  133.         {
  134.                 if(fang2==0)
  135.         {
  136.                 pwm2=1;
  137.                 pwm1=0;
  138.                 delay(300);;
  139.         }
  140.                 if(fang2==1)
  141.         {
  142.                 pwm1=1;
  143.                 pwm2=0;
  144.                 delay(300);
  145.         }
  146.         }
  147. }
  148. void duoji()
  149. {
  150.         switch(jiao)
  151. {
  152.   case 0:{pwm3=1;delay(50);
  153.                 pwm3=0;delay(1950);} break;// -90度
  154.         case 1:{pwm3=1;delay(118);
  155.                 pwm3=0;delay(1882);} break;// -60度
  156.         case 2:{pwm3=1;delay(135);
  157.                 pwm3=0;delay(1865);} break;// -30度
  158.         case 3:{pwm3=1;delay(152);
  159.                  pwm3=0;delay(1848);} break;// 0度
  160.         case 4:{pwm3=1;delay(169);
  161.                 pwm3=0;delay(1831);} break;// 30度
  162.         case 5:{pwm3=1;delay(186);
  163.                 pwm3=0;delay(1814);} break;// 60度
  164.         case 6:{pwm3=1;delay(250);
  165.                 pwm3=0;delay(1750);} break;// +90度
  166. }
  167. }
  168. void RGBLED()
  169. {
  170.         switch(color)
  171. {
  172.   case 0:{ R1=1;G1=1;B1=1;} break;// 黑色
  173.         case 1:{ R1=0;G1=1;B1=1;} break;// 红色
  174.         case 2:{ R1=0;G1=0;B1=1;} break;// 黄色
  175.         case 3:{ R1=1;G1=0;B1=1;} break;// 绿色
  176.         case 4:{ R1=1;G1=0;B1=0;} break;// 青色
  177.         case 5:{ R1=1;G1=1;B1=0;} break;// 蓝色
  178.         case 6:{ R1=0;G1=1;B1=0;} break;// 紫色
  179.         case 7:{ R1=0;G1=0;B1=0;} break;// 白色
  180. }
  181. }
  182. void Buzzer_Time(u16 ms)
  183. {
  184.         u16 i;
  185.         for(i=0;i<ms*2;i++)
  186.         {
  187.                 beep=!beep;
  188.                 Buzzer_Delay500us();
  189.         }
  190. }
  191. void Buzzer_Time2(u16 ms)
  192. {
  193.         u16 i;
  194.         for(i=0;i<ms*2;i++)
  195.         {
  196.                 beep=!beep;
  197.                 Buzzer_Delay500us();
  198.                 Buzzer_Delay500us();
  199.                 Buzzer_Delay500us();
  200.         }
  201. }
  202. void Beep()
  203. {
  204.         if(pinlv==0) beep=1;
  205.         if(pinlv==1)
  206.         { Buzzer_Time2(2000);
  207.         }
  208.         if(pinlv==2)
  209.         { Buzzer_Time(2000);
  210.         }
  211. }
  212. void WS()
  213. {
  214.                 tms50=0;
  215.                 DHT11_RH();
  216.                 UART1_Sends("温度:");
  217.                 UART1_Send (wen/10+'0');
  218.                 UART1_Send (wen%10+'0');
  219.                 UART1_Sends("湿度:");
  220.                 UART1_Send (shi/10+'0');
  221.                 UART1_Send (shi%10+'0');
  222.                 UART1_Send(0x0d);UART1_Send(0x0a);
  223.                 MAX7219_send16(1,LEDcode[wen/10]);
  224.                 MAX7219_send16(2,LEDcode[wen%10]);
  225.                 MAX7219_send16(4,LEDcode[shi/10]);
  226.                 MAX7219_send16(5,LEDcode[shi%10]);
  227. }
  228. void main()
  229. {
  230.         IT0=1;EX0=1;EA=1;
  231.         T0_init();
  232.         UART1_init();
  233.         MAX7219_init();
  234.         MAX7219_clear();
  235.         while(1)
  236.         {
  237.                 if(k==0)
  238.                 MAX7219_send16(7,LEDcode[0]);
  239.           MAX7219_send16(8,LEDcode[i+1]);
  240.                 if(k==1)
  241.                 {
  242.                         MAX7219_send16(7,LEDcode[i/10]);
  243.                         MAX7219_send16(8,LEDcode[i%10]);
  244.                 }
  245.                 deng();
  246.                 dianji();
  247.                 duoji();
  248.                 RGBLED();
  249.                 Beep();
  250.                
  251.         }
  252. }

  253. void Keydown() interrupt 0
  254. { i=0;
  255.         if(A==0) i=i+1;
  256.         if(D==0) i=i+2;
  257.         if(C==0) i=i+4;
  258.         if(GS1==0) k=0;
  259.         if(GS2==0) {k=1;i=i+9;}
  260.                         switch(i)
  261. {
  262.                         case 0: fang1=!fang1;break;
  263.                         case 1: t=!t; break;
  264.                         case 2: fang2=!fang2;break;
  265.                         case 3: run=!run;break;
  266.                         case 4: {jiao++;
  267.                                        if(jiao>=7) jiao=0;} break;
  268.                         case 5: {color++;
  269.                                        if(color>=8) color=0;} break;
  270.                         case 6: {pinlv++;
  271.                                  if(pinlv>=3) pinlv=0;} break;
  272. }
  273. }
  274. void T0_INT(void) interrupt 1//每隔15ms自动进来一次
  275. {
  276.     TH0 = 0x3C;
  277.     TL0 = 0xB0;
  278.           ms50++;
  279.                 tms50++;
  280.         if(tms50==300)
  281.         {
  282.                 tms50=0;
  283.           WS();
  284.         }
  285. }
  286. void UART1_INT(void) interrupt 4
  287. {
  288.         if(RI){RI=0;}//如果是串口输入引起的中断
  289.         else{TI=0;}//否则就是串口输出引起的中断
  290.         
  291. }
复制代码
51hei.png

仿真代码资料51hei附件下载:
仿真.7z (131.11 KB, 下载次数: 43)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:548551 发表于 2021-8-14 09:40 | 显示全部楼层
我想请问下你哪里都用到了中断,为什么还要用延时呢。
回复

使用道具 举报

ID:808939 发表于 2021-8-14 15:43 | 显示全部楼层
xqleft 发表于 2021-8-14 09:40
我想请问下你哪里都用到了中断,为什么还要用延时呢。

定时中断只是想单纯控制串口采集数据,虽然也可以利用它来进行其他的工作状态计时单机那样会复杂一点。我这个还是想让其他人尤其刚开始学习的更容易看懂,体会一下单片机的乐趣。
回复

使用道具 举报

ID:748788 发表于 2021-8-18 15:00 | 显示全部楼层
我用7219时发现仿真和实物的显示顺序是相反的,例如仿真显示12345678,下载的实物上却显示87654321.不知你是否遇到?
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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