为什么把51的12864的程序移植到STC15里就失灵了,就算是没改延时也应该显示出东西啊
如果STC15的速度比51快,而12864部分用延时代替查忙的话,应该就会无法显示了。
单片机速度快了,延时的时间就短了,不够了
还是没用,我把延时改了6倍,还是白屏。
请帮忙看一下代码,谢谢了
//#include <REG52.H>
#include "STC15.H"
#include <math.h> //Keil library
#include <stdio.h> //Keil library
#include <INTRINS.H>
//#include "STC15Fxxxx.H"
#define Busy 0x80
#define LCDdata P0
//typedef unsigned char uchar;
typedef unsigned short ushort;
//typedef unsigned int uint;
#define uint unsigned int
#define uchar unsigned char
uchar seg0[]="X:";
uchar seg1[]="Y:";
//uchar seg2[]="Z:";
//****************************************
// ?51?
//****************************************
//#define DataPort P0 //LCD1602?
sbit SCL=P1^0; //IIC?
sbit SDA=P1^1; //IIC?
/*sbit LCM_RS=P2^4; //LCD1602?
sbit LCM_RW=P2^5; //LCD1602?
sbit LCM_EN=P2^6; //LCD1602?
*/
sbit E=P2^7;
sbit RW=P2^6;
sbit RS=P2^5;
sbit RST=P2^3;
//****************************************
// ?MPU6050?
//****************************************
#define SMPLRT_div 0x19 //?,?:0x07(125Hz)
#define CONFIG 0x1A //?,?:0x06(5Hz)
#define GYRO_CONFIG 0x1B //?,?:0x18(?,2000deg/s)
#define ACCEL_CONFIG 0x1C //?,?:0x01(?,2G,5Hz)
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48
#define PWR_MGMT_1 0x6B //?,?:0x00(?)
#define WHO_AM_I 0x75 //IIC?(?0x68,?)
#define SlaveAddress 0xD0 //IIC?,+1?
//****************************************
//?
//****************************************
uchar dis[4]; //?(-511?512)?
int dis_data; //?
//int Temperature,Temp_h,Temp_l;
//?
//****************************************
//?
//****************************************
void delay(unsigned int xx); //?
//LCD?
//void InitLcd(); //?lcd1602
//void lcd_printf(uchar *s,int temp_data);
/*void WriteDataLCM(uchar dataW); //LCD?
void WriteCommandLCM(uchar CMD,uchar Attribc); //LCD?
void DisplayOneChar(uchar X,uchar Y,uchar DData); //?
void DisplayListChar(uchar X,uchar Y,uchar *DData,L);
//? */
//MPU6050?
void InitMPU6050(); //?MPU6050
void Delay5us();
void I2C_Start();
void I2C_Stop();
void I2C_SendACK(bit ack);
bit I2C_RecvACK();
void I2C_SendByte(uchar dat);
uchar I2C_RecvByte();
void I2C_ReadPage();
void I2C_WritePage();
void display_ACCEL_x();
void display_ACCEL_y();
void display_ACCEL_z();
uchar Single_ReadI2C(uchar REG_Address); //?I2C?
void Single_WriteI2C(uchar REG_Address,uchar REG_data);
//?I2C?
//****************************************
//?
//****************************************
void lcd_printf(uchar *s,int temp_data)
{
if(temp_data<0)
{
temp_data=-temp_data;
*s='-';
}
else *s=' ';
*++s =temp_data/100+0x30;
temp_data=temp_data%100; //?
*++s =temp_data/10+0x30;
temp_data=temp_data%10; //?
*++s =temp_data+0x30;
}
//****************************************
//?
//****************************************
void delay1(unsigned int k)
{
unsigned int i,j;
for(i=0;i<(6*k);i++)
{
for(j=0;j<121;j++);
}
}
//****************************************
//LCD1602?
//****************************************
void delay(uint xx) //?5ms
{
unsigned int yy;
yy=6*xx;
while(yy--);
}
void rdbf(void) //?
{
while(1)
{
RS=0;
RW=1;
E=0;
LCDdata=0xFF;
E=1;
if((LCDdata&Busy)==0)
break;
}
}
void wr_data(uchar wrdata) //?
{
rdbf();
RS=1;
RW=0;
E=1;
LCDdata=wrdata;
E=0;
}
void wr_cmd(uchar wrcmd,busyc) //?(?,?)
{
if(busyc)
rdbf(); //?BF=0?,?
RS=0;
RW=0;
E=1;
LCDdata=wrcmd;
E=0;
}
void display(uchar x,uchar y,uchar *seg) //x?,y?
{
uchar i;
uint t=0;
switch(x) //?
{
case 1: i=0x80; break;
//?
case 2: i=0x90; break;
//?
case 3: i=0x88; break;
//?
case 4: i=0x98; break;
//?
default : break;
}
i=i+y-1; //?
wr_cmd(i,1);
while(seg[t]!='\0')
{
wr_data(seg[t]);
//?
t++;
}
}
void lcd_init(void) //Lcd?
{
delay(5552);
RST=1;
RST=0;
RST=1;
wr_cmd(0x30,0);
delay(5552);
wr_cmd(0x30,0);
//2?,?(?)
delay(5552);
wr_cmd(0x0c,1);
//?,?
delay(5552);
wr_cmd(0x01,1);
//?
delay(5552);
delay(5552);
wr_cmd(0x06,1);
//?
delay(5552);
}
/*void InitLcd()
{
WriteCommandLCM(0x38,1);
WriteCommandLCM(0x08,1);
WriteCommandLCM(0x01,1);
WriteCommandLCM(0x06,1);
WriteCommandLCM(0x0c,1);
DisplayOneChar(0,0,'A');
DisplayOneChar(0,1,'G');
}*/
//****************************************
//LCD1602?
//****************************************
/*void WaitForEnable(void)
{
DataPort=0xff;
LCM_RS=0;LCM_RW=1;_nop_();
LCM_EN=1;_nop_();_nop_();
while(DataPort&0x80);
LCM_EN=0;
}
//****************************************
//LCD1602?
//****************************************
void WriteCommandLCM(uchar CMD,uchar Attribc)
{
if(Attribc)WaitForEnable();
LCM_RS=0;LCM_RW=0;_nop_();
DataPort=CMD;_nop_();
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}
//****************************************
//LCD1602?
//****************************************
void WriteDataLCM(uchar dataW)
{
WaitForEnable();
LCM_RS=1;LCM_RW=0;_nop_();
DataPort=dataW;_nop_();
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}
//****************************************
//LCD1602?
//****************************************
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
Y&=1;
X&=15;
if(Y)X|=0x40;
X|=0x80;
WriteCommandLCM(X,0);
WriteDataLCM(DData);
}
//****************************************
//LCD1602?
//****************************************
void DisplayListChar(uchar X,uchar Y,uchar *DData,L)
{
uchar ListLength=0;
Y&=0x1;
X&=0xF;
while(L--)
{
DisplayOneChar(X,Y,DData[ListLength]);
ListLength++;
X++;
}
} */
//**************************************
//?5?(STC90C52RC@12M)
//?,?
//?1T?MCU?,?
//**************************************
void Delay5us()
{
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
}
//**************************************
//I2C?
//**************************************
void I2C_Start()
{
SDA = 1; //?
SCL = 1; //?
Delay5us(); //?
SDA = 0; //?
Delay5us(); //?
SCL = 0; //?
}
//**************************************
//I2C?
//**************************************
void I2C_Stop()
{
SDA = 0; //?
SCL = 1; //?
Delay5us(); //?
SDA = 1; //?
Delay5us(); //?
}
//**************************************
//I2C?
//?:ack (0:ACK 1:NAK)
//**************************************
void I2C_SendACK(bit ack)
{
SDA = ack; //?
SCL = 1; //?
Delay5us(); //?
SCL = 0; //?
Delay5us(); //?
}
//**************************************
//I2C?
//**************************************
bit I2C_RecvACK()
{
SCL = 1; //?
Delay5us(); //?
CY = SDA; //?
SCL = 0; //?
Delay5us(); //?
return CY;
}
//**************************************
//?I2C?
//**************************************
void I2C_SendByte(uchar dat)
{
uchar i;
for (i=0; i<8; i++) //8?
{
dat <<= 1; //?
SDA = CY; //?
SCL = 1; //?
Delay5us(); //?
SCL = 0; //?
Delay5us(); //?
}
I2C_RecvACK();
}
//**************************************
//?I2C?
//**************************************
uchar I2C_RecvByte()
{
uchar i;
uchar dat = 0;
SDA = 1; //?,?,
for (i=0; i<8; i++) //8?
{
dat <<= 1;
SCL = 1; //?
Delay5us(); //?
dat |= SDA; //?
SCL = 0; //?
Delay5us(); //?
}
return dat;
}
//**************************************
//?I2C?
//**************************************
void Single_WriteI2C(uchar REG_Address,uchar REG_data)
{
I2C_Start(); //?
I2C_SendByte(SlaveAddress); //?+?
I2C_SendByte(REG_Address); //?,
I2C_SendByte(REG_data); //?,
I2C_Stop(); //?
}
//**************************************
//?I2C?
//**************************************
uchar Single_ReadI2C(uchar REG_Address)
{
uchar REG_data;
I2C_Start(); //?
I2C_SendByte(SlaveAddress); //?+?
I2C_SendByte(REG_Address); //?,?0?
I2C_Start(); //?
I2C_SendByte(SlaveAddress+1); //?+?
REG_data=I2C_RecvByte(); //?
I2C_SendACK(1); //?
I2C_Stop(); //?
return REG_data;
}
//**************************************
//?MPU6050
//**************************************
void InitMPU6050()
{
Single_WriteI2C(PWR_MGMT_1, 0x00);
//?
Single_WriteI2C(SMPLRT_div, 0x07);
Single_WriteI2C(CONFIG, 0x06);
Single_WriteI2C(GYRO_CONFIG, 0x18);
Single_WriteI2C(ACCEL_CONFIG, 0x01);
}
//**************************************
//?
//**************************************
int GetData(uchar REG_Address)
{
char H,L;
H=Single_ReadI2C(REG_Address);
L=Single_ReadI2C(REG_Address+1);
return (H<<8)+L; //?
}
//**************************************
//?1602?10?
//**************************************
void Display10BitData(int value,uchar x,uchar y)
{
value/=64; //?10?
lcd_printf(dis, value);
//?
display(x,y,dis);
//?,?,?,?
}
//**************************************
//?
//**************************************
/*void display_temp()
{
Temp_h=Single_ReadI2C(TEMP_OUT_H); //?
Temp_l=Single_ReadI2C(TEMP_OUT_L); //?
Temperature=Temp_h<<8|Temp_l; //?
Temperature = 35+ ((double) (Temperature + 13200)) / 280; // ?
lcd_printf(dis,Temperature); //?
DisplayListChar(11,1,dis,4); //?,?,?,?
} */
//*********************************************************
//?
//*********************************************************
void main()
{
P0M1 = 0; P0M0 = 0; //设置为准双向口
P1M1 = 0; P1M0 = 0; //设置为准双向口
P2M1 = 0; P2M0 = 0; //设置为准双向口
P3M1 = 0; P3M0 = 0; //设置为准双向口
P4M1 = 0; P4M0 = 0; //设置为准双向口
P5M1 = 0; P5M0 = 0; //设置为准双向口
P6M1 = 0; P6M0 = 0; //设置为准双向口
P7M1 = 0; P7M0 = 0; //设置为准双向口
delay1(500); //?
lcd_init(); //?
InitMPU6050();
//?MPU6050
delay1(150);
while(1)
{
Display10BitData(GetData(ACCEL_XOUT_H),1,2);
//?X?
Display10BitData(GetData(ACCEL_YOUT_H),2,2);
//?Y?
//Display10BitData(GetData(ACCEL_ZOUT_H),3,2);
//?Z?
Display10BitData(GetData(GYRO_XOUT_H),1,5);
//?X?
Display10BitData(GetData(GYRO_YOUT_H),2,5);
//?Y?
//Display10BitData(GetData(GYRO_ZOUT_H),3,5);
//?Z?
display(1,1,seg0);
display(2,1,seg1);
//display(3,1,seg2);
delay1(500);
}
}
由于STC15系列单片机比普通51速度快,原来程序中延时函数时间就短了,根据经验把原来延时函数的参数放大9倍即可。如原来delay(5)改为delay(45).要注意参数的数据类型,不要溢出了。
你想多了
我的也是一样,15W408AS的片子。貌似不是延迟的问题,我研究好长时间了。还会影响其他子程序的运行。目前还没有发现是什么问题。而且我用15F60S2测试也是一样的问题。如果是延时问题的话 直接分频应该就可以用了,但是没用。
你可以主函数内加一句CLK_div=0x04;试试,头文件需要改成 <STC15.h>。
而且这个子函数内的延迟对15单片机来说确实短了。
void WriteDataLCM(uchar dataW)
{
WaitForEnable();
LCM_RS=1;LCM_RW=0;_nop_();
DataPort=dataW;_nop_();
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}
对15来说这里2个NOP不够,51单片机12M晶振下1个nop是1US,就是1000ns,所以没问题。1602中E的信号周期是400ns最小。 15的理论上应该是一个NOP是1000/12ns,实际楼上的哥们已经说了 也就快了9倍,所以在加4个nop试试。 CMD和DAT都要加。
上KEIL仿真实测了一下 4个nop是360ns。 一起研究下看是什么原因。
刚才又研究测试了一下,用了8个nop,测试结果字符显示没有问题,但取模绘图就不行了,只有一半能显示出来。延时5ms,基本可以了。
程序已经调通了。测试STC15F2K60S2可用。写指令代码如下:
/*************************************************************
* @函数名称: Busy
* @参数: none
* @返回值: none
* @摘要: 忙检测*
*************************************************************/
bit lcd_busy()
{
bit result;
RS = 0;
RW = 1;
EN = 1;
delayNOP();
result = (bit)(P1&0x80);
EN = 0;
return(result);
}
/*************************************************************
* @函数名称: Write_Com
* @参数: command 命令字
* @返回值: none
* @摘要: 写命令字
*************************************************************/
void Write_Com(uint8_t command)
{
while(lcd_busy());
RS = 0; //数据
RW = 0;
EN = 0;
DataPort = command;
delay_1ms(5);
EN = 1;
delay_1ms(5);
EN = 0;
}
/*************************************************************
* @函数名称: Write_Data
* @参数: Data 命令字
* @返回值: none
* @摘要: 写字节数据
*************************************************************/
void Write_Data(uint8_t Data)
{
while(lcd_busy());
RS = 1; //数据
RW = 0;
EN = 0;
DataPort = Data;
delay_1ms(5);
EN = 1;
delay_1ms(5);
EN = 0;
}
之前显示不了 是因为把数据的函数直接拷到指令里边去了,该了Command,忘记改RS的值了。 我去,我找了几天愣是没发现啊,郁闷死我了。
写那么多nop,看着就晕,不会用for吗
这个就不用纠结了把....
信不信用for能减小程序空间
试了一下,看吧,如果是空间很小的单片机,这个是很有必要的
学习了,谢谢! 你这个界面是哪个上面的?
合泰单片机的HT-IDE3000
l小编,程序调通了吗?能不能发一份驱动代码