防误踩油门系统的设计,基于51单片机的,有原理图和程序
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
- #include <intrins.h> //因为要用到左右移函数,所以加入这个头文件
- #define uchar unsigned char
- #define uint unsigned int
- #define LCDLCDDisp_Off 0x3e
- #define LCDLCDDisp_On 0x3f
- #define Page_Add 0xb8//ye
- #define LCDCol_Add 0x40//lie
- #define Start_Line 0xC0//hang
- #define data_ora P0 /*液晶数据总线*/
- sbit k1=P1^4;
- sbit k2=P1^5;
- sbit k3=P1^6;
- sbit k4=P1^7;
- sbit beep=P1^1;
- sbit moto=P1^0;
- sbit LCDMcs=P2^1 ; /*片选1*/
- sbit LCDScs=P2^2 ; /*片选2*/
- sbit RESET=P2^3 ; /*复位信号*/
- sbit LCDDi=P2^4 ; /*数据/指令 选择*/
- sbit LCDRW=P2^5 ; /*读/写 选择*/
- sbit LCDEnable=P2^6 ; /*读/写 使能*/
- uchar *tab;
- uint k=0;
- uint q=0;
- uchar code hz1[]=
- {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- /*-- 文字: 安 --*/
- /*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=16x16 --*/
- 0xFF,0xFF,0xFF,0x8F,0xEF,0xEF,0x2D,0xF5,0xF3,0x77,0x57,0x67,0x7F,0x7F,0x7F,0xFF,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
- };
- void LCDdelay(uchar x)
- {
- int d;
- uchar y;
- for(y=0;y<x;y++)
- for(d=0;d<10;d++);
- }
- void CheckState()
- {
- uchar dat,DATA;//状态信息(判断是否忙)
- LCDDi=0; // 数据\指令选择,D/I(RS)="L" ,表示 DB7∽DB0 为显示指令数据
- LCDRW=1; //R/W="H" ,E="H"数据被读到DB7∽DB0
- do
- {
- DATA=0x00;
- LCDEnable=1; //EN下降源
- LCDdelay(1); //延时
- dat=DATA;
- LCDEnable=0;
- dat=0x80 & dat; //仅当第7位为0时才可操作(判别busy信号)
- }
- while(!(dat==0x00));
- }
- void write_com(uchar cmdcode)
- {
- CheckState();//检测LCD是否忙
- LCDDi=0;
- LCDRW=0;
- P0=cmdcode;
- LCDdelay(1);
- LCDEnable=1;
- LCDdelay(1);
- LCDEnable=0;
- }
- void write_data(uchar LCDDispdata)
- {
- CheckState();//检测LCD是否忙
- LCDDi=1;
- LCDRW=0;
- P0=LCDDispdata;
- LCDdelay(1);
- LCDEnable=1;
- LCDdelay(1);
- LCDEnable=0;
- }
- void init_lcd()
- {
- LCDdelay(1);
- LCDMcs=1;//刚开始关闭两屏
- LCDScs=1;
- LCDdelay(1);
- write_com(LCDLCDDisp_Off);//写初始化命令
- write_com(Page_Add+0);
- write_com(Start_Line+0);
- write_com(LCDCol_Add+0);
- write_com(LCDLCDDisp_On);
- }
- void Clr_Scr()
- {
- uchar j,k;
- LCDMcs=0; //左、右屏均开显示
- LCDScs=0;
- write_com(Page_Add+0);
- write_com(LCDCol_Add+0);
- for(k=0;k<8;k++)//控制页数0-7,共8页
- {
- write_com(Page_Add+k); //每页每页进行写
- for(j=0;j<64;j++) //每页最多可写32个中文文字或64个ASCII字符
- {
- write_com(LCDCol_Add+j);
- write_data(0x00);//控制列数0-63,共64列,写点内容,列地址自动加1
- }
- }
- }
- Disp(uchar page,uchar column, uchar code *word)
- {
- uchar i;
- LCDMcs=0;
- LCDScs=1;
- write_com(0xb8|page);
- write_com(0x40|column);
- for(i=0;i<16;i++)
- write_data(word[i]);
- for(i=32;i<48;i++)
- write_data(word[i]);
- for(i=64;i<80;i++)
- write_data(word[i]);
- for(i=96;i<112;i++)
- write_data(word[i]);
- LCDMcs=1;
- LCDScs=0;
- write_com(0xb8|page);
- write_com(0x40);
- for(i=128;i<144;i++)
- write_data(word[i]);
- for(i=160;i<176;i++)
- write_data(word[i]);
- for(i=192;i<208;i++)
- write_data(word[i]);
- for(i=224;i<240;i++)
- write_data(word[i]);
- LCDMcs=0;
- LCDScs=1;
- write_com(0xb8|page+1);
- write_com(0x40|column);
- for(i=16;i<32;i++)
- write_data(word[i]);
- for(i=48;i<64;i++)
- write_data(word[i]);
- for(i=80;i<96;i++)
- write_data(word[i]);
- for(i=112;i<128;i++)
- write_data(word[i]);
- LCDMcs=1;
- LCDScs=0;
- write_com(0xb8|page+1);
- write_com(0x40);
- for(i=144;i<160;i++)
- write_data(word[i]);
- for(i=176;i<192;i++)
- write_data(word[i]);
- for(i=208;i<224;i++)
- write_data(word[i]);
- for(i=240;i<250;i++)
- write_data(word[i]);
- }
- void lcd()
- {
- init_lcd();
- Clr_Scr();
- k=0;
- for(q=0;q<1;q++)
- {
- for(k=0xc0;k<0xff;k++)
- {
- Disp(0,0,hz1);
- Disp(2,0,hz2);
- Disp(4,0,hz3);
- Disp(6,0,hz4);
- LCDMcs=0;
- LCDScs=0;
- write_com(k);
- LCDdelay(2);
- }
- }
- }
- unsigned char start=0;
- unsigned char n=0; //n为节拍常数变量
- unsigned char code music_tab[] ={
- 0x18, 0x30, 0x1C , 0x10, //格式为: 频率常数, 节拍常数, 频率常数, 节拍常数,
- 0x20, 0x40, 0x1C , 0x10,
- 0x18, 0x10, 0x20 , 0x10,
- 0x1C, 0x10, 0x18 , 0x40,
- 0x1C, 0x20, 0x20 , 0x20,
- 0x1C, 0x20, 0x18 , 0x20,
- 0x20, 0x80, 0xFF , 0x20,
- 0x30, 0x1C, 0x10 , 0x18,
- 0x20, 0x15, 0x20 , 0x1C,
- 0x20, 0x20, 0x20 , 0x26,
- 0x40, 0x20, 0x20 , 0x2B,
- 0x20, 0x26, 0x20 , 0x20,
- 0x20, 0x30, 0x80 , 0xFF,
- 0x20, 0x20, 0x1C , 0x10,
- 0x18, 0x10, 0x20 , 0x20,
- 0x26, 0x20, 0x2B , 0x20,
- 0x30, 0x20, 0x2B , 0x40,
- 0x20, 0x20, 0x1C , 0x10,
- 0x18, 0x10, 0x20 , 0x20,
- 0x26, 0x20, 0x2B , 0x20,
- 0x30, 0x20, 0x2B , 0x40,
- 0x20, 0x30, 0x1C , 0x10,
- 0x18, 0x20, 0x15 , 0x20,
- 0x1C, 0x20, 0x20 , 0x20,
- 0x26, 0x40, 0x20 , 0x20,
- 0x2B, 0x20, 0x26 , 0x20,
- 0x20, 0x20, 0x30 , 0x80,
- 0x20, 0x30, 0x1C , 0x10,
- 0x20, 0x10, 0x1C , 0x10,
- 0x20, 0x20, 0x26 , 0x20,
- 0x2B, 0x20, 0x30 , 0x20,
- 0x2B, 0x40, 0x20 , 0x15,
- 0x1F, 0x05, 0x20 , 0x10,
- 0x1C, 0x10, 0x20 , 0x20,
- 0x26, 0x20, 0x2B , 0x20,
- 0x30, 0x20, 0x2B , 0x40,
- 0x20, 0x30, 0x1C , 0x10,
- 0x18, 0x20, 0x15 , 0x20,
- 0x1C, 0x20, 0x20 , 0x20,
- 0x26, 0x40, 0x20 , 0x20,
- 0x2B, 0x20, 0x26 , 0x20,
- 0x20, 0x20, 0x30 , 0x30,
- 0x20, 0x30, 0x1C , 0x10,
- 0x18, 0x40, 0x1C , 0x20,
- 0x20, 0x20, 0x26 , 0x40,
- 0x13, 0x60, 0x18 , 0x20,
- 0x15, 0x40, 0x13 , 0x40,
- 0x18, 0x80, 0x00
- };
-
- void int0() interrupt 1 //采用中断0 控制节拍
- { TH0=0xd8;
- TL0=0xef;
- n--;
- }
-
- void delaya(unsigned int a)
- {
- while(a--);
- }
- void delayb (unsigned char m) //控制频率延时
- {
- unsigned b=3*m;
- while(--b);
- }
-
- void delayc(unsigned char c) //豪秒延时子程序
- {
- while(--c);
- }
- void sound()
- {
- unsigned char p,m; //m为频率常数变量
- unsigned char i=0;
- TMOD&=0x0f;
- TMOD|=0x01;
- TH0=0xd8;TL0=0xef;
- IE=0x82;
- play:
- while(1)
- {
- a: p=music_tab[i];
- if(p==0x00) { i=0, delayc(1000); goto play;} //如果碰到结束符,延时1秒,回到开始再来一遍
- else if(p==0xff) { i=i+1;delayc(100),TR0=0; goto a;} //若碰到休止符,延时100ms,继续取下一音符
- else {m=music_tab[i++], n=music_tab[i++];} //取频率常数 和 节拍常数
- TR0=1; //开定时器1
- while(n!=0) beep=~beep,delayb(m); //等待节拍完成, 通过P1口输出音频
- TR0=0; //关定时器1
- }
- }
- void dcmotor()
- {
- unsigned char j;
- moto=0; //关闭电机
- for(j=0;j<100;j++) //循环100次,也就是大约5S
- {
- moto=1; //开启电机
- delaya(5000); //大约延时50ms
- }
- moto=0; //关闭电机
-
- }
-
- void keypros()
- {
- if((k1|k2|k3|k4)==0) //开始
- {
- delaya(1000);
- if((k1|k2|k3|k4)==0)
- {
- start=1;
- }
- }
- }
- void main()
- {
- while(1)
- {
- keypros();
- if(start==1)
- {
- lcd();
- dcmotor();
- sound();
- }
- else
- {
- beep=1;
- moto=0;
- }
- }
- }
复制代码
所有资料51hei提供下载:
proteus仿真代码.zip
(40.9 KB, 下载次数: 20)
Proteus原理图.zip
(69.12 KB, 下载次数: 17)
|