/**************************************************************************
文件名: main_p
芯片: STC8G2K16S2 LQFP48
晶振: IRC 11.0592M
作者: pdm
版本: V1.0
日期: 2021-05-11
**************************************************************************/
#include"stc8G.h"
#include <INTRINS.H>
#include <math.h> //Keil library
#include <stdio.h> //Keil library
#define uint unsigned int
#define uchar unsigned char
int *BGV;
#define bit3 P16
#define bit1 P17
#define bit2 P54
#define bit0 P52
#define k_m 0x08
#define k_up 0x04
#define k_down 0x02
#define k_on 0x01
#define k_zero 0x06
bit key_ok=0,f_screen=0;
bit key_up=0,count=0,boot_screen=0,save_flag=0;
uchar idata key_data=0;
uchar idata key_add=0;
uchar idata key_data_temp=0;
uchar idata key_t_temp=0;
uchar idata set_number_digital=0;
uchar idata time_action_temp;
uchar idata time_action_temp10;
uchar idata time_action_temp100,time_action_temp1000,num_b,num_c,num_d,k;
uint idata time_key_press=0;
//****************************************
// 定义51单片机端口
//****************************************
sbit SCL=P1^5; //IIC时钟引脚定义
sbit SDA=P1^4; //IIC数据引脚定义
//******角度参数************
#define Gx_offset -3.06
#define PI 3.14159
//float Gyro_y; //Y轴陀螺仪数据暂存
idata float Angle_gy; //由角速度计算的倾斜角度
//float Accel_x; //X轴加速度值暂存
idata float Angle_ax,Angle_az,Angle_ay; //由加速度计算的倾斜角度
idata float Angle,old_set; //小车最终倾斜角度
idata long Angle_temp=0,last_Angle=0; //小车最终倾斜角度
//uchar value; //角度正负极性标记
//******卡尔曼参数************
//float code Q_angle=0.001;
//float code Q_gyro=0.003;
//float code R_angle=0.5;
//float code dt=0.01; //dt为kalman滤波器采样时间;
//char code C_0 = 1;
//float xdata Q_bias, Angle_err;
//float xdata PCt_0, PCt_1, E;
//float xdata K_0, K_1, t_0, t_1;
//float xdata Pdot[4] ={0,0,0,0};
//float xdata PP[2][2] = { { 1, 0 },{ 0, 1 } };
//****************************************
// 定义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为读取
sbit LCD_EN=P0^3;
sbit SET_EN=P0^2;
sbit POWER_EN=P0^4;
sbit COM0=P1^2;
sbit COM1=P4^7;
sbit COM2=P1^1;
sbit COM3=P1^0;
//uchar add_sum=0;
idata uint vcc;
uchar LCD_buff[8];
uchar scan_index=0,scan_carton;//扫描索引
uchar code t_display[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,
0x7c,0x39,0x5e,0x79,0x71,0x00,0x5C,0x50,0x09,0x0f,0x39,0x08,0x0e,0x0d,0x0b,0x01,0x31,0x29,0x19,0x38}; //共阴
uchar DisplayBuf[7]={0,0,0,12,19,19,20}; //3位数字对应的显示暂存
idata int zero;
bit s_10,s_mu,jd_to_fen=0,l_v_set=1,erro_flag=0,l_v_flag=0,zhengfu_flag=0;
uchar time_second,time_minue,Ttotal=0;
void IapIdle()
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
IAP_ADDRL = 0;
}
char IapRead(int addr)
{
char dat;
IAP_CONTR = 0x80;
IAP_TPS = 12; //使能IAP
IAP_CMD = 1; //设置IAP读命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
dat = IAP_DATA; //读IAP数据
IapIdle(); //关闭IAP功能
return dat;
}
void IapProgram(int addr, char dat)
{
IAP_CONTR = 0x80;
IAP_TPS = 12; //使能IAP
IAP_CMD = 2; //设置IAP写命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_DATA = dat; //写IAP数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
IapIdle(); //关闭IAP功能
}
void IapErase(int addr)
{
IAP_CONTR = 0x80;
IAP_TPS = 12; //使能IAP
IAP_CMD = 3; //设置IAP擦除命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //
IapIdle(); //关闭IAP功能
}
void Delay1ms(uchar ms) //@6.000MHz
{
unsigned char i, j;
while(--ms)
{
WDT_CONTR |= 0x10; //清看门狗,否则系统复位
i = 8;
j = 200;
do
{
while (--j);
} while (--i);
}
}
void init_cpu(void)
{
// P4SW=0xff;
P0=0x14;
P1=0x00;
P2=0X00;
P3=0x00; /* 0001_0100 */
P4=0x00;
P5=0x04;
WDT_CONTR = 0x23; //使能看门狗,溢出时间约为0.5s
// WDT_CONTR = 0x24; //使能看门狗,溢出时间约为1s
// WDT_CONTR = 0x27; //使能看门狗,溢出时间约为8s
// EA=0;
/* -------------------------- */
IE=0x0a; /* EA,EWD,ET2,EBO,ET1,EX1,ET0,EX0 */
// IP=0x10; /* NC,PWD,PBO,PS,PT1,PX1,PT0,PX0 */
// IPH=0x08;
/* -------------------------- */
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x66; //设置定时初值
TH0 = 0xFC; //设置定时初值
ET0 = 1; //清除TF0标志
TR0 = 1; //定时器0开始计时
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x00; //设置定时初值 10ms
TH1 = 0xDC; //设置定时初值
ET1 = 1; //清除TF1标志
TR1 = 1; //定时器1开始计时
// AUXR |= 0x04; //定时器时钟1T模式
// T2L = 0x40; //设置定时初值
// T2H = 0xED; //设置定时初值
// AUXR |= 0x10; //定时器2开始计时
// IE2=ET2;
/* ---------configuration port----------------- */
P0M0=0xF8; /* 1111_1000 */
P0M1=0x07; /* 0000_0111 P0口推挽式输出*/
// P_SW2=0X80;P0PU=0X00;P_SW2=0X00;
P1M0=0x20; /* 0010_0000*/
P1M1=0x08; /* 0000_1000*/
// P1PU=0X10;
// P_SW2=0X80;P1PU=0X00;P_SW2=0X00;
P2M0=0x0F; /* 0000_1111 */ /* 0 向口 1 强上拉 0 高阻 1 输出 */
P2M1=0xF0; /* 1111_0000 */ /* 0 准双 0 推挽输出 1 仅为输入 1 开漏 */
// P_SW2=0X80;P2PU=0X00;P_SW2=0X00;
P3M0=0x80; /* 1000_0000 */
P3M1=0x7F; /* 0111_1111 */
// P_SW2=0X80;P3PU=0X03;P_SW2=0X00;
P4M0=0x1E; /* 0001_1110 */
P4M1=0x61; /* 0110_0001 */
// P_SW2=0X80;P4PU=0X01;P_SW2=0X00;
P5M0=0x08; /* 0000_1000 */
P5M1=0xe3; /* 1110_0011 */
// P_SW2=0X80;P5PU=0X14;P_SW2=0X00;
P0=0x14;
P1=0xF0;
P2=0X00;
P3=0x00; /* 0011_0000 */