找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机设计的防误踩油门系统 Proteus仿真程序

[复制链接]
ID:448615 发表于 2020-4-4 21:01 | 显示全部楼层 |阅读模式
防误踩油门系统的设计,基于51单片机的,有原理图和程序
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.png

单片机源程序如下:
  1. #include "reg52.h"        //此文件中定义了单片机的一些特殊功能寄存器
  2. #include <intrins.h>    //因为要用到左右移函数,所以加入这个头文件

  3. #define  uchar unsigned char
  4. #define  uint  unsigned int
  5. #define LCDLCDDisp_Off   0x3e
  6. #define LCDLCDDisp_On    0x3f
  7. #define Page_Add       0xb8//ye
  8. #define LCDCol_Add     0x40//lie
  9. #define Start_Line     0xC0//hang
  10. #define data_ora P0   /*液晶数据总线*/

  11. sbit k1=P1^4;
  12. sbit k2=P1^5;
  13. sbit k3=P1^6;
  14. sbit k4=P1^7;
  15. sbit beep=P1^1;
  16. sbit moto=P1^0;
  17. sbit LCDMcs=P2^1 ;    /*片选1*/
  18. sbit LCDScs=P2^2 ;    /*片选2*/
  19. sbit RESET=P2^3 ;     /*复位信号*/
  20. sbit LCDDi=P2^4 ;     /*数据/指令 选择*/
  21. sbit LCDRW=P2^5 ;     /*读/写 选择*/
  22. sbit LCDEnable=P2^6 ; /*读/写 使能*/

  23. uchar *tab;
  24. uint k=0;
  25. uint q=0;

  26. uchar code hz1[]=
  27. {
  28. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  29. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

  30. /*--  文字:  安  --*/
  31. /*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=16x16   --*/
  32. 0xFF,0xFF,0xFF,0x8F,0xEF,0xEF,0x2D,0xF5,0xF3,0x77,0x57,0x67,0x7F,0x7F,0x7F,0xFF,

  33. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
  34. };

  35. void LCDdelay(uchar x)
  36. {
  37.    int d;
  38.    uchar y;
  39.    for(y=0;y<x;y++)
  40.    for(d=0;d<10;d++);
  41. }

  42. void CheckState()        
  43. {
  44.    uchar dat,DATA;//状态信息(判断是否忙)
  45.    LCDDi=0; // 数据\指令选择,D/I(RS)="L" ,表示 DB7∽DB0 为显示指令数据
  46.    LCDRW=1; //R/W="H" ,E="H"数据被读到DB7∽DB0
  47.    do
  48.    {
  49.       DATA=0x00;
  50.       LCDEnable=1;    //EN下降源
  51.       LCDdelay(1);  //延时
  52.       dat=DATA;
  53.       LCDEnable=0;
  54.       dat=0x80 & dat; //仅当第7位为0时才可操作(判别busy信号)
  55.     }
  56.     while(!(dat==0x00));
  57. }

  58. void write_com(uchar cmdcode)
  59. {
  60.     CheckState();//检测LCD是否忙
  61.     LCDDi=0;
  62.     LCDRW=0;
  63.     P0=cmdcode;        
  64.     LCDdelay(1);
  65.     LCDEnable=1;
  66.     LCDdelay(1);
  67.     LCDEnable=0;
  68. }

  69. void write_data(uchar LCDDispdata)
  70. {
  71.     CheckState();//检测LCD是否忙
  72.     LCDDi=1;
  73.     LCDRW=0;
  74.     P0=LCDDispdata;
  75.     LCDdelay(1);
  76.     LCDEnable=1;
  77.     LCDdelay(1);
  78.     LCDEnable=0;
  79. }

  80. void init_lcd()
  81. {
  82.     LCDdelay(1);   
  83.     LCDMcs=1;//刚开始关闭两屏
  84.     LCDScs=1;
  85.     LCDdelay(1);
  86.     write_com(LCDLCDDisp_Off);//写初始化命令
  87.     write_com(Page_Add+0);
  88.     write_com(Start_Line+0);
  89.     write_com(LCDCol_Add+0);
  90.     write_com(LCDLCDDisp_On);
  91. }

  92. void Clr_Scr()
  93. {
  94.     uchar j,k;
  95.     LCDMcs=0; //左、右屏均开显示
  96.     LCDScs=0;
  97.      write_com(Page_Add+0);
  98.      write_com(LCDCol_Add+0);
  99.      for(k=0;k<8;k++)//控制页数0-7,共8页
  100.      {
  101.         write_com(Page_Add+k); //每页每页进行写
  102.           for(j=0;j<64;j++)  //每页最多可写32个中文文字或64个ASCII字符
  103.         {
  104.               write_com(LCDCol_Add+j);
  105.             write_data(0x00);//控制列数0-63,共64列,写点内容,列地址自动加1
  106.         }
  107.     }
  108. }

  109. Disp(uchar page,uchar column, uchar code *word)
  110. {
  111. uchar i;
  112. LCDMcs=0;
  113. LCDScs=1;
  114. write_com(0xb8|page);
  115. write_com(0x40|column);
  116. for(i=0;i<16;i++)
  117. write_data(word[i]);
  118. for(i=32;i<48;i++)
  119. write_data(word[i]);
  120. for(i=64;i<80;i++)
  121. write_data(word[i]);
  122. for(i=96;i<112;i++)
  123. write_data(word[i]);

  124. LCDMcs=1;
  125. LCDScs=0;
  126. write_com(0xb8|page);
  127. write_com(0x40);
  128. for(i=128;i<144;i++)
  129. write_data(word[i]);
  130. for(i=160;i<176;i++)
  131. write_data(word[i]);
  132. for(i=192;i<208;i++)
  133. write_data(word[i]);
  134. for(i=224;i<240;i++)
  135. write_data(word[i]);

  136. LCDMcs=0;
  137. LCDScs=1;
  138. write_com(0xb8|page+1);
  139. write_com(0x40|column);
  140. for(i=16;i<32;i++)
  141. write_data(word[i]);
  142. for(i=48;i<64;i++)
  143. write_data(word[i]);
  144. for(i=80;i<96;i++)
  145. write_data(word[i]);
  146. for(i=112;i<128;i++)
  147. write_data(word[i]);

  148. LCDMcs=1;
  149. LCDScs=0;
  150. write_com(0xb8|page+1);
  151. write_com(0x40);
  152. for(i=144;i<160;i++)
  153. write_data(word[i]);
  154. for(i=176;i<192;i++)
  155. write_data(word[i]);
  156. for(i=208;i<224;i++)
  157. write_data(word[i]);
  158. for(i=240;i<250;i++)
  159. write_data(word[i]);
  160. }

  161. void lcd()
  162. {
  163.     init_lcd();
  164.     Clr_Scr();
  165.      k=0;   
  166.      for(q=0;q<1;q++)
  167.      {
  168.       for(k=0xc0;k<0xff;k++)
  169.       {
  170.          Disp(0,0,hz1);
  171.          Disp(2,0,hz2);
  172.          Disp(4,0,hz3);
  173.          Disp(6,0,hz4);
  174.          LCDMcs=0;
  175.          LCDScs=0;
  176.          write_com(k);
  177.          LCDdelay(2);
  178.         }
  179.       }
  180. }   

  181. unsigned char start=0;
  182. unsigned char n=0;  //n为节拍常数变量   
  183. unsigned char code music_tab[] ={   
  184. 0x18, 0x30, 0x1C , 0x10, //格式为: 频率常数, 节拍常数, 频率常数, 节拍常数,   
  185. 0x20, 0x40, 0x1C , 0x10,   
  186. 0x18, 0x10, 0x20 , 0x10,   
  187. 0x1C, 0x10, 0x18 , 0x40,   
  188. 0x1C, 0x20, 0x20 , 0x20,   
  189. 0x1C, 0x20, 0x18 , 0x20,   
  190. 0x20, 0x80, 0xFF , 0x20,   
  191. 0x30, 0x1C, 0x10 , 0x18,   
  192. 0x20, 0x15, 0x20 , 0x1C,   
  193. 0x20, 0x20, 0x20 , 0x26,   
  194. 0x40, 0x20, 0x20 , 0x2B,   
  195. 0x20, 0x26, 0x20 , 0x20,   
  196. 0x20, 0x30, 0x80 , 0xFF,   
  197. 0x20, 0x20, 0x1C , 0x10,   
  198. 0x18, 0x10, 0x20 , 0x20,   
  199. 0x26, 0x20, 0x2B , 0x20,   
  200. 0x30, 0x20, 0x2B , 0x40,   
  201. 0x20, 0x20, 0x1C , 0x10,   
  202. 0x18, 0x10, 0x20 , 0x20,   
  203. 0x26, 0x20, 0x2B , 0x20,   
  204. 0x30, 0x20, 0x2B , 0x40,   
  205. 0x20, 0x30, 0x1C , 0x10,   
  206. 0x18, 0x20, 0x15 , 0x20,   
  207. 0x1C, 0x20, 0x20 , 0x20,   
  208. 0x26, 0x40, 0x20 , 0x20,   
  209. 0x2B, 0x20, 0x26 , 0x20,   
  210. 0x20, 0x20, 0x30 , 0x80,   
  211. 0x20, 0x30, 0x1C , 0x10,   
  212. 0x20, 0x10, 0x1C , 0x10,   
  213. 0x20, 0x20, 0x26 , 0x20,   
  214. 0x2B, 0x20, 0x30 , 0x20,   
  215. 0x2B, 0x40, 0x20 , 0x15,   
  216. 0x1F, 0x05, 0x20 , 0x10,   
  217. 0x1C, 0x10, 0x20 , 0x20,   
  218. 0x26, 0x20, 0x2B , 0x20,   
  219. 0x30, 0x20, 0x2B , 0x40,   
  220. 0x20, 0x30, 0x1C , 0x10,   
  221. 0x18, 0x20, 0x15 , 0x20,   
  222. 0x1C, 0x20, 0x20 , 0x20,   
  223. 0x26, 0x40, 0x20 , 0x20,   
  224. 0x2B, 0x20, 0x26 , 0x20,   
  225. 0x20, 0x20, 0x30 , 0x30,   
  226. 0x20, 0x30, 0x1C , 0x10,   
  227. 0x18, 0x40, 0x1C , 0x20,   
  228. 0x20, 0x20, 0x26 , 0x40,   
  229. 0x13, 0x60, 0x18 , 0x20,   
  230. 0x15, 0x40, 0x13 , 0x40,   
  231. 0x18, 0x80, 0x00   
  232. };
  233.    
  234. void int0()  interrupt 1 //采用中断0 控制节拍   
  235. {  TH0=0xd8;   
  236.    TL0=0xef;   
  237.    n--;   
  238. }
  239.    
  240. void delaya(unsigned int a)
  241. {
  242.     while(a--);   
  243. }

  244. void delayb (unsigned char m) //控制频率延时   
  245. {   
  246. unsigned b=3*m;   
  247. while(--b);   
  248. }   
  249.    
  250. void delayc(unsigned char c)  //豪秒延时子程序   
  251. {   
  252.   while(--c);               
  253. }   

  254. void sound()
  255. {
  256.   unsigned char p,m;   //m为频率常数变量   
  257.   unsigned char i=0;   
  258.   TMOD&=0x0f;   
  259.   TMOD|=0x01;   
  260.   TH0=0xd8;TL0=0xef;   
  261.   IE=0x82;   
  262. play:   
  263.   while(1)
  264.     {   
  265.     a: p=music_tab[i];   
  266.        if(p==0x00)       { i=0, delayc(1000); goto play;}     //如果碰到结束符,延时1秒,回到开始再来一遍   
  267.        else if(p==0xff)  { i=i+1;delayc(100),TR0=0; goto a;}  //若碰到休止符,延时100ms,继续取下一音符   
  268.             else         {m=music_tab[i++], n=music_tab[i++];}  //取频率常数 和 节拍常数   
  269.              TR0=1;                                             //开定时器1   
  270.            while(n!=0) beep=~beep,delayb(m);                         //等待节拍完成, 通过P1口输出音频
  271.        TR0=0;                                             //关定时器1   
  272.     }   
  273. }

  274. void dcmotor()
  275. {   
  276.     unsigned char j;
  277.     moto=0;            //关闭电机
  278.     for(j=0;j<100;j++)    //循环100次,也就是大约5S
  279.     {
  280.         moto=1;            //开启电机
  281.         delaya(5000);    //大约延时50ms
  282.     }
  283.     moto=0;            //关闭电机
  284.   
  285. }
  286.   
  287. void keypros()
  288. {
  289.     if((k1|k2|k3|k4)==0)     //开始
  290.     {
  291.         delaya(1000);
  292.         if((k1|k2|k3|k4)==0)
  293.         {
  294.             start=1;        
  295.         }
  296.     }
  297. }

  298. void main()
  299. {   
  300.     while(1)
  301.     {
  302.         keypros();
  303.         if(start==1)
  304.         {      
  305.             lcd();
  306.             dcmotor();         
  307.             sound();               
  308.         }      
  309.         else
  310.         {
  311.             beep=1;
  312.             moto=0;
  313.         }        
  314.     }        
  315. }
复制代码

所有资料51hei提供下载:
proteus仿真代码.zip (40.9 KB, 下载次数: 20)
回复

使用道具 举报

ID:328014 发表于 2020-4-4 22:08 | 显示全部楼层
程序有问题吧,无屏幕显示
回复

使用道具 举报

ID:402026 发表于 2020-4-19 18:04 | 显示全部楼层
这个程序和仿真有以下几个缺陷:1.仿真的时候,屏幕没有显示。2.缺少提示和说明,不知道按键是做什么的!3.这个防误踩油门系统,怎么工作的?原理如何?一个都不知道!
回复

使用道具 举报

ID:402026 发表于 2020-4-19 22:06 | 显示全部楼层
不过还是很感谢你的努力和辛苦,你的程序的借鉴意义是恨到的!再次感谢
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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