赞
踩
这是我对这几个月学习51单片机的一些汇总,谈谈对51的一些看法,51大致就是对定时器,计算器,中断,串口的一些操作,前面我浅谈一下51的基本操作,后面我会对Sg-90舵机,超声波,LCD1602,DHT11温湿度传感器,IIC-OLED,HC-05蓝牙模块,esp8266-01sWI-FI模块,4G模块,4驱小车进行一个详细的汇总,希望能对大家有所帮助。
文章目录
单片机是一种集成电路芯片,采用超大规模集成技术把具有处理数据能力的中央处理器CPU、随机存储器ROM、只读存储器RAM、定时器/计算器、中断系统和IO口等功能集成到一块硅片上构成的一个小型计算机,从当时的4为、8位发展到现在的300M的高速单片机。
我们都知道在学校是通过铃声来控制所有班级的上下课时间,我们都知道单片机执行指令的过程就是从ROM取出一条指令执行来完成它在各个地方的作用,那它什么时候取指令这个是顺序呢?这里引入一个时序的周期,每访问一次ROM的时间,就是一个机器周期的时间。
1个机器周期 = 6个状态周期 = 12个时钟(振荡)周期
时钟周期:即单片机的基本时间单位,若晶体的频率=12MHZ,那时钟周期 = 1/12MHZ,一个时钟周期 = 1/12MHZ = 1/12000 000每秒
机器周期:即12x1/12 000 000 =0.000001s = 1us,访问一次ROM取指令的时间就是1us
电平特性
数字电路中只有两种电平:高电平和低电平
高电平:5v或者3.3v,取决与单片机电源
低电平:0V
RS232电平:计算机串口的电平
高电平:-12v
低电平:+12v
我们跟电脑通信的时候,要通过元器件将单片机的电平转换成电脑能识别的电平,才能跟电脑进行通信。
"与"运算
有0得0,全1才1
1&1 = 1,1&0 = 0; 0&0 = 0;
"或"运算
有1得1,全0才0;
1|1 = 1;1|0 = 1;0|0 = 0;
"非"运算
~1 = 0;~0 = 1;
通过sbit访问单片机P2^0口,给它一个低电平,使它点亮
- #include <REGX52.h>
-
- sbit led = P2^0;//sbit作用是定义特殊功能寄存器的位变量 此时变量led就保存了p2^0的地址
-
- void main()
- {
-
- led = 0;//通过看原理图,这个io口的led是低电平触发
-
-
- }
通过单片机自带的按键使它点亮
- #include <REGX52.h>
-
- sbit led = P2^0;
-
- sbit key_open = P3^1;
- sbit key_close = P3^2;
-
- void main()
- {
-
- led = 1;//先默认让led关
-
- while(1)
- {
- if(key_open == 0)//当按下key_open它会的到一个低电平
- {
- led = 0;//按下按键我打开led
- }
-
- if(key_close == 0)//按下key_close,就关闭led
- {
- led = 1;
- }
- }
-
-
-
-
- }
这里是通过按键开关来控制点亮了led的
- #include <REGX52.h>
- #include <intrins.h>
-
- void main()
- {
-
- P2 = 0xfe;//因为led是低电平点亮 0xfe = 1111 1110,我们先让第0位点亮
-
- while(1)
- {
-
-
- Delay1000ms();
- P2 = P2 << 1;//然后依次左移一位就= 1111 1101,让第1位点亮,后面依次操作
- //循环到第7位 = 是0111 1111 但是之前每循环左移都给了低电平
- if(P2 == 0x00)//所以当 = 0111 1111 的时候重新给它赋值位0xfe
- {
-
- P2 = 0xfe;
- }
-
- }
-
-
- }
-
- void Delay1000ms() //延迟函数
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 8;
- j = 154;
- k = 122;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
通过震动点亮led
- #include <REGX52.h>
- #include <intrins.h>
-
- sbit shake = P0^0;
- sbit led = P2^0;
-
- void main()
- {
- led = 1;
-
- while(1)
- {
- if(shake == 0)//当发生震动 就点亮led
- {
- led = 0;
- }
-
- }
-
-
-
- }
通过震动让继电器把接在继电器上的灯点亮
- #include <REGX52.h>
- #include <intrins.h>
-
- sbit shake = P0^0;
- sbit relay = P0^1;
-
- void main()
- {
-
- while(1)
- {
- if(shake == 0)//当发生震动打开继电器
- {
- relay = 0;
-
- }
-
- }
-
- }
通过433收发模块按下打开继电器让报警器响,在按一下让它停止响,当然你也可以在配一个震动传感器,如果发生震动就响,在按一下就停止响。
- #include <REGX52.h>
- #include <intrins.h>
-
- sbit d0 = P0^0;
- sbit d1 = P0^1;
- sbit relay = P0^7;
-
- void main()
- {
-
- while(1)
- {
- if(d0 == 1)
- {
- relay = 0;
- }
-
- if(d1 == 1)
- {
- relay = 1;
- }
- }
-
-
- }
51单片机有两组定时器,一组是T0,一组是T1,因为几个定时/计数,所以称为定时器。定时器的本质就是每过一个机器周期加1
定时器一共有4个模式
GATE =1,要用软件使TR0/TR1置1,才能开始工作,同时外部中断INT0/1为高电平,才能启动定时器
C/T = 0是定时模式,=1是计数模式
- #include <REGX52.h>
- #include <intrins.h>
-
- sbit led = P2^0;
-
-
- void Delay1000ms() //延迟函数
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 8;
- j = 154;
- k = 122;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
-
- void Time_Init()
- {
- TMOD = 0x01;
- TL0 = 0x20; //设置定时初值1ms,定时器初值=(2的16次方(因为我选的模式1)—x)x12/你单片机晶振的频率 = 你要设的初值(us)求出的x转换成16 进制就行了
- TH0 = 0xD1;
- TR0 = 1;
- TF0 = 0;
-
-
- }
-
-
- void main()
- {
- int num = 0;
- Time_Init();
-
-
- led = 1;//默认led为关的状态
-
- while(1)
- {
- if(TF0 == 1)//定时好了溢出
- {
-
- ++num;//每溢出一次加1
-
- TL0 = 0x20; //设置定时初值
- TH0 = 0xD1;
- }
-
- if(num == 1000)//加到1000 也就是1s 打开led
- {
- led = !led;
-
- }
-
-
- }
-
-
-
- }
比如:你正在喝奶茶,此时发生了一个紧急事情,你就会先暂停喝奶茶,转而取处理这个紧急事情,等紧急事情处理完了,你就可以继续和奶茶了。我们把这种紧急事情叫做中断。但是如果你喝奶茶期间发生了许多事情,那就要按照紧急事情的优先级来处理。
- #include <REGX51.H>
-
- sbit led = P2^0;
-
- int cnt = 0;
-
- void Time_Init()
- {
- TMOD = 0x10;
- TL1 = 0x18; //设置定时初值
- TH1 = 0xFC;
- TR1 = 1;
- TF1 = 0;//现在还没有溢出,先让他=0
- ET1 = 1;//用的T1就必须用T1中断通道
- EA = 1;
-
-
-
- }
-
-
-
- void main()
- {
- Time_Init();
- led = 1;
-
- while(1);
-
- }
-
- void zd() interrupt 3
- {
- TL1 = 0x18;
- TH1 = 0xFC;
-
- cnt++;
-
- if(cnt == 500)
- {
- cnt = 0;
- led =!led;
- }
- }
超声波测距
- #include <regx52.h>
-
- sbit trig = P0^1;//发送超声波,要发送超声波,必须给trig一个10us以上的高电平
- sbit echo = P0^0;//判断超声波什么时候发送和什么时候接收
- sbit led = P2^0;
-
- void Delay10us() //@11.0592MHz
- {
- unsigned char i;
-
- i = 2;
- while (--i);
- }
-
-
- void trig10us()
- {
- trig = 0;
- trig = 1;
- Delay10us();
- trig = 0;
-
- }
-
- void Time1_Init()
- {
- TMOD = 0x10;//choose 16bit 计数
- TL1 = 0;
- TH1 = 0;
- }
-
-
- void main()
- {
- double time;
- double dis;
- Time1_Init();
-
- while(1)
- {
-
- trig10us();
- while(echo == 0);//判断超声波说明时候发送
- TR1 = 1;//开始定时
- while(echo == 1);//判断超声波什么时候返回
- TR1 = 0;//停止计时
- time = (TH1 *256 + TL1)*1;//TL1和TH1是所计的数,1是机器周期1us,time就是超声波去的时间和返回的时间
- dis = (time/2)*0.034;//因为time存放的是去和返回的时间,所以要除以2,超声波测距是340m/s换算成 34000cm/s = 34cm/ms = 0.034cm/us
- if(dis < 10)
- {
- led = 0;//open led
- }
- else
- {
- led = 1;
- }
-
- TH1 = 0;
- TL1 = 0;
- }
-
- }
舵机
- /*
- 控制舵机是通过占空比来控制的,也就是在单位时间内,你控制让它得到多少高电平
- sg90舵机最高频率是50Mhz 周期就是0.02s = 20ms,我们字舵机20ms这个周期内给它高电平控制舵机角度
-
- 0° = 0.5ms
- 45° = 1ms
- 90° = 1.5ms
- 135°= 2ms
- 180°= 2.5ms
-
- */
- #include <regx52.h>
- #include <intrins.h>
-
- sbit sg90 = P0^7;
-
- int jd;//用于控制舵机角度
- int cnt;//用于计数来判断定时器中断溢出
-
- void Time0_Init()
- {
- TMOD = 0x01;
- TL0 = 0x33; //定时器第八位初始化
- TH0 = 0xFE;//定时器高八位初始化 设置定时0,5ms
- TR0 = 1;
- TF0 = 0;
- ET0 = 1;
- EA = 1;
-
- }
-
- void Delay1000ms() //延迟函数
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 8;
- j = 1;
- k = 243;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
-
- void main()
- {
- Time0_Init();
- jd = 1;
- cnt = 0;
-
- while(1)
- {
- jd = 5;
- cnt = 0;
- Delay1000ms();
- jd = 1;
- cnt = 0;
- Delay1000ms();
-
- }
-
- }
-
- void zd() interrupt 1
- {
- TL0 = 0x33;
- TH0 = 0xFE;
- cnt++;
-
- if(cnt <= jd)
- {
- sg90 = 1;
- }
-
- else
- {
- sg90 = 0;
- }
-
- if(cnt == 40)
- {
- cnt = 0;
- }
- }
垃圾桶
- #include <regx52.h>
- #include <intrins.h>
-
- sbit led = P2^0;
- sbit trig = P0^1; //超声波发送 给trig至少10us高电平
- sbit echo = P0^0;//怎么知道他开始发和接受的返回波
- sbit dj = P0^7;
- sbit key = P3^1;
- int cnt = 0;
- int jd;
-
- void Time0_Init()
- {
- TMOD &= 0xF0;
- TMOD |= 0x01;
- TL0 = 0x33; //定时器第八位初始化
- TH0 = 0xFE;//定时器高八位初始化 设置定时0,5ms
- TR0 = 1;//开始定时
- TF0 = 0;//定时器溢出标志位
- EA = 1;//中断允许总开关
- ET0 = 1;//T0中断允许开关
-
-
-
- }
-
- void Delay2500ms() //@11.0592MHz
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 18;
- j = 131;
- k = 103;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
-
- void Delay10us() //给trig一个10us延时
- {
- unsigned char i;
-
- i = 2;
- while (--i);
- }
-
- void Time1_Init()//初始化定时器
- {
- TMOD = 0x10;
- TH1 = 0;//从0开始定时
- TL1 = 0;
-
- }
-
- void trig10()//给trig一个10us高电平
- {
- trig = 0;
- trig = 1;//向外发送
- Delay10us();
- trig = 0;//恢复
-
- }
-
- double Read_Csb()
- {
- double dis;
- double time;
-
- TH1 = 0;//从0开始定时
- TL1 = 0;
-
- trig10();//发送一个信号
- while(echo == 0);//通过echo从高电平跳转到低电平知道已经开始发送信号了
- TR1 = 1;//信号发送开始定时
- while(echo == 1);//通过从低电平跳转到高电平知道波回来了
- TR1 = 0;//波回来了结束定时
- time=(TH1 * 256 + TL1)*1;//us为单位 计算中间进过的时间 记得数TH0和TL0相加 就是TH0左移8位 移1位 = 2;8位 = 256 ;*1.085一个机器周期
- dis = time / 2* 0.034;//距离 = 340m/s = 34000cm/s = 34cm/ms = 0.034cm/us 时间来回两次 / 2
-
-
- return dis;
-
- }
-
- void main()
- {
- double dis;
- Time1_Init();//初始化定时器
- Time0_Init();
- jd = 1;
- cnt = 0;
- led = 1;
-
- while(1)
- {
- dis = Read_Csb();
-
- if(dis < 10 || key == 0)
- {
- led = 0;
- jd = 5;
- Delay2500ms();
-
-
-
- }
- else
- {
- led = 1;
- jd = 1;
- }
-
-
-
- }
-
- }
-
- void zd() interrupt 1 //控制脉冲
- {
- cnt++;
-
- TL0 = 0x33;
- TH0 = 0xFE;
-
- if(cnt <= jd)
- {
- dj = 1;
- }
- else
- {
- dj = 0;
- }
- if(cnt == 40)
- {
- cnt = 0;
-
- }
-
-
-
- }
串口通信
1.单工 只有一根线,只能单向传输
2.半双工 有两根线Tx、Rx,交叉连接,但是任何时候只有一个方向传输和接收
3.全双工 有两根线可以在两个方向上传输
同步和异步通信
1.同步通信 发送数据和,等待接收方回应了,才能继续发送下个数据
同步通信 必须保持双方在同一个时钟
2.异步通信 发送数据后,不等待接收方的回应,继续发送下个数据
异步通信 因为发送效率低,所以每发送一个字符,要加开始位和停止位,还要配置波特率
- #include <REGX51.H>
- #include <intrins.h>
-
- void UART_Init()
- {
- PCON = 0x00;//波特率不翻倍
- SCON = 0x50;//sm0 sm1 sm2 ren rb8 tb8 ti ri 每发送一个数据ti必须复位 每接收一个数据ri必须复位 ren = 1允许接收
- TMOD = 0x20;//波特率配置 方式1 9600 =(2smod/32)*t1的溢出率
- TH1 = 0XFD;//t1溢出率 = (频率/32)*(256 -TH1)
- TL1 = 0xFD;
- TR1 = 1;//打开定时器1
-
- }
-
- void Delay10000ms() //@11.0592MHz
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 71;
- j = 10;
- k = 171;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
-
- void main()
- {
-
- UART_Init();
-
- while(1)
- {
- Delay10000ms();
- SBUF = 'a';//每个一秒发送一个字符
- }
- }
- #include <REGX51.H>
- #include <intrins.h>
-
- void UART_Init()
- {
- SCON = 0x50;
- TMOD = 0x20;
- TH1 = 0XFD;
- TL1 = 0xFD;
- TR1= 1;
-
-
- }
-
-
- void Send_Bit(char Data)
- {
- SBUF = Data;
- while(!TI);
- TI = 0;
-
- }
-
- void Send_String(char * p)
- {
-
- while(*p != '\0')
- {
-
- Send_Bit(*p);
- p++;
- }
-
- }
-
- void Delay1000ms() //@11.0592MHz
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 8;
- j = 1;
- k = 243;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
-
- void main()
- {
- UART_Init();
-
- while(1)
- {
- Delay1000ms();
- Send_String("iverson");
- }
-
-
- }
-
- #include <REGX51.H>
- #include <intrins.h>
-
- sbit led =P2^0;
-
- void UART_Init()
- {
- SCON = 0x50;
- TMOD = 0x20;
- TH1 = 0XFD;
- TL1 = 0xFD;
- TR1 = 1;
- ES = 1;
- EA = 1;
-
- }
-
- void Delay1000ms() //@11.0592MHz
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 8;
- j = 1;
- k = 243;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
-
- void main()
- {
-
-
- UART_Init();
-
- while(1)
- {
- Delay1000ms();
- SBUF = 'a';
- }
- }
-
-
- void zd() interrupt 4//串口中断
- {
-
-
- if(RI == 1)
- {
- RI = 0;
-
- if(SBUF == 'o')
- {
- led = 0;
- }
- if(SBUF == 'c')
- {
- led = 1;
- }
- }
-
-
- }
- /*
- 就是在同一个局域网 服务器先连接WiFi 获得WiFiIP esp826601s在通过WIFIIP连接服务器
- 单片机通过串口发送数据给esp826601s esp826601s接受该AT数据连接 WIFI 和 服务器等
- 就开始实现数据传输
-
- AT+CWMODE=3 //1. 是station(设备)模式 2.是AP(路由)模式 3.是双模
- OK
-
- AT+CWJAP="TP-LINK_3E30","18650711783" //指令
- WIFI CONNECTED //结果
- WIFI GOT IP //结果
-
- AT+CIFSR //指令
- +CIFSR:APIP,"192.168.4.1" 当esp826601s做路由的IP
- +CIFSR:APMAC,"4e:75:25:0d:ae:2f"
- +CIFSR:STAIP,"192.168.0.148"
- +CIFSR:STAMAC,"4c:75:25:0d:ae:2f"
- OK
-
- AT+CIPSTART="TCP","192.168.0.113",8888 //指令,注意双引号逗号都要半角(英文)输入
- CONNECT //结果:成功
- OK //结果:成功
-
- AT+CIPSEND=4 // 设置即将发送数据的长度 (这里是4个字节)
- >CLCA // 看到大于号后,输入消息,CLCA,不要带回车
- Response :SEND OK //结果:成功
- //注意,这种情况下,每次发送前都要先发送AT+CIPSEND=长度 的指令,再发数据!
-
- AT+CIPMODE=1 //开启透传模式
- Response :OK
- +++退出透传模式
-
- AT+CIPSEND //带回车
- Response: > //这个时候随意发送接收数据咯
-
-
- */
-
- #include <regx52.h>
- #include <intrins.h>
- #include <string.h>
- #define SIZE 12
-
- sbit Led = P2^0;
- sbit Led1= P2^7;
-
- code char LJWL []="AT+CWJAP=\"iPhone\",\"00000000\"\r\n";
- code char LJFWQ[]="AT+CIPSTART=\"TCP\",\"169.254.165.190\",8880\r\n";
- char TC []="AT+CIPMODE=1\r\n";
- char SJFS[]="AT+CIPSEND\r\n";
-
- char buffer[SIZE];
-
- void Delay7000ms()
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 50;
- j = 7;
- k = 195;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
- void Delay1000ms()
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 8;
- j = 1;
- k = 243;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
-
- void Uart()
- {
- PCON = 0x00;
- SCON = 0x50;
- TMOD = 0x20;
- TH1 = 0xFD;
- TL1 = 0xFD;
- TR1 = 1;
- ES = 1;
- EA = 1;
- }
-
- void SendByt(char Js)
- {
- SBUF = Js;
- while(! TI );
- TI = 0;
- }
-
- void SendString(char * p)
- {
- while(*p != '\0')
- {
- SendByt(*p);
- p++;
- }
- }
-
- void main()
- {
- Led = 1;
-
- Uart();
- Delay1000ms();
-
- SendString(LJWL);
- Delay7000ms();
-
- SendString(LJFWQ);
- Delay7000ms();
-
- SendString(TC);
- Delay1000ms();
-
- SendString(SJFS);
- Delay1000ms();
-
- Led = 0;
-
- while(1)
- {
- SendString("666\r\n");
- }
-
- }
-
- void Zd() interrupt 4
- {
- unsigned char cmd;
- static int i = 0;
- if(RI == 1)
- {
- RI = 0;
- cmd = SBUF;
-
- if(cmd == 'o' ||cmd == 'c')
- {
- i = 0;
- }
- buffer[i++] = cmd;
- if(buffer[0] == 'o'&&buffer[3]=='n')
- {
- Led1 = 0;
- memset(buffer, '\0', SIZE);
-
- }
-
- if(buffer[0] == 'c'&& buffer[4]=='e')
- {
- Led1 = 1;
- memset(buffer, '\0', SIZE);
-
- }
-
- if(i == 12)i = 0;
- }
- }
- /*
-
- 4G是公网通信不认识:‘局域网’;
- 我们可以将内网IP穿透 就是利用花生壳 把内网ip弄成外网可以访问的一个地址端口
-
- 我建立个服务器 通过花生壳把IP打造成外网可以访问的IP 通过AT指令先配置好(4G模块是先配置 重启才能使用)
- 单片机接受4G发来的数据 如果检索到跟我设置一样的数据就可以进行点灯操作等。。。
- 跟蓝牙一样 优点是突破了地域限制
-
-
- 1. 打开串口连接4G模块,串口出产默认波特率是115200,可以自行根据用户手册修改
- 2. 进入AT指令模式,在串口助手内发送+++(不要勾选发送新行),必须在发送+++指令 3s 内发送其
- 他任意 AT 指令,比如AT+CPIN 1 检测到sim卡 0 没有检测到
- 3. 观察SIM卡灯是否亮起,AT+ICCID获得SIM卡信息,确认SIM卡安装完好 返回数据:
- +OK=89860116838013413419
- 检查信号是否正常,通过AT+CSQ指令检查信号值,建议插入信号天线,返回数据:+OK=31
- 4. AT+SOCK=TCPC,103.46.128.21,52541 连接socket服务器,
- 103.46.128.21是公网IP地址,通过花生壳获得,26532是端口号,参数之间逗号隔开
- 5.AT+REBT 重启模块。
- 6.AT+UART=9600,NONE none表示没有奇偶校验位 4g默认uart=115200;
- 7.AT+LINKSTA 查询 TCP 链接是否已建立链接 返回Connect(TCP 连接)/ Disconnect(TCP 断开)
-
-
- */
-
- #include <regx52.h>
- #include <string.h>
-
-
- sbit Led = P2^7;
-
-
-
- void Uart()
- {
- PCON = 0x00;
- SCON = 0x50;
- TMOD = 0x20;
- TH1 = 0xFD;
- TL1 = 0xFD;
- TR1 = 1;
- ES = 1;
- EA = 1;
- }
-
- void main()
- {
- Led = 1;
-
- Uart();
- while(1);
-
- }
-
- void Zd() interrupt 4
- {
- char cmd;
-
-
- if(RI == 1)
- {
- RI = 0;
- cmd = SBUF;
-
- if(cmd == 'o')
- {
- Led = 0;
- }
- if(cmd == 'c')
- {
- Led = 1;
- }
- }
- }
- #include <regx52.h>
- #include <intrins.h>
- #define buffer P0
-
- sbit RS = P2^6;
- sbit RW = P2^5;
- sbit EN = P2^7;
-
-
-
- void Read_Busy()
- {
- char flag = 0x80;
- buffer = 0x80;
-
- while(flag & 0x80)
- {
- RS = 0;
- RW = 1;
- EN = 0;
- _nop_();
-
- EN = 1;
- _nop_();
- _nop_();
-
- flag = buffer;
-
- EN = 0;
- _nop_();
-
- }
-
-
- }
-
- void Write_Cmd(char cmd)
- {
- Read_Busy();
-
- RS = 0;
- RW = 0;
-
- EN = 0;
- _nop_();
-
- buffer = cmd;
- _nop_();
-
- EN = 1;
- _nop_();
- _nop_();
-
- EN = 0;
- _nop_();
-
-
-
- }
-
- void Write_Data(char Data)
- {
- Read_Busy();
-
-
- RW = 0;
- RS = 1;
- EN = 0;
- _nop_();
-
- buffer = Data;
- _nop_();
-
- EN = 1;
- _nop_();
- _nop_();
-
- EN = 0;
- _nop_();
-
-
- }
-
- void Delay5ms() //@12.000MHz
- {
- unsigned char i, j;
-
- i = 10;
- j = 183;
- do
- {
- while (--j);
- } while (--i);
- }
-
- void Delay15ms() //@12.000MHz
- {
- unsigned char i, j;
-
- i = 30;
- j = 43;
- do
- {
- while (--j);
- } while (--i);
- }
-
-
-
- void LCD1602_Init()
- {
- //(1)延时 15ms
- Delay15ms();
- //(2)写指令 38H(不检测忙信号)
- Write_Cmd(0x38);
- //(3)延时 5ms
- Delay5ms();
- //(4)以后每次写指令,读/写数据操作均需要检测忙信号
- //(5)写指令 38H:显示模式设置
- Write_Cmd(0x38);
- //(6)写指令 08H:显示关闭
- Write_Cmd(0x08);
- //(7)写指令 01H:显示清屏
- Write_Cmd(0x01);
- //(8)写指令 06H:显示光标移动设置
- Write_Cmd(0x06);
- //(9)写指令 0CH:显示开及光标设置}
- Write_Cmd(0x0c);
-
-
- }
-
-
- void Data_Show(char hang,char lie,char *p)
- {
- switch(hang)
- {
- case 1:
-
- Write_Cmd(0x80 + lie);
-
- while(*p != '\0')
- {
- Write_Data(*p);
- p++;
- }
- case 2:
-
- Write_Cmd(0x80 + 0x40 + lie);
-
- while(*p != '\0')
- {
- Write_Data(*p);
- p++;
- }
- }
-
- }
-
- void main()
- {
- LCD1602_Init();
-
- while(1)
- {
-
- Data_Show(1,6,"NO.1");
- Data_Show(2,4,"iverson!");
-
- }
- //Write_Cmd(0x80);
- //Write_Data('a');
-
-
- }
- #include <regx52.h>
- #include <intrins.h>
-
- sbit Led = P2^0;
- sbit Dht = P0^0;
- char Data[5];
-
- void Uart()
- {
- PCON = 0x00;
- SCON = 0x50;
- TMOD = 0x20;
- TH1 = 0xFD;
- TL1 = 0xFD;
- TR1 = 1;
- }
-
- void SendByte(char Js)
- {
- SBUF = Js;
- while(!TI);
- TI = 0;
- }
-
- void SendString(char *p)
- {
- while(*p != '\0')
- {
- SendByte(*p);
- p++;
- }
- }
-
- void Delay30us()
- {
- unsigned char i;
-
- i = 11;
- while (--i);
- }
-
- void Delay40us()
- {
- unsigned char i;
-
- _nop_();
- i = 15;
- while (--i);
- }
-
-
- void Dht_Start()
- {
- Dht = 1;
- Dht = 0;
- Delay30us();
- Dht = 1;
-
- while(Dht);
- while(!Dht);
- while(Dht);
-
-
- }
-
- void Read_Dht()
- {
- int i;
- int j;
- char tmp;
- char flag;
-
- Dht_Start();
-
- for(i = 0;i < 5;++i)
- {
- for(j = 0;j < 8;++j)
- {
-
-
- while(!Dht);
- Delay40us();
-
- if(Dht == 1)
- {
- flag = 1;
- while(Dht);
- }
- else
- {
- flag = 0;
- }
- tmp = tmp << 1;
- tmp = flag | tmp;
-
- }
- Data[i] = tmp;
- }
- }
-
-
- void Delay500ms()
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 4;
- j = 129;
- k = 119;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
-
- void main()
- {
-
- Uart();
-
- while( 1 )
- {
- Delay500ms();
- Read_Dht();
-
- SendString("H:");
-
- SendByte(Data[0] / 10 +0x30); //0x30 - 0x39 是0 - 9的ascll码
- SendByte(Data[0] % 10 + 0x30);//这样就可以把对应的字符变成ascll输出
- SendByte('.');
- SendByte(Data[1] / 10 +0x30);
- SendByte(Data[1] % 10 + 0x30);
- SendString("\r\n");
-
- SendString("T:");
-
- SendByte(Data[2] / 10 +0x30);
- SendByte(Data[2] % 10 + 0x30);
- SendByte('.');
- SendByte(Data[3] / 10 +0x30);
- SendByte(Data[3] % 10 + 0x30);
- SendString("\r\n");
-
-
-
- }
-
-
-
-
-
- }
让dht温湿度数据显示在Lcd1602上面
- #include <regx52.h>
- #include <intrins.h>
- #define buffer P0
-
-
- /*---------定义LCD1602 & DHT 引脚-----------*/
-
- sbit dht = P0^0;
- sbit RS = P2^6;
- sbit RW = P2^5;
- sbit EN = P2^7;
-
- /*----------wd&sd用于存放温湿度数据---------*/
- char Data[5];
- char sd[9];
- char wd[9];
-
- /*----------读第7位是不是高电平-------------*/
- void Read_Busy()
- {
- char flag = 0x80;
- buffer = 0x80;
-
- while(flag & 0x80)
- {
- RS = 0;
- RW = 1;
- EN = 0;
- _nop_();
-
- EN = 1;
- _nop_();
- _nop_();
-
- flag = buffer;
-
- EN = 0;
- _nop_();
-
- }
-
-
- }
-
- void Write_Cmd(char cmd)
- {
- Read_Busy();
-
- RS = 0;
- RW = 0;
-
- EN = 0;
- _nop_();
-
- buffer = cmd;
- _nop_();
-
- EN = 1;
- _nop_();
- _nop_();
-
- EN = 0;
- _nop_();
-
-
-
- }
-
- void Write_Data(char Data)
- {
- Read_Busy();
-
-
- RW = 0;
- RS = 1;
- EN = 0;
- _nop_();
-
- buffer = Data;
- _nop_();
-
- EN = 1;
- _nop_();
- _nop_();
-
- EN = 0;
- _nop_();
-
-
- }
-
- void Delay5ms() //@12.000MHz
- {
- unsigned char i, j;
-
- i = 10;
- j = 183;
- do
- {
- while (--j);
- } while (--i);
- }
-
- void Delay15ms() //@12.000MHz
- {
- unsigned char i, j;
-
- i = 30;
- j = 43;
- do
- {
- while (--j);
- } while (--i);
- }
-
-
-
- void LCD1602_Init()
- {
- //(1)延时 15ms
- Delay15ms();
- //(2)写指令 38H(不检测忙信号)
- Write_Cmd(0x38);
- //(3)延时 5ms
- Delay5ms();
- //(4)以后每次写指令,读/写数据操作均需要检测忙信号
- //(5)写指令 38H:显示模式设置
- Write_Cmd(0x38);
- //(6)写指令 08H:显示关闭
- Write_Cmd(0x08);
- //(7)写指令 01H:显示清屏
- Write_Cmd(0x01);
- //(8)写指令 06H:显示光标移动设置
- Write_Cmd(0x06);
- //(9)写指令 0CH:显示开及光标设置}
- Write_Cmd(0x0c);
-
-
- }
-
-
- void Data_Show(char hang,char lie,char *p)
- {
- switch(hang)
- {
- case 1:
-
- Write_Cmd(0x80 + lie);
-
- while(*p != '\0')
- {
- Write_Data(*p);
- p++;
- }
- case 2:
-
- Write_Cmd(0x80 + 0x40 + lie);
-
- while(*p != '\0')
- {
- Write_Data(*p);
- p++;
- }
- }
-
- }
-
- void Uart()
- {
- PCON = 0x00;
- SCON = 0x50;
- TMOD = 0x20;
- TH1 = 0xFD;
- TL1 = 0xFD;
- TR1 = 1;
- }
-
- void SendByte(char Js)
- {
- SBUF = Js;
- while(!TI);
- TI = 0;
- }
-
- void SendString(char *p)
- {
- while(*p != '\0')
- {
- SendByte(*p);
- p++;
- }
- }
-
-
- void Delay30us()
- {
- unsigned char i;
-
- i = 11;
- while (--i);
- }
-
- void Delay40us()
- {
- unsigned char i;
-
- _nop_();
- i = 15;
- while (--i);
- }
-
-
- void Dht_Start()
- {
- dht = 1;
- dht = 0;
- Delay30us();
- dht = 1;
-
- while(dht);
- while(!dht);
- while(dht);
-
-
- }
-
- void Read_Dht()
- {
- int i;
- int j;
- char tmp;
- char flag;
-
- Dht_Start();
-
- for(i = 0;i < 5;++i)
- {
- for(j = 0;j < 8;++j)
- {
-
-
- while(!dht);
- Delay40us();
-
- if(dht == 1)
- {
- flag = 1;
- while(dht);
- }
- else
- {
- flag = 0;
- }
- tmp = tmp << 1;
- tmp = flag | tmp;
-
- }
- Data[i] = tmp;
- }
- }
-
-
- void Put_Data()
- {
- sd[0] = 's';
- sd[1] = 'd';
- sd[2] = ':';
- sd[3] = Data[0] /10 + 0x30;
- sd[4] = Data[0] %10 + 0x30;
- sd[5] = '.';
- sd[6] = Data[1] /10 + 0x30;
- sd[7] = Data[1] %10 + 0x30;
- sd[8] = '\0';
-
- wd[0] = 'w';
- wd[1] = 'd';
- wd[2] = ':';
- wd[3] = Data[2] /10 + 0x30;
- wd[4] = Data[2] %10 + 0x30;
- wd[5] = '.';
- wd[6] = Data[3] /10 + 0x30;
- wd[7] = Data[3] %10 + 0x30;
- wd[8] = '\0';
- }
-
-
- void Delay1000ms() //@11.0592MHz
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 8;
- j = 1;
- k = 243;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
-
- void main()
- {
- Uart();
- Delay1000ms();
-
- LCD1602_Init();
-
-
-
- while(1)
- {
- Delay1000ms();
- Read_Dht();
- Put_Data();
-
- Delay1000ms();
- Delay1000ms();
-
- SendString(wd);
- SendString("\r\n");
- SendString(sd);
- SendString("\r\n");
-
- Data_Show(1,0,wd);
- Data_Show(2,0,sd);
-
-
-
- }
- }
-
- /*
- 代码太多,需要的可以加我qq:2652408527
- */
- #include <regx52.h>
- #include <intrins.h>
- #include "oled.h"
- #include "oled_ziku.h"
- #include "dht.h"
-
- sbit SDA = P0^0;
- sbit SCL = P0^1;
- sbit dht = P0^2;
-
- extern char Data[5];
- extern char sd[9];
- extern char wd[9];
-
-
-
- void main()
- {
-
-
- Oled_INIT();
-
- Oled_Write_Cmd(0x20);
- Oled_Write_Cmd(0x02);//选择页寻址
-
- Oled_Clear();//清屏
-
- while(1)
- {
-
- Oled_Show_Str(1,0,"Li zhen");
- Oled_Show_Str(2,0,"I LOVE YOU");
- Oled_Show_Str(2,80,"!");
-
-
- }
-
-
- }
- /*
- 部分代码,需要的可以加我QQ:2652408527
- */
-
- #include <regx52.h>
- #include <intrins.h>
- #include "oled.h"
- #include "oled_ziku.h"
- #include "dht.h"
-
- sbit SDA = P0^0;
- sbit SCL = P0^1;
- sbit dht = P0^2;
-
- extern char Data[5];
- extern char sd[9];
- extern char wd[9];
- char command[5];
-
-
- void UART_Init()
- {
- PCON = 0x00;
- SCON = 0x50;
- TMOD = 0x20;
- TH1 = 0xFD;
- TL1 = 0xFD;
- TR1 = 1;
- ES = 1;
- EA = 1;
- }
-
-
- void main()
- {
- UART_Init();
- Delay1000ms();
- Oled_INIT();
-
- Oled_Write_Cmd(0x20);
- Oled_Write_Cmd(0x02);//选择页寻址
-
- Oled_Clear();//清屏
-
-
- while(1)
- {
-
-
- Read_Dht();
-
- Put_Data();
-
-
-
- Oled_Show_Str(4,40,"Li jian hua");
-
- Delay1000ms();
-
- }
-
-
- }
-
-
- void zd() interrupt 4
- {
- static i = 0;
-
-
-
- if(RI == 1)
- {
- RI = 0;
- command[i] = SBUF;
- i++;
-
- if(command[0]=='o'&&command[1]=='p'&&command[2]=='e'&&command[3]=='n')
- {
- Oled_Show_Str(1,0,wd);
- Oled_Show_Str(2,0,sd);
- }
-
- if(command[0]=='c'&&command[1]=='l'&&command[2]=='o'&&command[3]=='s')
- {
- Oled_Show_Str(1,0," ");
- Oled_Show_Str(2,0," ");
- }
-
- }
-
- }
由于没有循迹模块,我直接写了一个可以上下左右的小车代码
- #include <REGX52.H>
- #include "dianji.h"
-
- void UART_Init()
- {
- PCON = 0x00;
- SCON = 0x50;
- TMOD = 0x20;
- TH1 = 0xFD;
- TL1 = 0xFD;
- TR1 = 1;
- ES = 1;
- EA = 1;
- }
-
- void zd() interrupt 4
- {
- if(RI == 1)
- {
- RI = 0;
-
- if(SBUF == 'a')
- {
- Dianji_Left1Ward_Init();
- Dianji_Left2Ward_Init();
- Dianji_Right1Ward_Init();
- Dianji_Right2Ward_Init();
-
- }
-
- if(SBUF == 'b')
- {
- Dianji_Left1Back_Init();
- Dianji_Left2Back_Init();
- Dianji_Right1Back_Init();
- Dianji_Right2Back_Init();
- }
-
- if(SBUF == 'e')
- {
- 7 Stop();
- }
- }
-
-
- }
总结
感谢各位的观看,需要其中代码的兄弟可以私聊我。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。