基于51单片机的智能小车设计报告(51单片机之智能小车(避障、跟随、循迹))
目录
基本概述
硬件组成
功能
关键字
模块介绍
电机模块L9110S
循迹模块(TCRT5000传感器)
红外避障模块
测速模块
小车
移动小车(控制电机转动 ,使小车前进 、后退 、左转 、右转 )
遥控小车( 使用蓝牙模块 ,通过串口发送信息控制小车移动)
调速小车(利用PWM波对电机进行调速)
循迹小车 (利用循迹模块进行黑白色的检测)
跟随小车(利用红外避障模块完成跟随行为)
避障小车(利用超声波测距完成避障行为)
语音控制小车,循迹 、跟随 、避障三种功能切换
基本概述
硬件组成
电机模块L9110S 、循迹模块 、红外避障模块 、超声波模块 、测速模块、OLED屏 、蓝牙模块 、4G ,模块、语音模块SU-03T
功能
蓝牙控制小车 、WiFi控制小车 、4G控制小车、小车的避障 、跟随 、循迹
关键字
单片机中一般都有两块存储区域 ,ROM和RAM ,程序代码存储在ROM中 ,程序要用的变量存储在RAM中 。而“code ”的作用就是将其修饰过的变量存储在ROM中而非RAM 。 在单片机中 ,RAM空间都比较小 ,是比较宝贵的 ,当存放在RAM中的数据过多时 ,会导致编译不成功。
exturn:使用exturn关键字修饰的全局变量或函数 ,作用域不再局限本文件,其他文件同样能访问到这些变量或函数 ,跟static关键字恰恰相反 。 code:使用code关键字修饰的变量(一般是初始化后 ,值保持不变的变量)后会被存放到ROM区,从而节省RAM的空间 。模块介绍
电机模块L9110S
L0110S模块的A 、B分别控制着两个电机 ,如果需要控制四个电机 ,则需要两个L0110S模块
当B-1A为高电平,B-2A为低电平时 ,电机反转或正转 当B-1A为低电平 ,B-2A为高电平时 ,电机正转反转 当B-1A为低电平 ,B-2A为低电平时 ,电机不转 电机的正转和反转与跟电机的接线不同而不同 ,注意自己调试循迹模块(TCRT5000传感器)
当发射出的红外线没有被反射回来或被反射回来但强度不够大时 ,DO输出高电平 ,灯灭 。 黑色吸收红外线 ,DO输出高电平,灯亮 当发射出的红外线被反射回来或被反射回来且强度足够大 ,DO输出低电平 ,灯亮 。 白色反射红外线,DO输出低电平 ,灯亮 即黑色输出高电平 ,灯灭,白色输出低电平 ,灯亮红外避障模块
当发射出的红外线没有被反射回来或被反射回来但强度不够大时 ,DO输出高电平 ,灯灭 。没有障碍物 当发射出的红外线被反射回来 ,DO输出低电平 ,灯亮 。有障碍物 即有障碍物输出低电平 ,灯亮 ,没有障碍物输出高电平 ,灯灭测速模块
发射的红外线被物体遮挡时 ,输出高电平,发射的红外线没被物体遮挡时 ,输出低电平 有物体高电平 ,没物体低电平 当搭配小车测速盘,会形成下降沿(有遮挡高电平 ,没遮挡低电平)小车
移动小车(控制电机转动 ,使小车前进 、后退 、左转 、右转 )
#include "reg52.h" #include <intrins.h> sbit left_con1A = P1^1; sbit left_con2A = P1^2; sbit right_con1A = P1^3; sbit right_con2A = P1^4; void Delay2000ms() //@11.0592MHz { unsigned char i, j, k; _nop_(); i = 15; j = 2; k = 235; do { do { while (--k); } while (--j); } while (--i); } //两个电机反转,前进 void goForward() { left_con1A = 1; left_con2A = 0; right_con1A = 1; right_con2A = 0; } //两个电机正转 ,后退 void goBack() { left_con1A = 0; left_con2A = 1; right_con1A = 0; right_con2A = 1; } //两个电机不转 ,停止 void goStop() { left_con1A = 0; left_con2A = 0; right_con1A = 0; right_con2A = 0; } //左电机不转 ,右电机反转 ,左转 void goLeft() { left_con1A = 0; left_con2A = 0; right_con1A = 1; right_con2A = 0; } //左电机反转 ,右电机不转 ,右转 void goRight() { left_con1A = 1; left_con2A = 0; right_con1A = 0; right_con2A = 0; } void main() { while(1){ goForward(); Delay2000ms(); goBack(); Delay2000ms(); goLeft(); Delay2000ms(); goRight(); Delay2000ms(); goStop(); Delay2000ms(); } }遥控小车( 使用蓝牙模块 ,通过串口发送信息控制小车移动)
#include "reg52.h" #include <intrins.h> #include <string.h> sfr AUXR = 0x8E; sbit left_con1A = P1^1; sbit left_con2A = P1^2; sbit right_con1A = P1^3; sbit right_con2A = P1^4; sbit led1 = P3^7; char mybuf[24] ; 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 uartInit() { AUXR = 0x01; PCON &= 0x7F; //配置波特率正常 SCON = 0x50; //配置串口选择工作方式1,允许串口接收数据 //配置定时器1为8位自动重装模式 TMOD &= 0x0F; TMOD |= 0x20; //给定时器1,9600波特率初值 TH1 = 0xFD; //定时器1初值 TL1 = 0xFD; //定时器1重装值 ET1 = 0; //不允许定时器1产生中断 TR1 = 1; //开启定时器1 EA = 1; //开启总中断 ES = 1; //开启串口中断 } void sendByte(char mydata) { SBUF = mydata; //向串口发送一帧信息 while(!TI); //等待硬件置位 TI = 0; //TI软件清0 } void sendString(char *str) { while(*str != \0){ sendByte(*str); str++; } } //两个电机反转 ,前进 void goForward() { left_con1A = 1; left_con2A = 0; right_con1A = 1; right_con2A = 0; } //两个电机正转 ,后退 void goBack() { left_con1A = 0; left_con2A = 1; right_con1A = 0; right_con2A = 1; } //两个电机不转,停止 void goStop() { left_con1A = 0; left_con2A = 0; right_con1A = 0; right_con2A = 0; } //左电机不转 ,右电机反转 ,左转 void goLeft() { left_con1A = 0; left_con2A = 0; right_con1A = 1; right_con2A = 0; } //左电机反转,右电机不转 ,右转 void goRight() { left_con1A = 1; left_con2A = 0; right_con1A = 0; right_con2A = 0; } void main() { uartInit(); while(1){ sendString("jiangxiaoya\r\n"); //发送心跳包 ,确保串口通信没有中断 Delay1000ms(); } } void myUart() interrupt 4 { static int i = 0; char tmp; //接收数据后,RI硬件置位产生的中断 if(RI){ RI = 0; //RI软件清0 //获取从pc端接收到的数据 tmp = SBUF; if(tmp == f || tmp == b || tmp == l || tmp == r || tmp == s){ i = 0; } mybuf[i] = tmp; i++; //forward if(mybuf[0] == f && mybuf[1] == o){ goForward(); memset(mybuf,\0,24); } //forward if(mybuf[0] == b && mybuf[1] == a){ goBack(); memset(mybuf,\0,24); } //left if(mybuf[0] == l && mybuf[1] == e){ goLeft(); memset(mybuf,\0,24); } //right if(mybuf[0] == r && mybuf[1] == i){ goRight(); memset(mybuf,\0,24); } //stop if(mybuf[0] == s && mybuf[1] == t){ goStop(); memset(mybuf,\0,24); } if(i == 24){ i = 0; } } //发送数据后 ,TI硬件置位产生的中断 if(TI); }调速小车(利用PWM波对电机进行调速)
利用定时器0软件模拟PWM波控制小车左轮速度 ,定时器1软件模拟PWM波控制小车右轮速度 ,通过控制轮子的速度来达到前进 、停止 、左转 、右转 在20ms的过程中 ,部分时间让电机正转 ,剩下时间让电机停止不动就能改变电机获得的功率 ,从而改变电机速度 。 #include "reg52.h" #include <intrins.h> #include <string.h> sfr AUXR = 0x8E; sbit left_con1A = P1^1; sbit left_con2A = P1^2; sbit right_con1A = P1^3; sbit right_con2A = P1^4; sbit led1 = P3^7; char mybuf[24] ; char leftSpeed; char rightSpeed; int cntLeft = 0; int cntRight = 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 goLeftForward() { left_con1A = 1; left_con2A = 0; } //左电机不转 void goLeftStop() { left_con1A = 0; left_con2A = 0; } //右电机反转 void goRightForward() { right_con1A = 1; right_con2A = 0; } //右电机不转 void goRightStop() { right_con1A = 0; right_con2A = 0; } //前进 void goForward() { leftSpeed = 18; rightSpeed = 20; } //停止 void goStop() { leftSpeed = 0; rightSpeed = 0; } //左转 void goLeft() { leftSpeed = 10; rightSpeed = 20; } //右转 void goRight() { leftSpeed = 20; rightSpeed = 10; } void Timer0Init(void) //1毫秒@11.0592MHz { AUXR &= 0x7F; //定时器时钟12T模式 TMOD &= 0xF0; //设置定时器模式 TMOD |= 0x01; //设置定时器模式 //定时器初值为1ms TL0 = 0x66; TH0 = 0xFC; TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0 = 1; EA = 1; } void Timer1Init(void) //1毫秒@11.0592MHz { AUXR |= 0x40; //定时器时钟1T模式 TMOD &= 0x0F; //设置定时器模式 TMOD |= 0x10; //设置定时器模式 //定时器初值为1ms TL1 = 0xCD; TH1 = 0xD4; TF1 = 0; //清除TF1标志 TR1 = 1; //定时器1开始计时 ET1 = 1; EA = 1; } void main() { Timer0Init(); Timer1Init(); while(1){ Delay1000ms(); goForward(); Delay1000ms(); goLeft(); Delay1000ms(); goRight(); } } //定时器0的中断函数 void Time0Handler() interrupt 1 { cntLeft++; TL0 = 0x66; TH0 = 0xFC; if(cntLeft < leftSpeed) { goLeftForward(); }else{ goLeftStop(); } if(cntLeft == 20){ cntLeft = 0; } } void Time1Handler() interrupt 3 { cntRight++; TL1 = 0x66; TH1 = 0xFC; if(cntRight < rightSpeed) { goRightForward(); }else{ goRightStop(); } if(cntRight == 20){ cntRight = 0; } }循迹小车 (利用循迹模块进行黑白色的检测)
#include "reg52.h" #include <intrins.h> #include <string.h> sfr AUXR = 0x8E; sbit left_con1A = P1^1; sbit left_con2A = P1^2; sbit right_con1A = P1^3; sbit right_con2A = P1^4; sbit tracingLeft = P1^5; sbit tracingRight = P1^6; char leftSpeed; char rightSpeed; int cntLeft = 0; int cntRight = 0; //左电机反转 void goLeftForward() { left_con1A = 1; left_con2A = 0; } //左电机不转 void goLeftStop() { left_con1A = 0; left_con2A = 0; } //右电机反转 void goRightForward() { right_con1A = 1; right_con2A = 0; } //右电机不转 void goRightStop() { right_con1A = 0; right_con2A = 0; } //前进 void goForward() { leftSpeed = 17; rightSpeed = 20; } //停止 void goStop() { leftSpeed = 0; rightSpeed = 0; } //左转 void goLeft() { leftSpeed = 5; rightSpeed = 20; } //右转 void goRight() { leftSpeed = 20; rightSpeed = 5; } void Timer0Init(void) //1毫秒@11.0592MHz { AUXR &= 0x7F; //定时器时钟12T模式 TMOD &= 0xF0; //设置定时器模式 TMOD |= 0x01; //设置定时器模式 //定时器初值为1ms TL0 = 0x66; TH0 = 0xFC; TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0 = 1; EA = 1; } void Timer1Init(void) //1毫秒@11.0592MHz { AUXR |= 0x40; //定时器时钟1T模式 TMOD &= 0x0F; //设置定时器模式 TMOD |= 0x10; //设置定时器模式 //定时器初值为1ms TL1 = 0xCD; TH1 = 0xD4; TF1 = 0; //清除TF1标志 TR1 = 1; //定时器1开始计时 ET1 = 1; EA = 1; } void tracingMode() { if(tracingLeft == 0 && tracingRight == 0){ // goForward(); } if(tracingLeft == 0 && tracingRight == 1){ goRight(); } if(tracingLeft == 1 && tracingRight == 0){ goLeft(); } if(tracingLeft == 1 && tracingRight == 1){ goStop(); } } void main() { Timer0Init(); Timer1Init(); while(1){ tracingMode(); } } //定时器0的中断函数 void Time0Handler() interrupt 1 { cntLeft++; TL0 = 0x66; TH0 = 0xFC; if(cntLeft < leftSpeed) { goLeftForward(); }else{ goLeftStop(); } if(cntLeft == 20){ cntLeft = 0; } } void Time1Handler() interrupt 3 { cntRight++; TL1 = 0x66; TH1 = 0xFC; if(cntRight < rightSpeed) { goRightForward(); }else{ goRightStop(); } if(cntRight == 20){ cntRight = 0; } }跟随小车(利用红外避障模块完成跟随行为)
#include "reg52.h" #include <intrins.h> #include <string.h> sfr AUXR = 0x8E; sbit left_con1A = P1^1; sbit left_con2A = P1^2; sbit right_con1A = P1^3; sbit right_con2A = P1^4; sbit followLeft = P2^1; sbit followRight = P2^2; char leftSpeed; char rightSpeed; int cntLeft = 0; int cntRight = 0; //左电机反转 void goLeftForward() { left_con1A = 1; left_con2A = 0; } //左电机不转 void goLeftStop() { left_con1A = 0; left_con2A = 0; } //右电机反转 void goRightForward() { right_con1A = 1; right_con2A = 0; } //右电机不转 void goRightStop() { right_con1A = 0; right_con2A = 0; } //前进 void goForward() { leftSpeed = 17; rightSpeed = 20; } //停止 void goStop() { leftSpeed = 0; rightSpeed = 0; } //左转 void goLeft() { leftSpeed = 8; rightSpeed = 20; } //右转 void goRight() { leftSpeed = 20; rightSpeed = 10; } void Timer0Init(void) //1毫秒@11.0592MHz { AUXR &= 0x7F; //定时器时钟12T模式 TMOD &= 0xF0; //设置定时器模式 TMOD |= 0x01; //设置定时器模式 //定时器初值为1ms TL0 = 0x66; TH0 = 0xFC; TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0 = 1; EA = 1; } void Timer1Init(void) //1毫秒@11.0592MHz { AUXR |= 0x40; //定时器时钟1T模式 TMOD &= 0x0F; //设置定时器模式 TMOD |= 0x10; //设置定时器模式 //定时器初值为1ms TL1 = 0xCD; TH1 = 0xD4; TF1 = 0; //清除TF1标志 TR1 = 1; //定时器1开始计时 ET1 = 1; EA = 1; } void followMode() { if(followLeft == 0 && followRight == 0){ // goForward(); } if(followLeft == 0 && followRight == 1){ goRight(); } if(followLeft == 1 && followRight == 0){ goLeft(); } if(followLeft == 1 && followRight == 1){ goStop(); } } void main() { Timer0Init(); Timer1Init(); while(1){ followMode(); } } //定时器0的中断函数 void Time0Handler() interrupt 1 { cntLeft++; TL0 = 0x66; TH0 = 0xFC; if(cntLeft < leftSpeed) { goLeftForward(); }else{ goLeftStop(); } if(cntLeft == 20){ cntLeft = 0; } } void Time1Handler() interrupt 3 { cntRight++; TL1 = 0x66; TH1 = 0xFC; if(cntRight < rightSpeed) { goRightForward(); }else{ goRightStop(); } if(cntRight == 20){ cntRight = 0; } }避障小车(利用超声波测距完成避障行为)
利用定时器0软件模拟PWM波控制sg90舵机转动方向 利用定时器1和超声波不断测量前方距离 #include "reg52.h" #include <intrins.h> sbit left_con1A = P1^1; sbit left_con2A = P1^2; sbit right_con1A = P1^3; sbit right_con2A = P1^4; sbit Trig = P2^3; sbit Echo = P2^4; sbit sg90 = P2^5; int angle; int angleBack; int cnt = 0; void Delay100ms() //@11.0592MHz { unsigned char i, j; i = 180; j = 73; do { while (--j); } while (--i); } void Delay300ms() //@11.0592MHz { unsigned char i, j, k; _nop_(); i = 3; j = 26; k = 223; do { do { while (--k); } while (--j); } while (--i); } void Delay500ms() //@11.0592MHz { unsigned char i, j, k; _nop_(); i = 4; j = 129; k = 119; do { do { while (--k); } while (--j); } while (--i); } void Delay10us() //@11.0592MHz { unsigned char i; i = 2; while (--i); } //两个电机反转 ,前进 void goForward() { left_con1A = 1; left_con2A = 0; right_con1A = 1; right_con2A = 0; } //两个电机正转 ,后退 void goBack() { left_con1A = 0; left_con2A = 1; right_con1A = 0; right_con2A = 1; } //两个电机不转 ,停止 void goStop() { left_con1A = 0; left_con2A = 0; right_con1A = 0; right_con2A = 0; } //左电机不转,右电机反转 ,左转 void goLeft() { left_con1A = 0; left_con2A = 0; right_con1A = 1; right_con2A = 0; } //左电机反转 ,右电机不转,右转 void goRight() { left_con1A = 1; left_con2A = 0; right_con1A = 0; right_con2A = 0; } void timer0Init() { //设置定时器0为16为计时模式 TMOD &=0xF0; TMOD |=0x01; //设置定时器0定时时间为0.5ms TH0 = 0xFE; TL0 = 0x33; TR0 = 1; //定时器0开始计时 TF0 = 0; //不执行定时器0爆表时导致的中断 ET0 = 1; //定时器0中断开关 EA = 1; //总中断开关 } void timer1Init() { //设置定时器1为16为计时模式 TMOD &= 0x0F; TMOD |= 0x10; TH1 = 0x00; TL1 = 0x00; } void ultrasonicStart() { Trig = 0; Trig = 1; Delay10us(); Trig = 0; } double getDistance() { double time = 0; //定时器1清0 TH1 = 0x00; TL1 = 0x00; ultrasonicStart(); while(Echo == 0); //当Echo引脚从低电平跳到高电平时开启定时器1 TR1 = 1; while(Echo == 1); //当Echo引脚从高电平跳到低电平时关闭定时器1 TR1 = 0; time = (TH1*256 + TL1) * 1.085; //微秒 return (time * 0.017); } void sg90Left() { angle = 5; //180° if(angleBack != angle){ cnt = 0; } angleBack = angle; Delay100ms(); } void sg90Middle() { angle = 3; //90° if(angleBack != angle){ cnt = 0; } angleBack = angle; Delay100ms(); } void sg90Right() { angle = 1; //0° if(angleBack != angle){ cnt = 0; } angleBack = angle; Delay100ms(); } void main() { double leftDistance; double rightDistance; double middleDistance; timer0Init(); timer1Init(); sg90Middle(); Delay500ms(); while(1){ sg90Middle(); Delay300ms(); middleDistance = getDistance(); if(middleDistance > 35){ goForward(); }else{ goStop(); sg90Left(); Delay300ms(); leftDistance = getDistance(); sg90Middle(); Delay300ms(); sg90Right(); Delay300ms(); rightDistance = getDistance(); if(leftDistance < 15 && rightDistance < 15){ goBack(); Delay500ms(); goStop(); }else{ if(leftDistance > rightDistance){ goLeft(); Delay500ms(); goStop(); } if(rightDistance > leftDistance){ goRight(); Delay500ms(); goStop(); } } } } } //定时器0的中断函数 void Time0Handler() interrupt 1 { TH0 = 0xFE; TL0 = 0x33; cnt++; //控制占空比 if(cnt < angle){ sg90 = 1; }else{ sg90 = 0; } if(cnt == 40){ //每个周期为20ms cnt = 0; sg90 = 1; } }测速小车 ,使用OLED屏显示小车速度
轮子走一圈 ,经过一个周长,C = 2x3.14x半径= 3.14 x 直径(6.5cm) ,对应的转速码盘也转了一圈 码盘有20个格子 ,每经过一个格子 ,会遮挡(高电平)和不遮挡(低电平) ,即产生下降沿 ,一个下降沿就是走了 3.14 * 6.5 cm /20 = 1.0205CM 定时器可以设计成一秒 ,统计下降沿 ,一个下降沿就是1cm ,假设一秒有80脉冲 ,那么就是80cm/s #include "reg52.h" #include <intrins.h> #include <string.h> #include <stdio.h> sfr AUXR = 0x8E; sbit left_con1A = P1^1; sbit left_con2A = P1^2; sbit right_con1A = P1^3; sbit right_con2A = P1^4; sbit Tachometer = P3^2; //测速模块产生下降沿,让外部中断0产生中断 sbit scl = P2^6; sbit sda = P2^7; char mybuf[24]; int signal; unsigned int cnt; unsigned int speedCnt = 0; unsigned int speed; char speedMsg[24]; void Delay5us() //@11.0592MHz { } //两个电机反转 ,前进 void goForward() { left_con1A = 1; left_con2A = 0; right_con1A = 1; right_con2A = 0; } //两个电机正转 ,后退 void goBack() { left_con1A = 0; left_con2A = 1; right_con1A = 0; right_con2A = 1; } //两个电机不转,停止 void goStop() { left_con1A = 0; left_con2A = 0; right_con1A = 0; right_con2A = 0; } //左电机不转 ,右电机反转 ,左转 void goLeft() { left_con1A = 0; left_con2A = 0; right_con1A = 1; right_con2A = 0; } //左电机反转,右电机不转 ,右转 void goRight() { left_con1A = 1; left_con2A = 0; right_con1A = 0; right_con2A = 0; } //串口初始化 void uartInit() { AUXR = 0x01; PCON &= 0x7F; //配置波特率正常 SCON = 0x50; //配置串口选择工作方式1,允许串口接收数据 //配置定时器1为8位自动重装模式 TMOD &= 0x0F; TMOD |= 0x20; //给定时器1,9600波特率初值 TH1 = 0xFD; //定时器1初值 TL1 = 0xFD; //定时器1重装值 ET1 = 0; //不允许定时器1产生中断 TR1 = 1; //开启定时器1 EA = 1; //开启总中断 ES = 1; //开启串口中断 } //定时器0初始化 ,初值为1ms void Time0Init() { TMOD &=0xF0; TMOD |=0x01; //1ms TL0 = 0x66; TH0 = 0xFC; TR0 = 1; ET0 = 1; EA =1; } //外部中断0初始化 void int0Init() { EX0 = 1; EA = 1; IT0 = 1; //下降沿触发外部中断0 } //IIC起始信号 void IIC_start() { sda = 0; scl = 1; sda = 1; Delay5us(); sda = 0; Delay5us(); scl = 0; } //IIC终止信号 void IIC_stop() { scl = 0; sda = 0; scl = 1; Delay5us(); sda = 1; Delay5us(); sda = 0; } //IIC的ACK应答信号 char IIC_ack() { char flag; scl = 0; sda = 1; //在时钟脉冲9期间释放数据线 Delay5us(); //延时5微秒后 ,为读取sda数据做准备 scl = 1; Delay5us(); flag = sda; //读取数据线,0为应答 Delay5us(); scl = 0; Delay5us(); return flag; } //IIC发送一个字节 void IIC_sendByte(char myData) { int i; for ( i = 0; i < 8; i++){ //发生数据翻转 ,选择即将发送的是0还是1 scl = 0; sda = myData & 0x80; //获取需要发送字节的最高位到SDA Delay5us(); //数据建立时间 //开始发送数据 scl = 1; Delay5us(); //数据发送时间 scl = 0; //发送完毕拉低 ,等待下1bit数据的传输 Delay5us(); myData = myData << 1; } } //OLED写入一条指令 void oledWriteCmd(char writeCmd) { IIC_start(); IIC_sendByte(0x78); //选择一个OLED屏 ,写模式 IIC_ack(); IIC_sendByte(0x00); //写入命令 ,D/C位为0 IIC_ack(); IIC_sendByte(writeCmd); IIC_ack(); IIC_stop(); } //OLED写入一个数据 void oledWriteData(char writeData) { IIC_start(); IIC_sendByte(0x78); //选择一个OLED屏 ,写模式 IIC_ack(); IIC_sendByte(0x40); //写入命令 ,D/C位为0 IIC_ack(); IIC_sendByte(writeData); IIC_ack(); IIC_stop(); } //OLCD初始化 void oledInit() { oledWriteCmd(0xAE); oledWriteCmd(0x00); oledWriteCmd(0x10); oledWriteCmd(0x40); oledWriteCmd(0xB0); oledWriteCmd(0x81); oledWriteCmd(0xFF); oledWriteCmd(0xA1); oledWriteCmd(0xA6); oledWriteCmd(0xA8); oledWriteCmd(0x3F); oledWriteCmd(0xC8); oledWriteCmd(0xD3); oledWriteCmd(0x00); oledWriteCmd(0xD5); oledWriteCmd(0x80); oledWriteCmd(0xD8); oledWriteCmd(0x05); oledWriteCmd(0xD9); oledWriteCmd(0xF1); oledWriteCmd(0xDA); oledWriteCmd(0x12); oledWriteCmd(0xDB); oledWriteCmd(0x30); oledWriteCmd(0x8D); oledWriteCmd(0x14); oledWriteCmd(0xAF); } void olceClean() { int i,j; for(i=0;i<8;i++){ oledWriteCmd(0xB0 + i); //选择PAGE //选择PAGE的第0列开始显示 oledWriteCmd(0x00); oledWriteCmd(0x10); for(j = 0;j < 128; j++){ oledWriteData(0); //写入字符0 } } } //OLED的字符构造点阵 const unsigned char code oledFont[]= { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1 0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2 0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3 0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5 0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6 0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 7 0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8 0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9 0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10 0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14 0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30 0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33 0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34 0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35 0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38 0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40 0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41 0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42 0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43 0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44 0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45 0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47 0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49 0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50 0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51 0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!