51单片机笔记[7]-基于无线通信实现环境监测系统设计
实验目的
- 掌握电子系统设计的方法
- 学习无线通信的设计方法
实验内容
下位机
- 通过DS18B20或DHT11采集温湿度,并通过LCD1602显示
- 通过按键设置温度的上下限阙值,低于下限阙值时启动电机1档旋转,高于上限阙值时启动电机2档旋转
上位机
通过nRF24L01、蓝牙或者WIFI实现数据传输,并在上位机显示。(按照学号尾号后3位对3取余数,用相应方式传输。余数0:nRF24L01,余数1:蓝牙,余数2:WIFI
原理
nRF24L01
nRF24L01是由NORDIC出品的工作在2.4GHz~2.5GHz的ISM 频段的单片无线收发器芯片。无线收发器包括:频率发生器、增强型“SchockBurst”模式控制器、功率放大器、晶体振荡器、调制器和解调器。输出功率频道选择和协议的设置可以通过SPI 接口进行设置。几乎可以连接到各种单片机芯片,并完成无线数据传送工作。极低的电流消耗:当工作在发射模式下发射功率为0dBm 时电流消耗为11.3mA ,接收模式时为12.3mA,掉电模式和待机模式下电流消耗更低。
蓝牙、WIFI、蜂窝网络等一般工作在民用无线电频段:2.4GHz和5GHz;另外还有红外线和超声波通信。nRF就是工作在2.4GHz频段的一种通信方案,和蓝牙平级。
51单片机实现蓝牙通信
PZ-HC05 是一款高性能的主从一体蓝牙串口模块,可以同各种带蓝牙功能的 电脑、蓝牙主机、手机、 PDA、 PSP 等智能终端配对,该模块支持非常宽的波 特率范围:4800~1382400,并且兼容 5V 或 3.3V 单片机系统,可以很方便与您 的产品进行连接,使用非常灵活、方便。
PZ-HC05 蓝牙串口模块所有功能都是通过 AT 指令集控制, 这我们仅介绍 用户常用的几个 AT 指令:
模块的指令结构为: AT+
查看模块版本:AT+VERSION?\r\n
AT+ROLE=0 或 1,该指令来设置模块为从机或主机,并且可以通过 AT+ROLE? 来查看模块的主从状态
AT+CMODE=1,该指令设置模块可以对任意地址的蓝牙模块进行配对, 模块 默认设置为该参数。AT+CMODE=0, 该指令设置模块为指定地址配对,如果先设 置模块为任意地址,然后配对,接下去使用该指令,则模块会记忆最后一次配对 的地址,下次上电会一直搜索该地址的模块,直到搜索到为止。
AT+PSWD=
AT+NAME=
AT指令
AT指令是应用于终端设备与PC应用之间的连接与通信的指令。AT 即Attention。每个AT命令行中只能包含一条AT指令;对于AT指令的发送,除AT两个字符外,最多可以接收1056个字符的长度(包括最后的空字符)。
AT指令是以AT作首,字符结束的字符串,AT指令的响应数据包在 中。每个指令执行成功与否都有相应的返回。其他的一些非预期的信息(如有人拨号进来、线路无信号等),模块将有对应的一些信息提示,接收端可做相应的处理。
AT指令可应用于单片机与通信模块(HC-05,nRF24L01,ESP01S,LTE模组等)的通信.AT命令在通讯上有广泛的应用.
上位机、下位机
- 上位机
上位机是指可以直接发出操控命令的计算机,
一般是PC/host computer/master computer/upper computer,
屏幕上显示各种信号变化(液压,水位,温度等)。
- 下位机
下位机是直接控制设备获取设备状况的计算机,
一般是PLC/单片机single chip microcomputer/slave computer/lower computer之类的。
随机数生成
伪随机数
文件:test1.c
#include <stdio.h>
#include <reg52.h>
#include <stdlib.h>
void main(){
printf("%d",rand());
}
较为随机的数
读取定时器的值加上rand()的值。
int random=THX+rand();
实验内容
原理图
基于无线通信实现的环境监测系统 | 真机调试原理图 |
---|---|
![]() |
![]() |
流程图
总体流程 |
---|
代码
目录结构
├── App
│ ├── bluetooth
│ │ ├── bluetooth.c
│ │ └── bluetooth.h
│ ├── ds18b20
│ │ ├── ds18b20.c
│ │ └── ds18b20.h
│ ├── key
│ │ ├── key.c
│ │ └── key.h
│ ├── lcd1602
│ │ ├── lcd1602.c
│ │ └── lcd1602.h
│ ├── step_motor
│ │ ├── step_motor.c
│ │ └── step_motor.h
│ └── time
│ ├── time.c
│ └── time.h
├── Public
│ ├── public.c
│ ├── public.h
│ ├── uart.c
│ └── uart.h
├── main.c
文件:main.c
#include "Public\public.h"
#include "App\key\key.h"
#include "App\lcd1602\lcd1602.h"
#include "App\ds18b20\ds18b20.h"
#include "App\step_motor\step_motor.h"
#include "App\bluetooth\bluetooth.h"
#include "App\time\time.h"
uchar MAX_TEMP = 40;
uchar MIN_TEMP = 0;
uchar temperature;
//显示温度阙值
void show_max_temp(){
/*默认LCD1602已经初始化*/
//lcd1602_clear();
uchar tmp_char[10];
sprintf(tmp_char,"MAX:%d",MAX_TEMP);
lcd1602_show_string(1,1,tmp_char);
sprintf(tmp_char,"MIN:%d",MIN_TEMP);
lcd1602_show_string(2,1,tmp_char);
delay_ms(2000);
}
//温度数据处理
void temperture_datapros(u8 *tempbuf)
{
int temp_value;
temp_value=temperature*10;
if(temp_value<0)
{
temp_value=-temp_value;
tempbuf[0]='-';
}
else
tempbuf[0]=' ';
if(temp_value>=1000)
tempbuf[1]=temp_value/1000+0x30;
else
tempbuf[1]=' ';
tempbuf[2]=temp_value%1000/100+0x30;
tempbuf[3]=temp_value%1000%100/10+0x30;
tempbuf[4]='.';
tempbuf[5]=temp_value%1000%100%10+0x30;
tempbuf[6]='C';
tempbuf[7]='\0';
}
//DS18B20采集数据通过LCD1602显示
void collect_and_display(){
}
//按键扫描及设置温度阙值并显示
void key_scan_and_set(){
if(key_scan(1)==KEY1_PRESS){
MAX_TEMP++;
show_max_temp();
}
if(key_scan(1)==KEY2_PRESS){
MIN_TEMP--;
show_max_temp();
}
}
//电机响应温度
void motor_response_to_temperature(){
if(temperature>MAX_TEMP){
step_motor_28BYJ48(2);
}
if(temperature<MIN_TEMP){
step_motor_28BYJ48(1);
}
else{
step_motor_28BYJ48(0);
}
}
//蓝牙发送温度数据
void send_by_bluetooth(){
bluetooth_send_str(&temperature);
}
//主函数
void main()
{
ds18b20_init();
lcd1602_init();
show_max_temp();
time0_init();
while(1)
{
key_scan_and_set();
collect_and_display();
motor_response_to_temperature();
}
}
//定时取温度
void time0() interrupt 1{
static u8 cnt=0;
static u8 oneflag=1;
TH0=0xDC;
TL0=0x00;
cnt++;
if(cnt==50)
{
cnt=0;
//temperature=(unsigned char)ds18b20_read_temperture();
//temperature=30;
//uchar temp_char[10];
//temperture_datapros(temp_char);
lcd1602_clear();
lcd1602_show_string(1,1,"temperature");
//lcd1602_show_string(2,1,temp_char);
//bluetooth_send_str(temp_char);
}
}
Public文件夹
文件:public.h
#ifndef _public_H
#define _public_H
#include "reg52.h"
#include "stdio.h"
typedef unsigned int u16;
typedef unsigned char u8;
void delay_10us(u16 ten_us);
void delay_ms(u16 ms);
#endif
文件:public.c
#include "public.h"
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
void delay_ms(u16 ms)
{
u16 i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}
文件:uart.h
#ifndef _uart_H
#define _uart_H
#include "public.h"
#include "stdio.h"
#define UART_REC_LEN 10
extern u8 UART_RX_BUF[UART_REC_LEN];
extern u16 UART_RX_STA;
void UART_Init(void);
void UART_SendData(u8 dat);
void UART_SendString(u8 *pbuf);
#endif
文件:uart.c
#include "uart.h"
#define RELOAD_COUNT 0xFA //bpm:9600
void UART_Init(void)
{
SCON|=0X50;
TMOD|=0X20;
PCON=0X80;
TH1=RELOAD_COUNT;
TL1=TH1;
ES=0;
EA=1;
TR1=1;
// TI=1;
}
void UART_SendData(u8 dat)
{
ES=0;
TI=0;
SBUF=dat;
while(TI==0);
TI=0;
ES=1;
}
void UART_SendString(u8 *pbuf)
{
while(*pbuf!='\0')
{
UART_SendData(*pbuf);
delay_10us(5);
pbuf++;
}
}
u8 UART_RX_BUF[UART_REC_LEN];
u16 UART_RX_STA=0;
App文件夹
文件:key/key.h
#ifndef _key_H
#define _key_H
#include "Public\public.h"
sbit KEY1=P3^1;//上调温度阈值
sbit KEY2=P3^0;//下调温度阈值
sbit KEY3=P3^2;
sbit KEY4=P3^3;
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY_UNPRESS 0
u8 key_scan(u8 mode);
#endif
文件:key/key.c
#include "key.h"
u8 key_scan(u8 mode)
{
static u8 key=1;
if(mode)key=1;//����ɨ�谴��
if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))//���ⰴ������
{
delay_10us(1000);//����
key=0;
if(KEY1==0)
return KEY1_PRESS;
else if(KEY2==0)
return KEY2_PRESS;
else if(KEY3==0)
return KEY3_PRESS;
else if(KEY4==0)
return KEY4_PRESS;
}
else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1) //�ް�������
{
key=1;
}
return KEY_UNPRESS;
}
文件:bluetooth/bluetooth.h
#ifndef _bluetooth_H
#define _bluetooth_H
#include "Public\public.h"
void bluetooth_control_init(void);
void bluetooth_control(void);
extern void bluetooth_send_str(u8 *str);
#endif
文件:bluetooth/bluetooth.c
#include "bluetooth.h"
#include "Public\uart.h"
//����LED1�ܽ�
sbit LED1=P2^0;
//����������������
#define LED1_ON_CMD 0X11
#define LED1_OFF_CMD 0X10
void bluetooth_control_init(void)
{
UART_Init();
ES=1;
}
void bluetooth_control(void)
{
u16 i=0;
int temp_value;
u8 temp_buf[5];
u8 bluetooth_send_buf[7];
if(i%100==0)
{
bluetooth_send_buf[1]=temp_value/1000+0x30;
bluetooth_send_buf[2]=temp_value%1000/100+0x30;
bluetooth_send_buf[3]=temp_value%1000%100/10+0x30;
bluetooth_send_buf[4]='.';
bluetooth_send_buf[5]=temp_value%1000%100%10+0x30;
bluetooth_send_buf[6]='\0';
UART_SendString(bluetooth_send_buf);//ͨ�����ڷ����¶����ݵ�APP
}
}
//蓝牙发送字符串
void bluetooth_send_str(u8 *str){
UART_SendString(str);
}
//�����жϷ�����
//�����ֻ�APP���͵��źź���ư�����Դ
void UART_IRQn() interrupt 4
{
if(RI)
{
RI=0;
UART_RX_BUF[0]=SBUF;//��ȡ���յ�������
//��������
if(UART_RX_BUF[0]==LED1_ON_CMD)
LED1=0;
else if(UART_RX_BUF[0]==LED1_OFF_CMD)
LED1=1;
}
}
文件:step_motor/step_motor.h
#ifndef step_motor_H
#define step_motor_H
#include "Public\public.h"
extern void step_motor_28BYJ48_send_pulse(u8 step,u8 dir);
//0,1或2档循环旋转
extern void step_motor_28BYJ48(u8 level);
#endif
文件:step_motor/step_motor.c
#include "App\step_motor\step_motor.h"
#include "reg52.h"
sbit IN1_A=P1^0;
sbit IN2_B=P1^1;
sbit IN3_C=P1^2;
sbit IN4_D=P1^3;
#define STEPMOTOR_MAXSPEED 1
#define STEPMOTOR_MINSPEED 5
void step_motor_28BYJ48_send_pulse(u8 step,u8 dir)
{
u8 temp=step;
if(dir==0)
temp=7-step;
switch(temp)//8�����Ŀ��ƣ�A->AB->B->BC->C->CD->D->DA
{
case 0: IN1_A=1;IN2_B=0;IN3_C=0;IN4_D=0;break;
case 1: IN1_A=1;IN2_B=1;IN3_C=0;IN4_D=0;break;
case 2: IN1_A=0;IN2_B=1;IN3_C=0;IN4_D=0;break;
case 3: IN1_A=0;IN2_B=1;IN3_C=1;IN4_D=0;break;
case 4: IN1_A=0;IN2_B=0;IN3_C=1;IN4_D=0;break;
case 5: IN1_A=0;IN2_B=0;IN3_C=1;IN4_D=1;break;
case 6: IN1_A=0;IN2_B=0;IN3_C=0;IN4_D=1;break;
case 7: IN1_A=1;IN2_B=0;IN3_C=0;IN4_D=1;break;
default: IN1_A=0;IN2_B=0;IN3_C=0;IN4_D=0;break;
}
}
文件:time/time.h
#ifndef __TIME_H
#define __TIME_H
#include "Public\public.h"
void time0_init(void);
#endif
文件:time/time.c
#include "time.h"
void time0_init(void)
{
TMOD|=0X01;
TH0=0xDC;
TL0=0x00;//֨ʱ10ms
ET0=1;
EA=1;
TR0=1;
}
文件:ds18b20/ds18b20.h
#ifndef _ds18b20_H
#define _ds18b20_H
#include "Public\public.h"
sbit DS18B20_PORT=P3^7;
u8 ds18b20_init(void);
float ds18b20_read_temperture(void);
#endif
文件:ds18b20/ds18b20.c
#include "ds18b20.h"
#include "intrins.h"
/*******************************************************************************
* گ ˽ Ļ : ds18b20_reset
* گ˽٦Ŝ : شλDS18B20
* ˤ ɫ : Ϟ
* ˤ Զ : Ϟ
*******************************************************************************/
void ds18b20_reset(void)
{
DS18B20_PORT=0; //-֍DQ
delay_10us(75); //-֍750us
DS18B20_PORT=1; //DQ=1
delay_10us(2); //20US
}
/*******************************************************************************
* گ ˽ Ļ : ds18b20_check
* گ˽٦Ŝ : ݬӢDS18B20ˇرզ՚
* ˤ ɫ : Ϟ
* ˤ Զ : 1:δݬӢսDS18B20քզ՚ì0:զ՚
*******************************************************************************/
u8 ds18b20_check(void)
{
u8 time_temp=0;
while(DS18B20_PORT&&time_temp<20) //ֈսDQΪ֍֧ƽ
{
time_temp++;
delay_10us(1);
}
if(time_temp>=20)return 1; //ɧڻӬʱղǿ׆ܘ1
else time_temp=0;
while((!DS18B20_PORT)&&time_temp<20) //ֈսDQΪٟ֧ƽ
{
time_temp++;
delay_10us(1);
}
if(time_temp>=20)return 1; //ɧڻӬʱղǿ׆ܘ1
return 0;
}
/*******************************************************************************
* گ ˽ Ļ : ds18b20_read_bit
* گ˽٦Ŝ : ՓDS18B20ׁȡһٶλ
* ˤ ɫ : Ϟ
* ˤ Զ : 1/0
*******************************************************************************/
u8 ds18b20_read_bit(void)
{
u8 dat=0;
DS18B20_PORT=0;
_nop_();_nop_();
DS18B20_PORT=1;
_nop_();_nop_(); //كʱݤһŜڽӤìҘѫ՚15usŚׁȡ˽ߝ
if(DS18B20_PORT)dat=1; //ɧڻПʏΪ1ղ˽ߝdatΪ1ìرղΪ0
else dat=0;
delay_10us(5);
return dat;
}
/*******************************************************************************
* گ ˽ Ļ : ds18b20_read_byte
* گ˽٦Ŝ : ՓDS18B20ׁȡһٶؖޚ
* ˤ ɫ : Ϟ
* ˤ Զ : һٶؖޚ˽ߝ
*******************************************************************************/
u8 ds18b20_read_byte(void)
{
u8 i=0;
u8 dat=0;
u8 temp=0;
for(i=0;i<8;i++)//ѭ۷8ՎìÿՎׁȡһλìȒЈׁ֍λՙׁٟλ
{
temp=ds18b20_read_bit();
dat=(temp<<7)|(dat>>1);
}
return dat;
}
/*******************************************************************************
* گ ˽ Ļ : ds18b20_write_byte
* گ˽٦Ŝ : дһٶؖޚսDS18B20
* ˤ ɫ : datúҪдɫքؖޚ
* ˤ Զ : Ϟ
*******************************************************************************/
void ds18b20_write_byte(u8 dat)
{
u8 i=0;
u8 temp=0;
for(i=0;i<8;i++)//ѭ۷8ՎìÿՎдһλìȒЈд֍λՙдٟλ
{
temp=dat&0x01;//ѡձ֍λѸдɫ
dat>>=1;//ݫՎٟλӆս֍λ
if(temp)
{
DS18B20_PORT=0;
_nop_();_nop_();
DS18B20_PORT=1;
delay_10us(6);
}
else
{
DS18B20_PORT=0;
delay_10us(6);
DS18B20_PORT=1;
_nop_();_nop_();
}
}
}
/*******************************************************************************
* گ ˽ Ļ : ds18b20_start
* گ˽٦Ŝ : ߪʼςתۻ
* ˤ ɫ : Ϟ
* ˤ Զ : Ϟ
*******************************************************************************/
void ds18b20_start(void)
{
ds18b20_reset();//شλ
ds18b20_check();//ݬөDS18B20
ds18b20_write_byte(0xcc);//SKIP ROM
ds18b20_write_byte(0x44);//תۻļ®
}
/*******************************************************************************
* گ ˽ Ļ : ds18b20_init
* گ˽٦Ŝ : ԵʼۯDS18B20քIOࠚ DQ ͬʱݬӢDSքզ՚
* ˤ ɫ : Ϟ
* ˤ Զ : 1:һզ՚ì0:զ՚
*******************************************************************************/
u8 ds18b20_init(void)
{
ds18b20_reset();
return ds18b20_check();
}
/*******************************************************************************
* گ ˽ Ļ : ds18b20_read_temperture
* گ˽٦Ŝ : Փds18b20փսςֵ
* ˤ ɫ : Ϟ
* ˤ Զ : ς˽ߝ
*******************************************************************************/
float ds18b20_read_temperture(void)
{
float temp;
u8 dath=0;
u8 datl=0;
u16 value=0;
ds18b20_start();//ߪʼתۻ
ds18b20_reset();//شλ
ds18b20_check();
ds18b20_write_byte(0xcc);//SKIP ROM
ds18b20_write_byte(0xbe);//ׁզԢǷ
datl=ds18b20_read_byte();//֍ؖޚ
dath=ds18b20_read_byte();//ٟؖޚ
value=(dath<<8)+datl;//ۏҢΪ16λ˽ߝ
if((value&0xf800)==0xf800)//Ɛػۅλìغς
{
value=(~value)+1; //˽ߝȡ״ՙݓ1
temp=value*(-0.0625);//ԋӔޫ
}
else //ֽς
{
temp=value*0.0625;
}
return temp;
}
文件:lcd1602/lcd1602.h
#ifndef _lcd1602_H
#define _lcd1602_H
#include "Public\public.h"
#define LCD1602_4OR8_DATA_INTERFACE 0
sbit LCD1602_RS=P2^6;
sbit LCD1602_RW=P2^5;
sbit LCD1602_E=P2^7;
#define LCD1602_DATAPORT P0
extern void lcd1602_init(void);
extern void lcd1602_clear(void);
extern void lcd1602_show_string(u8 x,u8 y,u8 *str);
#endif
文件:lcd1602/lcd1602.c
#include "lcd1602.h"
#if (LCD1602_4OR8_DATA_INTERFACE==0)//8λLCD
void lcd1602_write_cmd(u8 cmd)
{
LCD1602_RS=0;
LCD1602_RW=0;
LCD1602_E=0;
LCD1602_DATAPORT=cmd;
delay_ms(1);
LCD1602_E=1;
delay_ms(1);
LCD1602_E=0;
}
#else //4λLCD
void lcd1602_write_cmd(u8 cmd)
{
LCD1602_RS=0;
LCD1602_RW=0;
LCD1602_E=0;
LCD1602_DATAPORT=cmd;
delay_ms(1);
LCD1602_E=1;
delay_ms(1);
LCD1602_E=0;
LCD1602_DATAPORT=cmd<<4;
delay_ms(1);
LCD1602_E=1;
delay_ms(1);
LCD1602_E=0;
}
#endif
#if (LCD1602_4OR8_DATA_INTERFACE==0)//8λLCD
void lcd1602_write_data(u8 dat)
{
LCD1602_RS=1;
LCD1602_RW=0;
LCD1602_E=0;
LCD1602_DATAPORT=dat;
delay_ms(1);
LCD1602_E=1;
delay_ms(1);
LCD1602_E=0;
}
#else
void lcd1602_write_data(u8 dat)
{
LCD1602_RS=1;//ѡձ˽ߝ
LCD1602_RW=0;//ѡձд
LCD1602_E=0;
LCD1602_DATAPORT=dat;//Ѹ˽ߝ
delay_ms(1);
LCD1602_E=1;//ʹŜޅEЈʏʽҘдɫ
delay_ms(1);
LCD1602_E=0;//ʹŜޅE۳غҤΪԉдɫ
LCD1602_DATAPORT=dat<<4;//Ѹ˽ߝ
delay_ms(1);
LCD1602_E=1;//ʹŜޅEЈʏʽҘдɫ
delay_ms(1);
LCD1602_E=0;//ʹŜޅE۳غҤΪԉдɫ
}
#endif
/*******************************************************************************
* گ ˽ Ļ : lcd1602_init
* گ˽٦Ŝ : LCD1602Եʼۯ
* ˤ ɫ : Ϟ
* ˤ Զ : Ϟ
*******************************************************************************/
#if (LCD1602_4OR8_DATA_INTERFACE==0)//8λLCD
void lcd1602_init(void)
{
lcd1602_write_cmd(0x38);//˽ߝП8λìДʾ2ѐì5*7ֳ֣/ؖػ
lcd1602_write_cmd(0x0c);//Дʾ٦ŜߪìϞڢҪìڢҪʁ˸
lcd1602_write_cmd(0x06);//дɫт˽ߝ۳ڢҪԒӆìДʾǁһӆ֯
lcd1602_write_cmd(0x01);//ȥǁ
}
#else
void lcd1602_init(void)
{
lcd1602_write_cmd(0x28);//˽ߝП4λìДʾ2ѐì5*7ֳ֣/ؖػ
lcd1602_write_cmd(0x0c);//Дʾ٦ŜߪìϞڢҪìڢҪʁ˸
lcd1602_write_cmd(0x06);//дɫт˽ߝ۳ڢҪԒӆìДʾǁһӆ֯
lcd1602_write_cmd(0x01);//ȥǁ
}
#endif
/*******************************************************************************
* گ ˽ Ļ : lcd1602_clear
* گ˽٦Ŝ : LCD1602ȥǁ
* ˤ ɫ : Ϟ
* ˤ Զ : Ϟ
*******************************************************************************/
void lcd1602_clear(void)
{
lcd1602_write_cmd(0x01);
}
/*******************************************************************************
* گ ˽ Ļ : lcd1602_show_string
* گ˽٦Ŝ : LCD1602Дʾؖػ
* ˤ ɫ : x,yúДʾظҪìx=0~15ìy=0~1;
strúДʾؖػԮ
* ˤ Զ : Ϟ
*******************************************************************************/
void lcd1602_show_string(u8 x,u8 y,u8 *str)
{
u8 i=0;
if(y>1||x>15)return;//ѐӎ˽һהղǿ׆Զ
if(y<1) //֚1ѐДʾ
{
while(*str!='\0')//ؖػԮˇӔ'\0'ޡβìֻҪǰĦԐŚɝߍДʾ
{
if(i<16-x)//ɧڻؖػӤӬڽ֚һѐДʾΧìղ՚֚ѐѸДʾ
{
lcd1602_write_cmd(0x80+i+x);//֚һѐДʾַ֘ʨ׃
}
else
{
lcd1602_write_cmd(0x40+0x80+i+x-16);//֚ѐДʾַ֘ʨ׃
}
lcd1602_write_data(*str);//ДʾŚɝ
str++;//ָ֫֝ն
i++;
}
}
else //֚2ѐДʾ
{
while(*str!='\0')
{
if(i<16-x) //ɧڻؖػӤӬڽ֚ѐДʾΧìղ՚֚һѐѸДʾ
{
lcd1602_write_cmd(0x80+0x40+i+x);
}
else
{
lcd1602_write_cmd(0x80+i+x-16);
}
lcd1602_write_data(*str);
str++;
i++;
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
2021-09-10 QS27及SZ-J2辉光管资料
2021-09-10 下载安卓源码手记(mac)