找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4006|回复: 1
打印 上一主题 下一主题
收起左侧

stc89c52单片机+sg90舵机实现9°控制旋转程序 lcd1602显示

[复制链接]
跳转到指定楼层
楼主
自己做的第一个小实物
  
真的有点累 跟仿真还是有差距的  自己焊的开发板到处都是问题  给大家分享一下我自己东拼西凑的程序   备注我已经尽量写的详细了  程序都贴出来了
电路图不会画  所以提供不了  不过这个东西也没多复杂  程序上的端口我都备注了
//main.c
//头文件
#include <reg52.h>
#include "lcd1602.h"
#include "sg90.h"
#include "anjian.h"
//定义端口
//定义变量
//unsigned char code str1[]={"error!"};
unsigned char code str2[]={"SG90 control"};
unsigned char code str3[]={"program...."};
unsigned char code str4[]={"direction:"};
unsigned char code str7[]={"angle:90"};
//unsigned char code str5[]={"left "};
//unsigned char code str6[]={"right"};
void main()
{
LCDINIT(); //LCD初始化
WCLCD(0X01,0); //清屏  不检测忙
DISPLAYSTR(0,0,str2); //输出字符串
DISPLAYSTR(0,1,str3);
delay(3000);
WCLCD(0X01,0);
DISPLAYSTR(0,0,str4);
DISPLAYSTR(0,1,str7);
SG90INIT();//舵机驱动
while(1)
{
  if(count>=250)  count=0;//设置舵机脉冲时基 25ms
  anjian();//按键控制
}
}

//lcd1602.h
// lcd 1602驱动程序  
#ifndef __LCD1602_H__
#define __LCD1602_H__
//头文件
#include "delay.h"
//函数申明
void WDLCD(unsigned char WDLCD); //写数据
void WCLCD(unsigned char WCLCD,BUSYC); //写状态
unsigned char RSLCD(void); //读状态
void LCDINIT(void);//初始化
void DISPLAYCHAR(unsigned char X, unsigned char Y, unsigned char DData);//指定位置输出一个字符
void DISPLAYSTR(unsigned char X, unsigned char Y, unsigned char code *DData);//指定位置输出一串字符
//定义端口
#define LCD P1 //lcd1602 D0-D7端口
sbit LCD_E=P3^4;
sbit LCD_RS=P3^5;
sbit LCD_RW=P3^6;
//定义变量
unsigned char BUSY=0X80;//忙
//写数据
void WDLCD(unsigned char WDLCD)
{
RSLCD(); //检测忙
LCD= WDLCD;
LCD_RS = 1;
LCD_RW = 0;
LCD_E = 0; //若晶振速度太高可以在这后加小的延时
LCD_E = 0; //延时
LCD_E = 1;
}
//写指令
void WCLCD(unsigned char WCLCD,BUSYC) //BuysC为0时忽略忙检测
{
if (BUSYC) RSLCD(); //根据需要检测忙
LCD = WCLCD;
LCD_RS = 0;
LCD_RW = 0;
LCD_E = 0;
LCD_E = 0;
LCD_E = 1;
}
//读状态
unsigned char RSLCD(void)
{
LCD = 0xFF;
LCD_RS = 0;
LCD_RW = 1;
LCD_E = 0;
LCD_E = 0;
LCD_E = 1;
while (LCD & BUSY); //检测忙信号
return(LCD);
}
void LCDINIT(void) //LCD初始化
{
LCD = 0;
WCLCD(0x38,0); //工作方式设置 8位数据接口 两行显示 5*8点阵
delay(5);
WCLCD(0x38,0);
delay(5);
WCLCD(0x38,0);
delay(5);
WCLCD(0x38,1); //显示模式设置,开始要求每次检测忙信号
WCLCD(0x08,1); //显示关 光标不显示 光标不闪烁
WCLCD(0x01,1); //清屏
WCLCD(0x06,1); // 写入新数据后光标右移 显示不移动
WCLCD(0x0F,1); // 显示开 光标显示 光标闪烁
}
//按指定位置显示一个字符
void DISPLAYCHAR(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80;   //算出指令码
WCLCD(X, 1);  //发命令字
WDLCD(DData); //发数据
}
//按指定位置显示一串字符
void DISPLAYSTR(unsigned char X, unsigned char Y, unsigned char code *DData)
{
unsigned char ListLength;
    ListLength = 0;
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
while (DData[ListLength]>0x19) //若到达字串尾则退出
  {
   if (X <= 0xF) //X坐标应小于0xF
    {
     DISPLAYCHAR(X, Y, DData[ListLength]); //显示单个字符
     ListLength++;
     X++;
    }
  }
}
#endif

//sg90.h
//舵机驱动
#ifndef __SG90_H__
#define __SG90_H__
//端口
sbit SG_PWM=P2^6; //舵机脉冲输出端
//变量
unsigned char PWM_count=15;//pwm高电平时间   初始为1.5ms   舵机转动90°
unsigned int count=0;//延时中断计数

void SG90INIT()
{
    TMOD = 0x02;//定时器0 方式2
    TH0 = 0xa4;//100us定时
    TL0 = 0x0a4;
    EA = 1;//中断开启
    ET0 = 1;
    TR0 = 1;//开始计数
}
void timer0()interrupt 1  //100us 中断
{
  if(count<=PWM_count)//脉冲高电平时间
    {
      SG_PWM=1;
    }
    else //脉冲时基-高电平=低电平时间
    {
       SG_PWM=0;
    }
  count++;
}
#endif

//anjian.h
//按键驱动
#ifndef __ANJIAN_H__
#define __ANJIAN_H__
//字符串数组
unsigned char code str5[]={"left "};
unsigned char code str6[]={"right"};
unsigned char code ASCII[]={"0123456789"};
unsigned char num;//显示数字 变量
void anjian()
{
if((P2&0x03)!=0x03)//判断  P2^0 and P2^1是否有按键
    {
     delay(5); //延时
     if((P2&0x03)!=0x03)//再判断一次
     switch(P2&0x03)
     {
      case 0x02:   //P2^0按下
       PWM_count++; //高电平时间加100us
       DISPLAYSTR(0x0a,0,str5);//显示left
       if(PWM_count>=25)//高电平不会大于2.5ms 25*100us=2.5ms
       PWM_count=25;
       num=(PWM_count-5)*9; //计算舵机角度
       DISPLAYCHAR(0X06,1,ASCII[num/100]);
       DISPLAYCHAR(0X07,1,ASCII[num/10%10]);
       DISPLAYCHAR(0X08,1,ASCII[num%10]);//显示角度
      
       break;
      case 0x01: //P2^1按下
       PWM_count--;
       DISPLAYSTR(0x0a,0,str6);
       if(PWM_count<=5)
       PWM_count=5;
       num=(PWM_count-5)*9;
       DISPLAYCHAR(0X06,1,ASCII[num/100]);
       DISPLAYCHAR(0X07,1,ASCII[num/10%10]);
       DISPLAYCHAR(0X08,1,ASCII[num%10]);
          break;
      default: //两个键同时按下  跳出
       break;
     }
      do{delay(5);}
      while((P2&0x03)!=0x03); //判断是否松开按键
    }
}
#endif

//delay.h
//延时函数 毫秒级
#ifndef __DELAY_H__
#define __DELAY_H__
#define uint unsigned int
#define uchar unsigned char
void delay(uint count)
{
uint i;
uchar j,k;
for(i=0;i<count;i++)
for(j=0;j<88;j++)
for(k=0;k<2;k++);
}
#endif


全部程序51hei下载地址:
舵机控制.zip (20.18 KB, 下载次数: 83)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:766435 发表于 2020-6-2 13:15 | 只看该作者
这么好的帖子,顶起!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表