BTS7960 直流电机控制程序
/*************正转逻辑*****************/
LEN=1
REN=1
while()
{
LPWN=0
DELAY
LPWM=1
DELAY
}
/************反转逻辑******************/
LEN=1
REN=1
while()
{
RPWN=0
DELAY
RPWM=1
DELAY
}
/******************************/
/***2025 测试直流电机正反转past***/
/***2024 11 21板2025 4 16 *L908CODE4240**/
#include <REG52.H>
#include "intrins.h" //
#include "stdio.h"
#include <stdlib.h>
#define uint unsigned int
#define uchar unsigned char
sbit SCL=P1^1;
sbit SDA=P1^0;
sbit INTPUT1=P1^2; //电机A左行
sbit INTPUT2=P1^3; //电机A右行
sbit INTPUT3=P1^4; //电机B左行
sbit INTPUT4=P1^5; //电机B右行
sbit OUTPUT1=P3^0; //电机A左行
sbit OUTPUT2=P3^1; //电机A右行
sbit OUTPUT3=P3^2; //电机B左行
sbit OUTPUT4=P3^3; //电机B右行
sbit D1_ADD=P5^4; //
sbit D1_DEC=P1^6; //
sbit L1_PWM=P3^5; //
sbit L1_EN=P3^4; // 高电平使能 低电平关闭
sbit R1_PWM=P3^6; //
sbit R1_EN=P3^7; //
//sbit L1_PWM=P3^5; //
//sbit L1_EN=P3^3; // 高电平使能 低电平关闭
//sbit R1_PWM=P3^0; //
//sbit R1_EN=P3^1; //
bit MOTORARUN_L; //电机A左行启动标志 0关闭 1启动
bit MOTORARUN_R; //电机A右行启动标志 0关闭 1启动
uchar count = 0;
uchar aa;
uchar kcounter,kstatus; //按键计数标志 按键状态标志
uchar time1; //电机占空比
uchar timeA; //
#define high 1
#define low 0
#define uint unsigned int //
#define uchar unsigned char //
#define CMD_IDLE 0 //空闲模式
#define CMD_READ 1 //IAP字节读命令
#define CMD_PROGRAM 2 //IAP字节编程命令
#define CMD_ERASE 3 //IAP扇区擦除命令
#define ENABLE_IAP 0x82 //if SYSCLK<20MHz
#define IAP_ADDRESS 0x1600 //时间 EEPROM首地址
#define IAP_ADDRESS1 0x1800 //时间 EEPROM首地址
typedef unsigned char BYTE; //Catch_Up接上Catch_Dwon接下
typedef unsigned int WORD;
uchar code show1[]=
{
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,/*"0",0*/
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,/*"1",1*/
0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,/*"2",2*/
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,/*"3",3*/
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,/*"4",4*/
0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,/*"5",5*/
0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,/*"6",6*/
0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,/*"7",7*/
0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,/*"8",8*/
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,/*"9",9*/
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x1F,0x01,0x01,0x01,0x01,0x1F,0x00,/*"A",10*/
0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,/*"D",11*/
0x08,0xF8,0x00,0xF8,0x00,0xF8,0x08,0x00,0x00,0x03,0x3E,0x01,0x3E,0x03,0x00,0x00,/*"W",12*/
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,/*"O",13*/
0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,/*"N",14*/
};
uchar code show2[]=
{
0x08,0x08,0x08,0x08,0x88,0x78,0x0F,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,
0x20,0x10,0x48,0x46,0x41,0x41,0x41,0x41,0x7F,0x41,0x41,0x41,0x41,0x40,0x40,0x00,/*"左",0*/
0x08,0x08,0x08,0x08,0xC8,0x38,0x0F,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,
0x08,0x04,0x02,0x01,0xFF,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0xFF,0x00,0x00,0x00,/*"右",1*/
0x80,0x60,0xF8,0x07,0x00,0x04,0x74,0x54,0x55,0x56,0x54,0x54,0x74,0x04,0x00,0x00,
0x00,0x00,0xFF,0x00,0x03,0x01,0x05,0x45,0x85,0x7D,0x05,0x05,0x05,0x01,0x03,0x00,/*"停",2*/
0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0xFF,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,
0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,/*"止",3*/
0x00,0x00,0x00,0xFC,0x44,0x44,0x44,0x45,0x46,0x44,0x44,0x44,0x44,0x7C,0x00,0x00,
0x40,0x20,0x18,0x07,0x00,0xFC,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0xFC,0x00,0x00,/*"启",4*/
0x40,0x44,0xC4,0x44,0x44,0x44,0x40,0x10,0x10,0xFF,0x10,0x10,0x10,0xF0,0x00,0x00,
0x10,0x3C,0x13,0x10,0x14,0xB8,0x40,0x30,0x0E,0x01,0x40,0x80,0x40,0x3F,0x00,0x00,/*"动",5*/
0x00,0x04,0x84,0x84,0x94,0xE4,0x85,0x86,0x84,0xC4,0xB4,0x84,0x84,0x84,0x80,0x00,
0x80,0x60,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"产",6*/
0x20,0x20,0x20,0xBE,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xBE,0x20,0x20,0x20,0x00,
0x00,0x80,0x80,0xAF,0xAA,0xAA,0xAA,0xFF,0xAA,0xAA,0xAA,0xAF,0x80,0x80,0x00,0x00,/*"量",7*/
0x40,0x40,0x42,0xCC,0x00,0x80,0x88,0x88,0xFF,0x88,0x88,0xFF,0x88,0x88,0x80,0x00,
0x00,0x40,0x20,0x1F,0x20,0x40,0x50,0x4C,0x43,0x40,0x40,0x5F,0x40,0x40,0x40,0x00,/*"进",8*/
0x40,0x40,0x42,0xCC,0x00,0x00,0xFF,0x49,0x49,0xC9,0x49,0x49,0x7F,0x80,0x00,0x00,
0x00,0x40,0x20,0x1F,0x20,0x40,0x5F,0x48,0x44,0x40,0x41,0x42,0x45,0x58,0x40,0x00,/*"退",9*/
0x00,0x00,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x04,0xFC,0x00,0x00,0x00,
0x00,0x80,0x40,0x20,0x18,0x06,0x01,0x00,0x00,0x40,0x80,0x40,0x3F,0x00,0x00,0x00,/*"刀",10*/
0x00,0x10,0x88,0xC4,0x33,0x40,0x48,0x48,0x48,0x7F,0x48,0xC8,0x48,0x48,0x40,0x00,
0x02,0x01,0x00,0xFF,0x00,0x02,0x0A,0x32,0x02,0x42,0x82,0x7F,0x02,0x02,0x02,0x00,/*"待",11*/
0x10,0x10,0xD0,0xFF,0x90,0x10,0x00,0xFE,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,
0x04,0x03,0x00,0xFF,0x00,0x83,0x60,0x1F,0x00,0x00,0x00,0x3F,0x40,0x40,0x78,0x00,/*"机",12*/
};
/*************Pin Define***************/
void Initial_LY096BG30();
void Delay_50ms(uint Del_50ms);
void fill_picture(uchar fill_Data);
void IIC_Start();
void IIC_Stop();
void Write_IIC_Command(uchar IIC_Command);
void Write_IIC_Data(uchar IIC_Data);
bit Write_IIC_Byte(uchar IIC_Byte);
void dis_Value(uchar s);
/*---------------延时子程序----------------*/
void delay (uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<2;j++)
;
}
/**************Delay*******************************/
void Delay_50ms(uint Del_50ms) //
{
uint m;
for(;Del_50ms>0;Del_50ms--)
for(m=62450;m>0;m--);
}
/*************关所有输出*******************************/
void reset_io()
{
L1_PWM=1; //
L1_EN=1; //
R1_PWM=1; //
R1_EN=1; //
}
/*----关闭IAP----------------------------*/
void IapIdle()
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
IAP_ADDRL = 0;
}
/*-从ISP/IAP/EEPROM区域读取一字节-*/
BYTE IapReadByte(WORD addr)
{
BYTE dat; //数据缓冲区
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_READ; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
dat = IAP_DATA; //读ISP/IAP/EEPROM数据
IapIdle(); //关闭IAP功能
return dat; //返回
}
/*-写一字节数据到ISP/IAP/EEPROM区域-*/
void IapProgramByte(WORD addr, BYTE dat)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_PROGRAM; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_DATA = dat; //写ISP/IAP/EEPROM数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle();
}
/*---扇区擦除---------------*/
void IapEraseSector(WORD addr)
{
IAP_CONTR = ENABLE_IAP; //使能IAP val=IapReadByte(IAP_ADDRESS+1);
IAP_CMD = CMD_ERASE; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle();
}
/****************按键计数器状态寄存器归零*************/
void RstKey()
{
kcounter=0; //按键计数器归零
kstatus=0; //状态寄存器归零
}
/*****************按键低电平检测函数*****************/
void LowVoltKey(void) //按键计数器状态标志加一
{
kcounter++;
kstatus++;
delay(5); //延时
}
/*****************按键高电平检测函数*****************/
void HighVoltKey(void) //按键计数器加一 状态标志归零
{
kcounter++; //按键计数器加一
kstatus=0; //按键状态标志归零
delay(5); //延时
}
/*******************IIC Start******************/
void IIC_Start()
{
SCL=high;
//Delay_us(1);
SDA=high;
_nop_();
SDA=low;
_nop_();_nop_();
SCL=low;
}
/*************IIC Stop*************************/
void IIC_Stop()
{
SDA=low;
_nop_();
SCL=high;
_nop_();_nop_();
SDA=high;
}
/*****************IIC Write byte***************/
bit Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
bit Ack_Bit; //应答信号
for(i=0;i<8;i++)
{
if(IIC_Byte & 0x80) //1?0?
SDA=high;
else
SDA=low;
//Delay_us(1);
SCL=high;
_nop_();_nop_();
SCL=low;
//Delay_us(1);
IIC_Byte<<=1; //loop
}
SDA=high; //释放IIC SDA总线为主器件接收从器件产生应答信号
_nop_();_nop_();
SCL=high; //第9个时钟周期
_nop_();_nop_();
Ack_Bit=SDA; //读取应答信号
SCL=low;
return Ack_Bit;
}
/*************IIC Write Command*****************/
void Write_IIC_Command(unsigned char IIC_Command)
{
IIC_Start();
Write_IIC_Byte(0x78); //Slave address,SA0=0
Write_IIC_Byte(0x00); //write command
Write_IIC_Byte(IIC_Command);
IIC_Stop();
}
/****************IIC Write Data*****************/
void Write_IIC_Data(unsigned char IIC_Data)
{
IIC_Start();
Write_IIC_Byte(0x78);
Write_IIC_Byte(0x40); //write data
Write_IIC_Byte(IIC_Data);
IIC_Stop();
}
/***************设置参数显示******************/
void dis_Val1(uchar s)
{
uchar x,y;
uint i=0;
uchar A1,A2,A3;
A1=s/100;
A2=(s-A1*100)/10;
A3=s-A1*100-A2*10;
for(y=0;y<2;y++) //百位显示
{
Write_IIC_Command(0XB4+y); //纵向页
Write_IIC_Command(00); //横向离左部边缘开始的距离
Write_IIC_Command(0X10); //横向第四个字
for(x=0;x<8;x++) //横向像素
{
Write_IIC_Data(show1[x+y*8+A1*16]); //0--A字符表
}
for(x=0;x<8;x++) //横向像素
{
Write_IIC_Data(show1[x+y*8+A2*16]);
}
}
for(y=0;y<2;y++) //十位显示
{
Write_IIC_Command(0XB4+y); //纵向页
Write_IIC_Command(00); //横向离左部边缘开始的距离
Write_IIC_Command(0X11); //横向第五个字
for(x=0;x<8;x++) //横向像素
{
Write_IIC_Data(show1[x+y*8+A3*16]);
}
}
}
/***************设置参数显示******************/
void dis_Val2(uchar s)
{
uchar x,y;
uint i=0;
uchar A1,A2,A3;
A1=s/100;
A2=(s-A1*100)/10;
A3=s-A1*100-A2*10;
for(y=0;y<2;y++) //百位显示
{
Write_IIC_Command(0XB4+y); //纵向页
Write_IIC_Command(00); //横向离左部边缘开始的距离
Write_IIC_Command(0X14); //横向第四个字
for(x=0;x<8;x++) //横向像素
{
Write_IIC_Data(show1[x+y*8+A1*16]);//0--A字符表
}
for(x=0;x<8;x++) //横向像素
{
Write_IIC_Data(show1[x+y*8+A2*16]);
}
}
for(y=0;y<2;y++) //十位显示
{
Write_IIC_Command(0XB4+y); //纵向页
Write_IIC_Command(00); //横向离左部边缘开始的距离
Write_IIC_Command(0X115); //横向第五个字
for(x=0;x<8;x++) //横向像素
{
Write_IIC_Data(show1[x+y*8+A3*16]);
}
}
}
/***************定时器参数显示******************/
void dis_Val(uchar s)
{
uchar x,y;
uint i=0;
uchar A1,A2,A3;
A1=s/100;
A2=(s-A1*100)/10;
A3=s-A1*100-A2*10;
for(y=0;y<2;y++) //百位显示
{
Write_IIC_Command(0XB6+y); //纵向页
Write_IIC_Command(00); //横向离左部边缘开始的距离
Write_IIC_Command(0X12); //横向第四个字
for(x=0;x<8;x++) //横向像素
{
Write_IIC_Data(show1[x+y*8+A1*16]); //0--A字符表
}
for(x=0;x<8;x++) //横向像素
{
Write_IIC_Data(show1[x+y*8+A2*16]);
}
}
for(y=0;y<2;y++) //十位显示
{
Write_IIC_Command(0XB6+y); //纵向页
Write_IIC_Command(00); //横向离左部边缘开始的距离
Write_IIC_Command(0X13); //横向第五个字
for(x=0;x<8;x++) //横向像素
{
Write_IIC_Data(show1[x+y*8+A3*16]);
}
}
}
/***************设置参数显示******************/
void dis_Val4(uchar s)
{
uchar x,y;
uint i=0;
uchar A1,A2,A3;
A1=s/100;
A2=(s-A1*100)/10;
A3=s-A1*100-A2*10;
for(y=0;y<2;y++) //百位显示
{
Write_IIC_Command(0XB6+y); //纵向页
Write_IIC_Command(00); //横向离左部边缘开始的距离
Write_IIC_Command(0X15); //横向第四个字
for(x=0;x<8;x++) //横向像素
{
Write_IIC_Data(show1[x+y*8+A1*16]);//0--A字符表
}
for(x=0;x<8;x++) //横向像素
{
Write_IIC_Data(show1[x+y*8+A2*16]);
}
}
for(y=0;y<2;y++) //十位显示
{
Write_IIC_Command(0XB6+y); //纵向页
Write_IIC_Command(00); //横向离左部边缘开始的距离
Write_IIC_Command(0X16); //横向第五个字
for(x=0;x<8;x++) //横向像素
{
Write_IIC_Data(show1[x+y*8+A3*16]);
}
}
}
/********************picture**********************/
void cleardisp()
{
uchar x,y;
for(y=0;y<8;y++)
{
Write_IIC_Command(0xb0+y);
Write_IIC_Command(0x00);
Write_IIC_Command(0x10);
for(x=0;x<128;x++) //横向像素
{
Write_IIC_Data(0X00);
}
}
}
/***********************Initial code*********************/
void Initial_LY096BG30()
{
Write_IIC_Command(0xAE); //display off
Write_IIC_Command(0x20); //Set Memory Addressing Mode
Write_IIC_Command(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
Write_IIC_Command(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
Write_IIC_Command(0xc8); //Set COM Output Scan Direction
Write_IIC_Command(0x00); //---set low column address
Write_IIC_Command(0x10); //---set high column address
Write_IIC_Command(0x40); //--set start line address
Write_IIC_Command(0x81); //--set contrast control register
Write_IIC_Command(0x7f);
Write_IIC_Command(0xa1); //--set segment re-map 0 to 127
Write_IIC_Command(0xa6); //--set normal display
Write_IIC_Command(0xa8); //--set multiplex ratio(1 to 64)
Write_IIC_Command(0x3F); //
Write_IIC_Command(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
Write_IIC_Command(0xd3); //-set display offset
Write_IIC_Command(0x00); //-not offset
Write_IIC_Command(0xd5); //--set display clock divide ratio/oscillator frequency
Write_IIC_Command(0xf0); //--set divide ratio
Write_IIC_Command(0xd9); //--set pre-charge period
Write_IIC_Command(0x22); //
Write_IIC_Command(0xda); //--set com pins hardware configuration
Write_IIC_Command(0x12);
Write_IIC_Command(0xdb); //--set vcomh
Write_IIC_Command(0x20); //0x20,0.77xVcc
Write_IIC_Command(0x8d); //--set DC-DC enable
Write_IIC_Command(0x14); //
Write_IIC_Command(0xaf); //--turn on oled panel
}
/*-----------------------------------------*/
void red_eeprom(void)
{
time1=IapReadByte(IAP_ADDRESS); //十位
}
/***************************************/
void write_eeprom( )
{
IapEraseSector(IAP_ADDRESS); //扇区擦除
IapProgramByte(IAP_ADDRESS,time1); /**/
}
/********************显示待机**********************/
void Diswait()
{
uchar x,y;
uint Cnt=32;
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb6+y); //竖向第一行 待
Write_IIC_Command(0x00);
Write_IIC_Command(0x10); //横向第一个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*11]); //字符表第7个字
}
}
//
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb6+y); //竖向第一行 机
Write_IIC_Command(0x00);
Write_IIC_Command(0x11); //横向第二个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*12]);//字符表第8个字
}
}
}
/************电机一前进*****/
void LEFT_FORWARD()
{
uchar x,y;
uint Cnt=32;
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 左
Write_IIC_Command(0x00);
Write_IIC_Command(0x10); //横向第一个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*0]); //字符表第7个字
}
}
//
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 启
Write_IIC_Command(0x00);
Write_IIC_Command(0x11); //横向第二个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*8]);//字符表第8个字
}
}
//
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 动
Write_IIC_Command(0x00);
Write_IIC_Command(0x12); //横向第二个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*4]);//字符表第8个字
}
}
//
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 进
Write_IIC_Command(0x00);
Write_IIC_Command(0x13); //横向第二个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*5]);//字符表第8个字
}
}
}
/*************电机一后退****/
void LEFT_BACK()
{
uchar x,y;
uint Cnt=32;
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 左
Write_IIC_Command(0x00);
Write_IIC_Command(0x14); //横向第一个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*0]);//字符表第7个字
}
}
//
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 启
Write_IIC_Command(0x00);
Write_IIC_Command(0x15); //横向第二个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*9]); //字符表第8个字
}
}
//
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 动
Write_IIC_Command(0x00);
Write_IIC_Command(0x16); //横向第二个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*4]);//字符表第8个字
}
}
//
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 进
Write_IIC_Command(0x00);
Write_IIC_Command(0x17); //横向第二个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*5]);//字符表第8个字
}
}
}
/**************电机一左进停止***/
void Left_ForStop()
{
uchar x,y;
uint Cnt=32;
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 左
Write_IIC_Command(0x00);
Write_IIC_Command(0x10); //横向第一个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*0]); //字符表第7个字
}
}
//
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 进
Write_IIC_Command(0x00);
Write_IIC_Command(0x11); //横向第二个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*8]); //字符表第8个字
}
}
//
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 停
Write_IIC_Command(0x00);
Write_IIC_Command(0x12); //横向第二个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*2]);//字符表第8个字
}
}
//
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 止
Write_IIC_Command(0x00);
Write_IIC_Command(0x13); //横向第二个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*3]);//字符表第8个字
}
}
}
/**************电机一左退停止***/
void Left_BackStop()
{
uchar x,y;
uint Cnt=32;
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 左
Write_IIC_Command(0x00);
Write_IIC_Command(0x14); //横向第一个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*0]); //字符表第7个字
}
}
//
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 退
Write_IIC_Command(0x00);
Write_IIC_Command(0x15); //横向第二个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*9]); //字符表第8个字
}
}
//
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 停
Write_IIC_Command(0x00);
Write_IIC_Command(0x16); //横向第二个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*2]); //字符表第8个字
}
}
//
for(y=0;y<2;y++)
{
Write_IIC_Command(0xb0+y); //竖向第一行 止
Write_IIC_Command(0x00);
Write_IIC_Command(0x17); //横向第二个字
for(x=0;x<16;x++) //横向像素
{
Write_IIC_Data(show2[x+y*16+Cnt*3]); //字符表第8个字
}
}
}
/**************定时中断*************************/
void timer0() interrupt 1
{
aa++;
if(aa>=30) //指示灯计数30取反
{
OUTPUT4=~OUTPUT4;
aa=0;
}
if(MOTORARUN_L==1)
{
timeA++; //计数加
if(timeA<time1) //小于设置值
{
L1_PWM=0; //输出低电平
}
else if(timeA>time1&&timeA<99) //大于设置值小于MAX 99
{
L1_PWM=1; //输出高电平
timeA=0; //计数值归零
}
else if(timeA>99)
{
timeA=0; //计数值归零
}
}
else if(MOTORARUN_L==0)
{
L1_PWM=1;
// L1_EN=0;
}
if(MOTORARUN_R==1)
{
timeA++; //计数加
if(timeA<time1) //time=20
{
R1_PWM=0;
}
else if(timeA>time1&&timeA<99)
{
R1_PWM=1;
timeA=0;
}
else if(timeA>99)
{
R1_PWM=0;
timeA=0;
}
}
else if(MOTORARUN_R==0)
{
R1_PWM=1;
}
}
/**************TMOD***********************************/
/**| 定时器1 | | 定时器0 |**/
/***GATE C/T M1 M0 GATE C/T M1 M0 ***/
//M1 M0 00 13位定时器/计数器,兼容8048定时模式,TL1使用低五位,TH1使用全部八位
//M1 M0 01 16位定时器/计数器
//M1 M0 10 8位自动重载定时器,当溢出时将TH1的值自动载入TL1
//M1 M0 11 定时器1无效
//M1 M0 11 定时器0作为双八位定时器/计数器,TL0作为八位定时器/计数器,通过标准定时器0
//的控制位控制,TH0仅作为一个八位定时器,由定时器1 的控制位控制
/*************************************************/
void main( ) /*主程序开始*/
{
// P3M0=0XFF; //强推挽
// P3M1=0X00;
MOTORARUN_L=0; //电机A左使能关闭
MOTORARUN_R=0; //电机A右使能关闭
reset_io(); //
Initial_LY096BG30(); //初始化显示屏
Delay_50ms(2);
cleardisp(); //清除显示
Diswait(); //显示待机
Left_ForStop();
Left_BackStop(); //RIGHT
red_eeprom(); //
dis_Val1(time1); //
dis_Val2(time1); //
TMOD&=0xF0; //设置定时器模式
TL0=0x00; //设置定时初始值
TH0=0x28; //设置定时初始值
ET0=1;
TF0=1; //清除TF0标志
TR0=1; //定时器0开始计时
EA=1; //
while(1)
{
/***************电机一延时参数加*************/
dis_Val(aa);
dis_Val4(count);
RstKey(); //按键复位
for(;kcounter<5;) //按键循环5次
{
if(!D1_ADD) //按键低电平
{
LowVoltKey();
}
else if(~!D1_ADD) //按键高电平
{
HighVoltKey();
}
}
if(kstatus>=4) /*按键状态标志大于等于3为有效值*/
{ /*循环检测 */
time1++;
if(time1>99)
time1=0;
write_eeprom();
dis_Val1(time1);
}
/***************电机一延时参数减*************/
RstKey(); //按键复位
for(;kcounter<5;) //按键循环5次
{
if(!D1_DEC) //按键低电平
{
LowVoltKey();
}
else if(~!D1_DEC) //按键高电平
{
HighVoltKey();
}
}
if(kstatus>=4) /*按键状态标志大于等于3为有效值*/
{ /*循环检测 */
time1--;
if(time1<1)
time1=99;
write_eeprom();
dis_Val1(time1);
}
//电机一左进 开左使能 关右使能 0关 1开
RstKey();
if(MOTORARUN_L==0) //如果电机左进关闭状态
{
for(;kcounter<5;) //按键循环5次
{
if(!INTPUT1) //按键低电平
{
LowVoltKey(); //按键低电平 计数器加一状态标志加一
}
else if(~!INTPUT1) //按键高电平
{
HighVoltKey(); //按键计数器加一 状态标志归零
}
}
if(kstatus>=3) /*按键状态标志大于等于3为有效值*/
{
OUTPUT3=0;
MOTORARUN_L=1; //电机左运行标志
MOTORARUN_R=0; //电机右运行标志
L1_EN=1; //
LEFT_FORWARD(); //显示电机左进
}
}
//电机一左进停止 关左近使能 0关 1开
RstKey(); //高电平关电机左进
if(MOTORARUN_L==1) //如果电机左进开启状态
{
for(;kcounter<5;) //按键循环5次
{
if(~!INTPUT1) //按键高电平
{
LowVoltKey(); //按键低电平 计数器加一状态标志加一
}
else if(!INTPUT1) //按键低电平
{
HighVoltKey(); //按键计数器加一 状态标志归零
}
}
if(kstatus>=3) /*按键状态标志大于等于3为有效值*/
{
// L1_EN=0;
OUTPUT3=1;
MOTORARUN_L=0;
Left_ForStop(); //显示左进停止
}
}
//电机一左退 开右使能 关左使能 0关 1开
RstKey();
if(MOTORARUN_R==0) //如果电机左退关闭状态
{
for(;kcounter<5;) //按键循环5次
{
if(!INTPUT2) //按键低电平
{
LowVoltKey(); //按键低电平 计数器加一状态标志加一
}
else if(~!INTPUT2) //按键高电平
{
HighVoltKey(); //按键计数器加一 状态标志归零
}
}
if(kstatus>=3) /*按键状态标志大于等于3为有效值*/
{
OUTPUT2=0;
MOTORARUN_R=1; //电机右运行标志
MOTORARUN_L=0; //电机左运行标志
R1_EN=1;
LEFT_BACK(); //显示电机左退
}
}
//电机一左退停止 关右使能 0关 1开
RstKey(); //高电平关电机左退
if(MOTORARUN_R==1) //如果电机左退开启状态
{
for(;kcounter<5;) //按键循环5次
{
if(~!INTPUT2) //按键高电平
{
LowVoltKey(); //按键低电平 计数器加一状态标志加一
}
else if(!INTPUT2) //按键低电平
{
HighVoltKey(); //按键计数器加一 状态标志归零
}
}
if(kstatus>=3) /*按键状态标志大于等于3为有效值*/
{
// R1_EN=0;
OUTPUT2=1;
MOTORARUN_R=0;
Left_BackStop(); //显示左退停止
}
}
}
} //L908 CODE4240 12 17
/**********************************************
项目名称1路PWM频率0-200占空比0-100% 步进5
版本号2025.0128
基本参数
1.单片机型号:STC15W408AS 兼容15F
2.串口波特率:9600
3.串口校验位:none
4.串口停止位:1
5.地址 NO
6.IRC频率:12.000000MHz
目 录
一、宏定义区
二、函数声明区
三、IO定义区
四、变量声明区
五、主函数区
六、子函数区
七、所有初始化函数
八、所有中断函数
九、EEPROM擦写函数
***********************************************/
//==========================================================
// 一、宏定义区
//==========================================================
#include <STC15.H> //头文件
#include <intrins.h> //库函数文件
#define FOSC 12000000L //IRC频率
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
//==========================================================
// 二、函数声明区
//==========================================================
void UartInit(void); //9600bps@24MHz
void Timer0_Init(void); //25微秒@24MHz
void Timer2_Init(void); //100微秒@24MHz
void Init_IO(void); //IO初始化
void key_san(void); //按键扫描程序
void sedusart(u8 x); //串口发送测试void sedusart(10)
void delayms(u16 c); //1ms误差 0us
//==========================================================
// 三、IO定义区
//==========================================================
sbit S1 = P5^4; //按键频率加
sbit S2 = P1^6; //按键频率减
sbit S3 = P5^5; //按键占空比加
sbit S4 = P1^7; //按键占空比减
sbit PWM1 = P3^6; //输出1
sbit Led = P3^3; //LED
//===========================================================
// 四、变量声明区
//===========================================================
u8 data recive[10]; //声明数组,接收到的数据缓存
u8 data recive_1[10]; //声明数组,接收到的数据缓存
u8 data time; //软件计时,延时读取通讯数据
u8 data num; //通讯字节计数专用
u8 UART_FIG; //串口接收标志位
u16 Time_1US,F_Hz,CT,Step; //F_HZ=100倍(20000对应200HZ) CT=50(占空比50%) Step(步进数)
//===========================================================
// 五、主函数区
//===========================================================
main()
{
Init_IO(); //IO初始化
UartInit(); //串口初始化
F_Hz = 55; //初始值频率
CT = 50; //初始值占空比10%
Step = 5; //步进数
Timer2_Init(); //定时器2初始化
while(1)
{
key_san();
//静态数码管显示
// Pout1 = !Pout1;
}
}
//==========================================================
// 六、子函数区
//==========================================================
// 描述:控制函数
void key_san(void)
{
if(S1 == 0) //频率加
{
if(++Time_1US>20000) //
if(S1 == 0)
{
Time_1US = 0;
F_Hz = F_Hz/100; //缩小100倍
F_Hz = F_Hz + Step; //
if(F_Hz>=200) //
{
F_Hz=0; //
}
Timer2_Init();
Led = 0;
}
}
if(S2 == 0) //频率减
{
if(++Time_1US>20000) //
if(S2 == 0)
{
Time_1US = 0;
F_Hz = F_Hz/100; //缩小100倍
F_Hz = F_Hz - Step; //
if(F_Hz==0)
{
F_Hz=200;
}
Timer2_Init(); //
Led = 0;
}
}
if(S3 == 0) //占空比加
{
if(++Time_1US>20000) //
if(S3 == 0) //
{
Time_1US = 0; //
CT = CT + Step; //
if(CT>=100){CT=0;} //
// Timer2_Init();
Led = 0;
}
}
if(S4 == 0) //占空比减
{
if(++Time_1US>20000) //频率
if(S4 == 0)
{
Time_1US = 0; //F_HZ
CT = CT - Step; //占空比-步进数
if(CT==0){CT=100;} //占空比
// Timer2_Init();
Led = 0;
}
}
}
//=========================================================
// 七、所有初始化函数
//=========================================================
void UartInit(void) //9600bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xC7; //设置定时初始值
TH1 = 0xFE; //设置定时初始值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
ES = 1; //打开串口中断
EA = 1; //打开总中断
}
//=========================================================
// 定时器2初始化
//=========================================================
void Timer2_Init(void) //1000微秒@12.000MHz
{
AUXR |= 0x04; //定时器2为1T模式
F_Hz = F_Hz*100; //*100 总分频20000HZ
T2L = (65536-FOSC/2/F_Hz); //初始化计时值
T2H = (65536-FOSC/2/F_Hz) >> 8;
AUXR |= 0x10; //定时器2开始计时
// INT_CLKO = 0x04; //使能定时器2的时钟输出功能
IE2 |= 0x04; //开定时器2中断
EA = 1; //打开总中断
if(F_Hz == 0||F_Hz == 20000) //当频率值为0或200Hz关闭输出
{
IE2 &= ~0x04; //关闭中断
AUXR &= ~0x10; //定时器2停止计时
PWM1 = 0;
}
}
//=========================================================
// 初始化IO口函数
//=========================================================
void Init_IO(void) //IO初始化
{
P1M0 = 0x00;
P1M1 = 0x00;
P3M0 = 0x01;
P3M1 = 0x00;
S1 = S2 = S3 = S4 = 1;
PWM1 = 0;
Led = 1;
}
//=========================================================
// 八、所有中断函数
//=========================================================
// 描述:定时器0中断函数,1毫秒进入一次中断
void time0() interrupt 1 //定时器0中断程序
{
// u16 x;
//
// PWM2 = !PWM2;
// Led = !Led;
// x++;
// if(x>=10)
// {
//
// x = 0;
// }
// time--;
// if(time<=1)
// {
// num=0;
// }
}
//=========================================================
// 定时器2中断程序
//=========================================================
void t2int() interrupt 12 //定时器2中断程序,
{
u16 CT1,CT2; //CT占空比数0-100 CT2分频常数2 CT2为占空比计数器0-100
CT2++;
if(CT2>=2)
{
CT2 = 0;
CT1++;
if(CT1>=CT)
{
PWM1 = 0; //
}
else{PWM1 = 1;}
if(CT1>=100)
{
CT1 = 0;
}
}
}
//=========================================================
// 串口中断通信
//=========================================================
void exter0() interrupt 4 //串口中断通信
{
if(RI==1)
{
recive[num++]=SBUF;//接收一个字节
if(num>=2)
{
F_Hz = recive[0];
CT = recive[1];
// F_Hz = F_Hz*100;
// T2L = (65536-FOSC/2/F_Hz); //初始化计时值
// T2H = (65536-FOSC/2/F_Hz) >> 8;
Timer2_Init();
Led = 0;
num=0;
} //防止缓存数据超限
RI=0;
}
time=10; //数据延时读取时间
if(num>=2)
{
num=0;
}
}