程序是根据STC的datasheet改的如下:
头文件:
/*
签名 :刘伟
日期 :20070530
功能描述:宏声明
其它功能:
版本 :
*/
#ifndef __SENSOR_MACRO_H__
#define __SENSOR_MACRO_H__
/*----------------------传感器选择-------------------------*/
#define sensor_presure 00
// #define DEBUG
/*-----------------------UART协议命令----------------------*/
#define NORMAL 0
#define READ 1
#define READ_CAN_SEND 2
#define SAMPLING_PRESS 3
#define READ_CAN_RECEIVE 4
#define CHANGE_ADDR 5
#define TX_STATUS 6
#define CAN_LOOP 7 //CAN回环测试模式
#define REPEAT 8
#define FLASH_USED 10
// #define GET 2
// #define TWO_BYTE 2
/*---------------------------------------------------------*/
#define ADC_DATA_LENGTH 8 //adc数据长度暂取6位
/*-----------------------本机位号--------------------------*/
// #define IP_ADDRESS 1
#define DIGIT 256 //累加位数
#define FST_TIMES 16
/*-----------------------定时器----------------------------*/
// #define #00111101B 0x3d
#define WDT (WDT_CONTR= 0x3d)
/*允许WDT,WDT开始计数,看门狗始终计数,预分频64,
溢出时间=12*预分频*32768/时钟频率,12MHz下为1.25ms*/
#define SHUTDOWN_WDT (WDT_CONTR=0x1d) //关闭看门狗,重新计数其它不变
/* TIMER0开始*/
#define T0_START (TR0 = 1)
/*TIMER0关闭*/
#define T0_SHUT (TR0 = 0)
/*TIMER1开始*/
#define T1_START (TR1 = 1)
/*TIMER1关闭*/
#define T1_SHUT (TR1 = 0)
/*--------------------USART-------------------------------*/
// #define uart_oe P1_7
#define CS P1_1 //SPI片选
#define CLK P1_7
#define MISO P1_6
#define MOSI P1_5
#define UART_MODE_0 0 //MODE 0 ,同步移位模式 baud=fosc/12
#define UART_MODE_1 0X40 //MODE 1 ,10BIT 异步收发
#define UART_MODE_2 0X80 //MODE 2 ,11BIT baud = fosc/32 or fosc/64
#define UART_MODE_3 0XC0 //MODE 3 ,11BIT
//--------------------------
#define UART_TIIF_CLR (TI = 0)
#define UART_RIIF_CLR (RI = 0)
#define setup_uart(x) (SCON = (x))
#define ENABLE_UART_RCV (REN = 1)
#define DISABLE_UART_RCV (REN = 0)
#define UART_RATE_MUL (PCON |= 0X80) //baudrate *2
#define UART_RATE_NOR (PCON &= 0X7F)
#define READ_UART() SBUF //读缓冲
#define WRITE_UART(x) (SBUF = (x)) //写缓冲
/*-------ADC应先打开电源->引脚开漏->设置速度->设置通道->延时1ms->启动A/D------------*/
#define ADC_Chanel_0_Result 0x30 //0通道A/D转换结果
#define ADC_Chanel_1_Result 0x31
#define ADC_Chanel_2_Result 0x32
#define AD_CH0 0
#define AD_CH1 1
#define AD_CH2 2
#define AD_CH3 3
#define AD_CH4 4
#define AD_CH5 5
#define AD_CH6 6
#define AD_CH7 7
#define AD_SPEED1 0
#define AD_SPEED2 1
#define AD_SPEED3 2
#define AD_SPEED4 3 //最高速
#define set_adc_ch(x) (ADC_CONTR &= 0XF8) ;(ADC_CONTR |= (x)) //ad通道选择选择P1口
#define ADCIF_CLR (ADC_CONTR &= 0XEF) //AD标志清零
#define set_adc_speed(x) (ADC_CONTR &= 0X9F); (ADC_CONTR |= (x)) //ad转换速度
#define ADC_START (ADC_CONTR |= 0X08) //启动AD。在结束前最好不要改变任何IO状态以提高精度
#define ADC_POWER_ON (ADC_CONTR |= 0X80) //打开adc电源。ad启动前一定要打开
#define ADC_POWER_OFF (ADC_CONTR &= 0X7F) //ad转换结束后可以关闭以节电。初次打开后延时再测量。
/*-------------------------12C5410flash------------------------*/
// #define ENABLE_ISP 0x80 //<30MHz
// #define ENABLE_ISP 0x81 //<24MHz
#define ENABLE_ISP 0x82 //<20MHz
// #define ENABLE_ISP 0x83 //小于12MHz时值
// #define ENABLE_ISP 0x84 //<6MHz
// #define ENABLE_ISP 0x85 //<3MHz
// #define ENABLE_ISP 0x86 //<2MHZ
// #define ENABLE_ISP 0x87 //<1MHz
#define DATA_FLASH_START_ADDRESS_H 0x28
#define DATA_FLASH_START_ADDRESS_L 0x00 //5410系列起始地址,间隔0x200
#define ISP_IAP_BYTE_READ 1
#define ISP_IAP_BYTE_PROGRAM 2
#define ISP_IAP_SECTOR_ERASE 3
/*-------------------------SPI宏---------------------------------*/
#define ENABLE_SPI SPCTL |= 0X40
#define DISABLE_SPI SPCTL &= 0XBF
#define SPI_MASTER_BY_SS 0 // SPCTL &= 0X7F
#define SPI_MASTER_BY_MSTR 0X80 //SPCTL |= 0X80
#define SPI_LSB 0X20 //SPCTL |= 0X10
#define SPI_MSB 0 //SPCTL &= 0XDF 高位在前
#define SPI_MATER_MODE 0X10 //SPCTL |= 0X08 主模式
#define SPI_SLAVE_MODE 0 //SPCTL &= 0XF7
#define SPI_CLK_POSITIVE 0 //SPCTL &= 0XFB
#define SPI_CLK_NEGATIVE 0X08 //SPCTL |= 0X04
#define SPI_CLK_PHAF 0X04 //SPCTL |= 0X02
#define SPI_CLK_PHAB 0 //SPCTL &= 0XFD
#define SPI_CLK_DIV_BY_4 0X00 //时钟四分频
#define SPI_CLK_DIV_BY_16 0X01
#define SPI_CLK_DIV_BY_64 0X02
#define SPI_CLK_DIV_BY_128 0X03
#define setup_spi(x) SPCTL = (x); //spi的工作模式
//----------------------------------------------------------
#define SPIF_CLR SPSTAT |= 0X80
#define SPIF_WCOL SPSTAT |= 0X40
#define SPIF (SPSTAT & 0X80) //中断标志
#define SPWCOL SPSTAT & 0X40; //冲突标志
//------------------------------------------------------------
#define wrb_spi(x) SPDAT = (x) //spi发送一个字节数据
#define rdb_spi() SPDAT //接收一个数据
/*-------------------------其它常量------------------------------------*/
#define HIGH 1
#define LOW 0
#define BAUD_RATE 0xd9 //1200,1.5MHz 1T方式
#endif
除引用没改。
下边是程序:
// #pragma src
#include "STC54XX.H"
#include "sensor_macro.h"
#include "sensor_var.h"
#include "sensor_function.h"
unsigned char xdata flash_data[FLASH_USED]; //Flash数据刷新时备份
/*-----------这里集中定义了与Flash相关的变量以利于简化读写程序------*/
unsigned char data ip_addr[2],main_ip[2];
data union //定义曲线的k
{
unsigned int ui_k;
unsigned char uc_k[2];
} k;
data union //定义曲线的b
{
unsigned long ul_b;
unsigned char uc_b[4];
} b0;
/*
函数名:shut_isp()
接口 :直接调用
功能 :为防止误操作,完全关闭ISP,这是必要的
*/
void shut_isp(void)
{
ISP_CONTR=0;
ISP_CMD=0; //空闲状态
ISP_TRIG=0;
}
/*
函数名 :ReadByte()
接口 :Flash地址增量即以0x2800作为基址
功能 :从Flash从读取一个字节
*/
unsigned char ReadByte (unsigned char ad_l)
{
ISP_CONTR=ENABLE_ISP;
ISP_CMD=ISP_IAP_BYTE_READ; //读状态
ISP_ADDRH=DATA_FLASH_START_ADDRESS_H;
ISP_ADDRL=DATA_FLASH_START_ADDRESS_L+ad_l;
EA=0;
ISP_TRIG=0x46;
ISP_TRIG=0xb9;
EA=1;
shut_isp(); //关闭ISP
return ISP_DATA;
}
/*
函数名 :WriteByte()
接口 :地址和数据
功能 :写一字节到Flash的指定地址
*/
void WriteByte (unsigned char ad_l,unsigned char dh)
{
ISP_CONTR=ENABLE_ISP;
ISP_CMD=ISP_IAP_BYTE_PROGRAM; //写状态
ISP_ADDRH=DATA_FLASH_START_ADDRESS_H;
ISP_ADDRL=DATA_FLASH_START_ADDRESS_L+ad_l;
ISP_DATA=dh;
EA=0;
ISP_TRIG=0x46;
ISP_TRIG=0xb9;
EA=1;
shut_isp(); //关闭ISP
}
/*
函数名 :erase()
接口 :
功能 :擦除自0x2800的第一页
*/
void erase (void)
{
ISP_CONTR=ENABLE_ISP;
ISP_CMD=ISP_IAP_SECTOR_ERASE; //擦除状态
ISP_ADDRH=DATA_FLASH_START_ADDRESS_H;
ISP_ADDRL=DATA_FLASH_START_ADDRESS_L;
EA=0;
ISP_TRIG=0x46;
ISP_TRIG=0xb9;
EA=1;
shut_isp();
}
/*
函数名 :Flash_buckup()
接口 :
功能 :擦除数据前的备份数据
*/
void Flash_buckup(void)
{
unsigned char data i;
for(i=0;i<FLASH_USED;i++)
{
flash_data[i]=ReadByte(i);
}
}
/*
函数名 :Flash_buckup()
接口 :
功能 :全部数据写入
*/
void Flash_write(void)
{
unsigned char data i;
WDT_CONTR&=0x07; //关闭看门狗
erase();
for(i=0;i<=FLASH_USED;i++)
{
WriteByte(i,flash_data[i]);
}
WriteByte(100,0x88); //改写标志位
WDT; //重启看门狗
}
/*
函数名 :change_address()
接口 :
功能 :修改地址
*/
void change_address(void)
{
Flash_buckup(); //先备份数据
flash_data[0]=ip_addr[0]; //修改相应数据
flash_data[1]=ip_addr[1];
flash_data[8]=main_ip[0];
flash_data[9]=main_ip[1];
Flash_write(); //写入
init_can(); //再次初始化CAN控制器
}
/*
函数名 :change_address()
接口 :
功能 :修改y=kx+b的常数
*/
void change_k_b(void) //仅在调试完成时调用它
{
// unsigned char data i;
Flash_buckup(); //先备份数据
flash_data[2]=k.uc_k[0]; //修改相应数据
flash_data[3]=k.uc_k[1];
flash_data[5]=b0.uc_b[1];
flash_data[6]=b0.uc_b[2];
flash_data[7]=b0.uc_b[3];
if(!b_bflag) //b<0?
{
b0.uc_b[0]=0;
b_bflag=0;
}
else
{
b0.uc_b[0]=1;
b_bflag=1;
}
flash_data[4]=b0.uc_b[0];
Flash_write();
b0.uc_b[0]=0; //回到工作状态最高位清零,无符号数
}
/*
函数名 :read_data()
接口 :
功能 :数据读入内存
*/
void read_data(void)
{
unsigned char data i;
unsigned char data *data ptr;
ptr=&ip_addr;
for(i=0;i<=FLASH_USED;i++)
{
*ptr=ReadByte(i);
ptr++;
}
/*
ip_addr[0]=ReadByte(0);
ip_addr[1]=ReadByte(1)&0xe0;
main_ip[0]=ReadByte(2);
main_ip[1]=ReadByte(3);
k.uc_k[0]=ReadByte(4);
k.uc_k[1]=ReadByte(5);
b0.uc_b[0]=ReadByte(6);
b0.uc_b[1]=ReadByte(7);
b0.uc_b[2]=ReadByte(8);
b0.uc_b[3]=ReadByte(9);
*/
if(b0.uc_b[0]==0)
{b_bflag=0;}
else
{b_bflag=1;}
b0.uc_b[0]=0;
} |