📄 control.c
字号:
#include <c8051f060.h> // SFR declarations
#include <stdio.h>
unsigned int block;
unsigned int page;
unsigned char RECVDAT;
unsigned char abc;
unsigned char frame_cnt;
unsigned int bytecnt;
unsigned char time4;
unsigned char time3;
unsigned char time2;
unsigned char time1;
unsigned char k;
unsigned char inc;
unsigned char j;
unsigned char h;
unsigned int xdata * data write_ptr;
unsigned int xdata * data read_ptr;
bit time_flag;
bit frame_half1;
bit frame_half2;
bit s1;
bit s2;
bit wait;
bit f_write_status;
bit f_read_status;
unsigned int T0_count;
bit time1s_ok;
unsigned long flag;
bit UART0_RECV;
sbit we = P3^2;
sbit ale = P3^3;
sbit cle = P0^5;
sbit re = P3^0;
sbit rb = P3^4;
sbit wp = P3^1;
sbit rd = P3^7; // 低电平表示读状态
sbit req = P3^6;
sbit JS=P3^5;
void SYSCLK_Init (void);
void UART0_Init(void);
void UART1_Init(void);
void PORT_Init(void);
void ADC2_Init(void);
void RAM_Init(void);
void Frame_Init(void);
void Timer4_Init(void);
sfr16 RCAP3=0xCA;
sfr16 TMR3=0xCC;
unsigned int T3reload;
sfr16 RCAP4=0xCA;
sfr16 TMR4=0xCC;
unsigned int T4reload;
void delays(unsigned int c) //68ns
{
unsigned int i;
for(i=0;i<c;i++);
}
void ADC2_ISR() interrupt 18
{
AD2INT=0;
if(s2==0 && s1==0)
{
AMX2SL=0x01; // 1通道送入AD转换
s2=0;s1=1;
}
else if(s2==0 && s1==1)
{
AMX2SL=0x02; // 2通道送入AD转换
s2=1;
}
else
{
AMX2SL=0x00; // 0通道送入AD转换
s2=0;s1=0;
}
if(time_flag) // 如果已打上时标
{
if(k<14)
{
*write_ptr=ADC2L;
write_ptr++;
*write_ptr=ADC2H;
write_ptr++; // 地址推进
k++; // 振动数据计数加1
}
else // 振动数据的第29和30字节
{
*write_ptr=ADC2L;
write_ptr++;
*write_ptr=ADC2H;
write_ptr++;
write_ptr=write_ptr+14; // 连续推进14个地址
time_flag=0; // 表示时标未打上
k=0; // 将振动数据计数清零
time1=flag;
time2=flag>>8;
time3=flag>>16;
time4=flag>>24;
if(frame_cnt==20)
{
frame_half1=1; // 前21帧已满
frame_cnt++;
}
else if(frame_cnt==41)
{
frame_half2=1;
frame_cnt=0;
write_ptr=4; // RAM地址归0
}
else
{
frame_cnt++;
}
}
}
else //还没有打上时标
{
*write_ptr=time4;
write_ptr++;
*write_ptr=time3;
write_ptr++;
*write_ptr=time2;
write_ptr++;
*write_ptr=time1;
write_ptr++;
*write_ptr=ADC2L;
write_ptr++;
*write_ptr=ADC2H;
write_ptr++;
k++;
time_flag=1; // 时标已打上
}
}
void Timer4_ISR() interrupt 16
{
TF4=0;
flag=flag+1;
}
void Timer0_ISR() interrupt 1
{
if (T0_count==400)
{
time1s_ok=1; // 1s定时时间到
TH0= 0x70; // 5ms 定时
TL0= 0x1f;
T0_count=1;
}
else
{
TH0= 0x70; // 5ms 定时
TL0= 0x1f;
T0_count++;
}
}
void UART0_ISR() interrupt 4
{
if(RI0)
{
RI0=0;
RECVDAT=SBUF0;
UART0_RECV=1; // 接收到惯组数据
}
}
void main (void)
{
wp=1;
ale=0;
cle=0;
re=1;
we=1;
page=0;
block=0;
bytecnt=0;
abc=0x00;
read_ptr=0;
frame_half1=1;
frame_half2=1;
frame_cnt=0;
time1=0x00;
time4=0x00;
time3=0x00;
time2=0x00;
k=0;
j=0;
h=0;
s1=0;
s2=0;
wait=1;
f_read_status=0;
f_write_status=0;
EA=0;
WDTCN=0x07;
WDTCN=0xDE;
WDTCN=0xAD;
EA=1;
SFRPAGE = 0;
RSTSRC = 0x04; // enable missing clock detector reset
SYSCLK_Init();
PORT_Init();
Timer4_Init();
RAM_Init();
write_ptr=4; // 写地址指针应该初始化在第3个地址上
ADC2_Init();
UART0_Init();
UART1_Init();
time_flag=0;
k=0;
rd=1; // 输出置为高阻态
delays(2);
//--------------------------------------------
// 擦除FLASH
//--------------------------------------------
while(1)
{
while(wait==1 && time1s_ok==0) //在1s的定时时间里
{
if(UART0_RECV==1) //如果串口0接收到数据
{
f_write_status=1; // 写状态标志
wait=0; // 退出1s的定时等待
SFRPAGE = 0;
TR0=0; // 关闭定时器0
ET0=0; // 定时器0中断关闭
SFRPAGE = UART0_PAGE;
SCON0 = 0x40; // 8位UART,可变波特率;接收禁止,清除TI0和RI0
ES0=0; // 串口0中断禁止
SFRPAGE = ADC2_PAGE;
EIE2 |=0x10; // 允许ADC2中断
SFRPAGE = TMR3_PAGE;
TR3=1; // 开启定时器3
}
}
if (time1s_ok==1 && f_write_status==0) // 1s定时时间到,且未处于写状态
{
time1s_ok=0; // 清除1s定时时间到的标志
if (rd==0) // 读信号有效
{
f_read_status=1;// 置读状态标志
wait=0; // 退出1s的定时等待
SFRPAGE = 0;
TR0=0; // 关闭定时器0
ET0=0; // 定时器0中断关闭
SFRPAGE = UART0_PAGE;
SCON0 = 0x40; // 8位UART,可变波特率;接收禁止,清除TI0和RI0
ES0=0; // 串口0中断禁止
SFRPAGE = ADC2_PAGE;
EIE2 &=0xEF; // 禁止ADC2中断
SFRPAGE = TMR3_PAGE;
TR3=0; //关闭定时器3
}
}
while(f_write_status==1)
{
while(block<100)
{
cle=1;
P2=0x60;
we=0;
we=1;
cle=0;
ale=1;
P2=((block%4)<<6);
we=0;
we=1;
P2=((block>>2)%256);
we=0;
we=1;
P2=(block>>10);
we=0;
we=1;
ale=0;
cle=1;
P2=0xd0;
we=0;
we=1;
cle=0;
rb=1;
delays(5); // wait for 340ns;
while(!rb); // wait for rb=1
//--------------------------------------------
// 写FLASH
//-------------------------------------------
page=0;
while(page<64)
{
cle=1;
P2=0x80; // command 0x80
we=0;
we=1;
cle=0;
ale=1;
P2=0x00; // column address #1
we=0;
we=1;
P2=0x00; // column address #2
we=0;
we=1;
P2=((block%4)<<6)|page;
we=0;
we=1;
P2=((block>>2)%256);
we=0;
we=1;
P2=(block>>10);
we=0;
we=1;
ale=0;
read_ptr=0; // 读指针归0
bytecnt=0; // 字节计数归0
//----------------------
while(frame_half1==0);
while(bytecnt<1008)
{
we=0;
P2=*read_ptr;
we=1;
bytecnt++;
read_ptr++;
}
frame_half1=0;
bytecnt=0; // 字节计数归0
while(frame_half2==0);
while(bytecnt<1008)
{
we=0;
P2=*read_ptr;
we=1;
bytecnt++;
read_ptr++;
}
frame_half2=0;
//------------------------
cle=1;
P2=0x10;
we=0;
we=1;
cle=0;
rb=1;
delays(5); // wait for 340ns;
while(!rb); // wait for rb=1;
page++;
}
block++;
}
}
while(f_read_status==1) // 为1时进入读模式
{
SFRPAGE = UART0_PAGE;
SCON0 = 0x40; // 8位UART,可变波特率;接收禁止,清除TI0和RI0
ES0=0;
SFRPAGE = UART1_PAGE;
block=1;
while(block<100)
{
page=0;
while(page<64)
{
cle=1;
P2=0x00;
we=0;
we=1;
cle=0;
ale=1;
P2=0x00; // column address #1
we=0;
we=1;
P2=0x00;
we=0;
we=1; // column address #2
P2=((block%4)<<6)|page;
we=0;
we=1;
P2=((block>>2)%256);
we=0;
we=1;
P2=(block>>10);
we=0;
we=1;
ale=0;
cle=1;
P2=0x30;
we=0;
we=1;
cle=0;
delays(5); // wait for 340ns;
rb=1;
while(!rb); // wait for rb=1;
P2=0xFF;
bytecnt=0;
while(bytecnt<2016 && req==0)
{
re=0;
SBUF1=P2; // 从P2口读FLASH数据 通过串口1发送
re=1;
while(!TI1);
TI1=0;
bytecnt++;
}
page++;
}
block++;
}
}
}
}
//-----------------------------------------------------------------------------
// Configure the Crossbar and GPIO ports
void PORT_Init (void)
{
char old_SFRPAGE = SFRPAGE;
SFRPAGE = CONFIG_PAGE; // Switch to configuration page
XBR0 = 0x04; // 使能串口0
XBR1 = 0x00;
XBR2 = 0x44; // 使能串口1 ,开启交叉开关
P0MDOUT = 0xFF; // push-pull 输出
P1MDIN = 0xF8; // P1口低3位为模拟输入,
P1MDOUT = 0x00; // P1口输出保持默认为开漏输出
P1=0xFF; // 输出置为高阻态
P2MDIN = 0xFF; // P2口为数字输入模式
P2MDOUT = 0xFF; // P2口输出push-pull
P3MDOUT = 0xFF; // P3口输出保持默认为开漏输出
SFRPAGE = old_SFRPAGE; // restore SFRPAGE
}
void UART0_Init(void)
{
char old_SFRPAGE = SFRPAGE;
SFRPAGE = UART0_PAGE;
SCON0 = 0x50; // 8位UART,可变波特率;接收允许,清除TI0和RI0
SSTA0=0x15;
ES0=1; // 串口0中断
SFRPAGE = TMR2_PAGE; // 定时器2作为串口0的波特率发生器
TMR2CF = 0x08;
RCAP2L=0xff; //921.6kbps
RCAP2H=0xFF;
TMR2L=0xff;
TMR2H=0xFF;
TR2=1;
SFRPAGE = old_SFRPAGE;
}
void UART1_Init(void)
{
char old_SFRPAGE = SFRPAGE;
SFRPAGE = UART1_PAGE;
SCON1 = 0x40; // TI和RI清0
SFRPAGE = 0; // 切换到Timer1 page Switch to Timer 1 page,the same to Timer 2 page
TMOD = 0x21; // TMOD: timer 1, mode 2, 8-bit reload
// timer 0, mode 1, 16-bit
CKCON = 0x18; // sysclock as T1 time base
// sysclock as T0 time base
TH1 = 0xFE; // 0xfe,3.6864Mbps
TL1 = TH1;
TR1 = 1; // start Timer1
TH0= 0x70; // 5ms 定时
TL0= 0x1f;
TR0= 1;// start Timer0
ET0= 1;// timer0 interrupt enable
PT0= 0; //T0优先级为低优先级
SFRPAGE = old_SFRPAGE; // restore SFRPAGE
}
void Timer4_Init()
{
char old_SFRPAGE = SFRPAGE;
SFRPAGE = 2;
TMR4CN=0x04; // 开启T4,清除TF4标志
TMR4CF=0x08; // T4时钟选择系统时钟
T4reload=1475;// 14745600/10000=1474.56,10k
RCAP4=~T4reload+1;
TMR4=0xffff; // 立即装载
EIE2 |= 0x04; // 开启T4中断
EIP2 |= 0x04; // 优先级为高
SFRPAGE = old_SFRPAGE; // restore SFRPAGE
}
void SYSCLK_Init (void)
{
char old_SFRPAGE = SFRPAGE;
int i;
SFRPAGE = CONFIG_PAGE;
OSCXCN = 0x67; // 外部晶振模式
for (i=0; i <5000; i++) ; // XTLVLD blanking interval (>1ms)
// while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settle
CLKSEL = 0x01; // 采用外部时钟
OSCICN = 0x00; // 内部晶振禁止
SFRPAGE = old_SFRPAGE; // restore SFRPAGE
}
void ADC2_Init()
{
char old_SFRPAGE = SFRPAGE;
SFRPAGE = ADC2_PAGE;
ADC2CF=0x58; // 2M 的转换速度
ADC2CN=0xc4; // 使能ADC2,低功耗跟踪模式,T3溢出启动ADC2转换
AMX2CF=0x00; // 全部保持单端输入
AMX2SL=0x00; // 0通道送入AD转换
REF2CN=0x0B; // ADC2电压基准取自AV+,BIASE=1.偏压产生器工作,REFBE=1,内部参考电平工作并输出到VREF引脚
//EIE2 |=0x10; // 允许ADC2中断
SFRPAGE = TMR3_PAGE;
TMR3CN=0x04; // 禁止T3,清除TF3
TMR3CF=0x08; // T3时钟选择系统时钟
T3reload=983;// 14745600/15000=983.04,取为983,
RCAP3=~T3reload+1;
TMR3=0xffff; // 立即装载
//TR3=1; // 开启定时器3
SFRPAGE = old_SFRPAGE;
}
void Frame_Init()
{
unsigned char m;
*write_ptr=0x14;
write_ptr++;
*write_ptr=0x6F;
write_ptr++;
for(m=0;m<46;m++)
{
*write_ptr=0x00;
write_ptr++;
}
}
void RAM_Init()
{
unsigned char n;
write_ptr=0;
for(n=0;n<42;n++)
{
Frame_Init();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -