赞
踩
硬件方面选择的是51单片机,显示屏LCD1602,姿态传感器MPU6050的型号为维特智能的JY60,具体设计思路见笔者的文章基于单片机的云台姿态测量系统设计。
STM32将mpu6050的数据DAC并用LCD显示
基于单片机的云台姿态测量系统设计(一)
/*预处理命令*/ #include <reg52.h> //包含单片机寄存器的头文件 #include <string.h> #include <stdio.h> /*================================================= *自定义数据类型 =================================================*/ typedef unsigned char uchar; typedef unsigned int uint; #define LCD1602_DB P0 //LCD1602数据总线 sbit LCD1602_RS = P3^5; //RS端 sbit LCD1602_RW = P3^6; //RW端 sbit LCD1602_EN = P3^4; //EN端 sbit DU = P2^6;// sbit WE = P2^7;//数码管位选段选用于关闭数码管显示 unsigned char Re_buf[11],counter; unsigned char ucStra[6],ucStrw[6],ucStrAngle[6];
/*================================================= *函数名称:Read_Busy *函数功能:判断1602液晶忙,并等待 =================================================*/ void Read_Busy() { uchar busy; LCD1602_DB = 0xff;//复位数据总线 LCD1602_RS = 0; //拉低RS LCD1602_RW = 1; //拉高RW读 do { LCD1602_EN = 1;//使能EN busy = LCD1602_DB;//读回数据 LCD1602_EN = 0; //拉低使能以便于下一次产生上升沿 }while(busy & 0x80); //判断状态字BIT7位是否为1,为1则表示忙,程序等待 }
/*=================================================
*函数名称:LCD1602_Write_Cmd
*函数功能:写LCD1602命令
*调用:Read_Busy();
*输入:cmd:要写的命令
=================================================*/
void LCD1602_Write_Cmd(uchar cmd)
{
Read_Busy(); //判断忙,忙则等待
LCD1602_RS = 0;
LCD1602_RW = 0; //拉低RS、RW
LCD1602_DB = cmd;//写入命令
LCD1602_EN = 1; //拉高使能端 数据被传输到LCD1602内
LCD1602_EN = 0; //拉低使能以便于下一次产生上升沿
}
/*=================================================
*函数名称:LCD1602_Write_Dat
*函数功能:写LCD1602数据
*调用:Read_Busy();
*输入:dat:需要写入的数据
=================================================*/
void LCD1602_Write_Dat(uchar dat)
{
Read_Busy();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_EN = 1;
LCD1602_EN = 0;
}
/*================================================= *函数名称:LCD1602_Dis_Str *函数功能:在指定位置显示字符串 *调用:LCD1602_Write_Cmd(); LCD1602_Write_Dat(); *输入:x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行) *str:需要显示的字符串 =================================================*/ void LCD1602_Dis_Str(uchar x, uchar y, uchar *str) { if(y) x |= 0x40; x |= 0x80; LCD1602_Write_Cmd(x); while(*str != '\0') { LCD1602_Write_Dat(*str++); } }
/*=================================================
*函数名称:Init_LCD1602
*函数功能:1602初始化
*调用: LCD1602_Write_Cmd();
=================================================*/
void Init_LCD1602()
{
LCD1602_Write_Cmd(0x38); // 设置16*2显示,5*7点阵,8位数据接口
LCD1602_Write_Cmd(0x0c); //开显示
LCD1602_Write_Cmd(0x06); //读写一字节后地址指针加1
LCD1602_Write_Cmd(0x01); //清除显示
}
void main() { //中断初始化 float Value[3]; unsigned char i=0; char buffer[10]; TMOD=0x20; //用定时器工作在方式2设置串口波特率 9600 TH1=0xfd; TL1=0xfd; TR1=1; TI=1; REN=1; //串口初始化 SM0=0; //串口工作在方式2,使用默认的定时器来提供波特率 SM1=1; EA=1; //开启总中断 ES=1; Init_LCD1602();//1602初始化 while(1) { // 角度的显示 Value[0] = ((short)(ucStrAngle[1]<<8| ucStrAngle[0]))/32768.0*180; Value[1] = ((short)(ucStrAngle[3]<<8| ucStrAngle[2]))/32768.0*180; Value[2] = ((short)(ucStrAngle[5]<<8| ucStrAngle[4]))/32768.0*180; sprintf(buffer,"AX:%5.1f",Value[0]); LCD1602_Dis_Str(0, 0, &buffer); //显示字符串 sprintf(buffer,"AY:%5.1f",Value[1]); LCD1602_Dis_Str(8, 0, &buffer); //显示字符串 sprintf(buffer,"AZ:%5.1f",Value[2]); LCD1602_Dis_Str(0, 1, &buffer); //显示字符串 } } void ser() interrupt 4 { if (RI) { RI=0; Re_buf[counter]=SBUF; if(counter==0&&Re_buf[0]!=0x55) return; //第0号数据不是帧头,跳过 counter++; if(counter==11) //接收到11个数据 { counter=0; //重新赋值,准备下一帧数据的接收 switch(Re_buf [1]) { case 0x51: ucStra[0]=Re_buf[2]; ucStra[1]=Re_buf[3]; ucStra[2]=Re_buf[4]; ucStra[3]=Re_buf[5]; ucStra[4]=Re_buf[6]; ucStra[5]=Re_buf[7]; break; case 0x52: ucStrw[0]=Re_buf[2]; ucStrw[1]=Re_buf[3]; ucStrw[2]=Re_buf[4]; ucStrw[3]=Re_buf[5]; ucStrw[4]=Re_buf[6]; ucStrw[5]=Re_buf[7]; break; case 0x53: ucStrAngle[0]=Re_buf[2]; ucStrAngle[1]=Re_buf[3]; ucStrAngle[2]=Re_buf[4]; ucStrAngle[3]=Re_buf[5]; ucStrAngle[4]=Re_buf[6]; ucStrAngle[5]=Re_buf[7]; break; } } } }
需要注意的是笔者的波特率选择的是9600,若出现不能显示的情况有可能是波特率设置的问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。