16级灰度护栏灯控制器程序
硬件资源:
RAM ADDRESS :0000H---7FFFH
CF card ADDRESS:8000H---8FFFH
CPLD ADDRESS:9000H---FFFFH
RAM SIZE :32K FLASH SIZE:8MBYTE = 4K*512PAGE*4PCS
PCB:V10
*/
#include <reg52.h>
#include <intrins.h>
//#include <ctype.h>//字符函数
#include <string.h>//字符串函数
#include <stdio.h>//一般I/O函数
#include <stdlib.h>//标准函数
//#include <math.h>//数学函数
#include <absacc.h>//绝对地址
#include <intrins.h>//内部函数
#include <setjmp.h>
#define uchar unsigned char
#define uint unsigned int
#define byte unsigned char
#define ulong unsigned long
#define bool bit
#define TRUE 1
#define FALSE 0
#define V_TH0 0xff /* 时间常数高8位 (65536-500)/256 */
#define V_TL0 0xff /* 时间常数低8位 (65536-500)>256 11.0592*/
//#define V_TH0 (65536-1536)/256
//#define V_TL0 (65536-1536)>256
#define V_TMOD 0x01 /* 定时器T0方式控制字 */
#define WriteDeviceAddress 0xa0
#define ReadDviceAddress 0xa1
sfr CHPCON= 0xbf;
sfr CHPENR=0xf6;
sfr PMR= 0xC4;
sfr SBUF1=0xc1;
sfr SCON1=0xc0;
sbit SM01 = SCON1^7; /* alternative SM0_FE_1 */
sbit SM11 = SCON1^6; /* alternative SM1_1 */
sbit SM21 = SCON1^5; /* alternative SM2_1 */
sbit REN1 = SCON1^4; /* alternative REN_1 */
sbit TB81 = SCON1^3; /* alternative TB8_1 */
sbit RB81 = SCON1^2; /* alternative RB8_1 */
sbit TI1 = SCON1^1; /* alternative TI_1 */
sbit RI1 = SCON1^0; /* alternative RI_1 */
sbit ES1 = IE^6;
/* 定义定时器T0的时间常数值和方式控制字 */
#define REGL XBYTE[0x9003] //控制寄存器护栏管的长度
#define FPGH XBYTE[0x9001] //闪存页高位
#define FPGL XBYTE[0x9002] //闪存页低位
//-------- CF CARD REG ADDRESS
#define EVEN_Data XBYTE[0xa400]
#define ODD_Data XBYTE[0xa400]
#define Data_Reg XBYTE[0xa000] //DATA REGISTER(R/W)
#define Error_Reg XBYTE[0xa001] //ERROR REGISTER(READ)
#define Features XBYTE[0xa001] //FEATURE REGISTER(WRITE)
#define Sectr_Cnt XBYTE[0xa002]//SECTOR COUNT REGISTER(R/W)
#define Sectr_No XBYTE[0xa003] //SECTOR NUMBER REGISTER(R/W)
#define Cylinder_Low XBYTE[0xa004] //CYLINDER LOW REGISTER(R/W)
#define Cylinder_Hi XBYTE[0xa005] //CYLINDER HIGH REGISTER(R/W)
#define Drv_Head XBYTE[0xa006] //DIRVE/HEAD REGISTER(R/W)
#define Status XBYTE[0xa007] //STATUS REGISTER(READ)
#define Command XBYTE[0xa007] //COMMAND REGISTER(WRITE)
#define Alt_Status XBYTE[0xa00e] //Alternate Status Regiter(read only)
#define Device_Ctrl XBYTE[0xa00e] //Device Control Register(Write only)
#define Device_Addrs XBYTE[0xa00f] //Drive Address Register(read only).Not used in this demo
#define Config XBYTE[0x8200] //Configuration Option Register
#define Socket XBYTE[0x8206] //Socket and copy Register
//CF card All command code
#define ChkPwr 0xe5
#define Diagnostic 0x90
#define EraseSctr 0xc0
#define Format 0x50
#define Identify 0xec
#define Idle 0xe3
#define Idlelmm 0xe1
#define Initialize 0x91
#define ReadBuf 0xe4
#define ReadLong 0x22
#define ReadMulti 0xc4
#define ReadSctr 0x20
#define ReadVerify 0x40
#define Recalibrate 0x10
#define ReadSense 0x03
#define Seek 0x70
#define SetFeature 0xef
#define SetMulti 0xc6
#define Sleep 0xe6
#define Standby 0xe2
#define Standbylmm 0xe0
#define Translate 0x87
#define WearLevel 0xf5
#define WriteBuf 0xe8
#define WriteLong 0x32
#define WriteMulti 0xc5
#define WriteSctr 0x30
#define WriteVerify 0x3c
#define WrtMwoErase 0xcd
#define WrtSwoErase 0x38
#define debug 1;
//**********************************************
sbit senden=P3^2;
sbit SDA=P3^3;
sbit SCL=P3^5;
sbit wdgclr=P1^7;
//*************************************************
uchar Select;
uchar LBA[6]; //Sets up sector ,CF Card Address
uint zhepe; //帧频
uint ms; //毫秒定时
uchar ADD; //地址
uchar idata iic_buf[96]; //接收缓冲区
uint pointer;
uchar xdata *bufp;
uchar subchk; //接收指针 和校验
uchar paklen; //包长
uint Dcyli; //总柱面
uint Dhead; //总磁头
uint sec_track; //扇区/磁道
uchar bdata flag;
sbit frameok=flag^0; //rece ok
sbit color=flag^1; //0 sing red color 1 red green color
sbit rec_sta=flag^2; //1 进入接状态,不显示
sbit rec_end=flag^3;
sbit timout=flag^4;
//jmp_buf env;
//int retval;
/***************************************************************************/
void I2cDelay(unsigned int number) {
unsigned char temp;
for(;number!=0;number--,wdgclr=!wdgclr) {
for(temp=112;temp!=0;temp--) {
}
}
}
//*******************************
void SomeNOP(void)
{
uchar i;
i=5;
while(i--);
}
/***************************************************************************/
void Start() {
SDA=1;SomeNOP();
SCL=1;SomeNOP();
SDA=0;SomeNOP();
SCL=0;SomeNOP();
}
/***************************************************************************/
void Stop() {
SCL=0;SomeNOP();
SDA=0;SomeNOP();
SCL=1;SomeNOP();
SDA=1;SomeNOP();
}
/***************************************************************************/
void Ack() {
SDA=0;SomeNOP();
SCL=1;SomeNOP();
SCL=0;SomeNOP();
SDA=1;SomeNOP();
}
/***************************************************************************/
void NoAck() {
SDA=1;SomeNOP();
SCL=1;SomeNOP();
SCL=0;SomeNOP();
}
/***************************************************************************/
bit TestAck() {
bit ErrorBit;
SDA=1;SomeNOP();
SCL=1;SomeNOP();
ErrorBit=SDA;
SCL=0;
return(ErrorBit);
}
/***************************************************************************/
Write8Bit(unsigned char input)
{
unsigned char temp;
for(temp=8;temp!=0;temp--) {
SDA=(bit)(input&amt;0x80);
SCL=1;SomeNOP();
SCL=0;SomeNOP();
input=input<<1;
}
}
/***************************************************************************/
void Write24c02(unsigned char xdata *Wdata,unsigned char RomAddress,unsigned char number) {
wdgclr=!wdgclr;
Start();
Write8Bit(WriteDeviceAddress);
TestAck();
Write8Bit(RomAddress);
TestAck();
for(;number!=0;number--) {
Write8Bit(*Wdata);
TestAck();
Wdata++;
}
Stop();
I2cDelay(10);
}
/***************************************************************************/
unsigned char Read8Bit() {
unsigned char temp,rbyte=0;
for(temp=8;temp!=0;temp--) {
SCL=1;
rbyte=rbyte<<1;
rbyte=rbyte|((unsigned char)(SDA));
SCL=0;
}
return(rbyte);
}
/***************************************************************************/
void Read24c02(unsigned char *RamAddress,unsigned char RomAddress,unsigned char bytes) {
// unsigned char temp,rbyte;
wdgclr=!wdgclr;
Start();
Write8Bit(WriteDeviceAddress);
TestAck();
Write8Bit(RomAddress);
TestAck();
Start();
Write8Bit(ReadDviceAddress);
TestAck();
while(bytes!=1) {
*RamAddress=Read8Bit();
Ack();
RamAddress++;
bytes--;
}
*RamAddress=Read8Bit();
NoAck();
Stop();
}
/*************************************************
************************************************/
void delayms( uchar ticks )
{
uint Count;
uchar Tick;
for (Tick=ticks;Tick>0;Tick--)
{
for (Count=0;Count<=500;Count++);
wdgclr=!wdgclr;
}
}
/************************************
通讯协议解析 接收数据
*******************************************8
*/
void receive(void)
{
uchar i;
uchar xdata *sp;
wdgclr=!wdgclr;
switch(XBYTE[0x1002])//命令标志
{
case 1:rec_sta=1;TR0=0;//进入接收状态
break;
case 2: //接收数据
break;
case 0: //加载某一帧数据到显存
break;
case 3: //将一扇区数据写闪存
break;
case 4: //测试
break;
case 5: //接收到显存
case 6: //同步信号
ms=0;
break;
case 7: //进入自动播放
sp=0x1008;
for(i=0;i<12;i++)
{
Write24c02(sp,i*8,8);
sp+=8;
}
ms=0;
TR0=1;
break;
case 8:
break;
default:break;
}
}
void send_char(unsigned char ascii)
/*往串口发送一个字符 */
{
SBUF=ascii;
while(!TI);TI=0;
}
void send_string(unsigned char code *string)
/*往串口发送一个字符串,字符串为存储在程序空间,碰到0x00结束 */
{
TB8=1;
while(*string!=0)
{
send_char(*string);
string++;
}
TB8=0;
}
//***************************
void delay(uchar sec)
{
uint i;
while(sec)
{for(i=0;i<50000;i++);sec--;}
}
//****************************
void SoftRST(void)
{
Device_Ctrl=0x0c;
Device_Ctrl=0x08;
delay(10); //delay 0.5s
}
//*********************************
bit Busy(void)
{
send_string("rBusy");
while(Status&amt;0x80);
if(Status&amt;0x01)
{send_string("rBusy_ERR");return(0);}
else
{send_string("rBusy_OK");return(1);}
}
//**********************************
bit Wait_Ready(void)
{
send_string("rWait_Ready");
while((Status&amt;0xf0)!=0x50);
send_string("rWait_Ready_OK");
return(1);
}
//**********************************
bit Wait_Drq(void)
{
send_string("rWait_Drq");
while((Status&amt;0xf8)!=0x58);
send_string("rWait_Drq OK");
return(1);
}
//********************************
void Enable8bit(void)
{
Busy();
Features=0x01;
Drv_Head=Select;
Command=0xef;
}
//*********************
void SetupCard(void)
{
Select=0xe0;
Socket=0;
Enable8bit();
}
//****************************
//Set up sector count ,lba addresses command code
//****************************
void Function(void)
{
send_string("rFunction");
Busy();
Sectr_Cnt=LBA[0];
Sectr_No=LBA[1];
Cylinder_Low=LBA[2];
Cylinder_Hi=LBA[3];
Drv_Head=LBA[4];
Command=LBA[5];
}
//*********************************
void Read512(uchar xdata *RamBuf)
{
uint i;
for(i=0;i<256;i++)
{*RamBuf++=EVEN_Data;
*RamBuf++=ODD_Data;}
}
//*********************************
void Write512(uchar xdata *RamBuf)
{
uint i;
for(i=0;i<256;i++)
{EVEN_Data=*RamBuf++;
ODD_Data=*RamBuf++;}
}
//***********************************
void Read_Sctr(uchar lba0,lba1,lba2,lba3)
{
Wait_Ready();
LBA[0]=1;
LBA[1]=lba3;
LBA[2]=lba2;
LBA[3]=lba1;
LBA[4]=0xe0|(lba0&amt;0x0f);
LBA[5]=ReadSctr;
Function();
Wait_Drq();
Read512(0x0000);
}
//***********************************
void Read_Identify(void)
{
Wait_Ready();
LBA[0]=1;
LBA[1]=0;
LBA[2]=0;
LBA[3]=0;
LBA[4]=0xe0;
LBA[5]=Identify;
Function();
Wait_Drq();
Read512(0x0000);
}
//***********************************
void Write_Sctr(void)
{
Wait_Ready();
LBA[0]=1;
LBA[1]=0x0a;
LBA[2]=0;
LBA[3]=0;
LBA[4]=0xe0;
LBA[5]=WriteSctr;
Function();
Wait_Drq();
Write512(0x0000);
}
//**************************
void Send512(void)
{
uint i;
uchar xdata *p;
p=0;
TB8=1;
for(i=0;i<512;i++)
{SBUF=*p++;while(!TI);TI=0;}
TB8=0;
}
//********************************************
// 主程序
//********************************************
void main()
{
uchar *p;
uint l;
//uchar i,play; //播放列表计数
//uint rplay; //重复次数
PS=1;
ES=0;
SM0=1;
SM1=1;
T2CON=0X30;
RCAP2H=0XFF;
TH2=0XFF;
RCAP2L=0Xfb; //9600bps= c4 115200bps =fb 57600= f6 19200 = e2
TL2=0Xfb;
TR2=1;
REN=1;
TMOD=0x05; //定时器0 模式1 外部时钟
//TMOD=0x01; //定时器0 模式1 外部时钟
TL0=V_TL0;
TH0=V_TH0;
//TR0=1;
ET0=1;
//ES=1;
TI=0;
EA=1;
SM2=1;
PMR=PMR|0x01; //enable on-chip RAM
ADD=(~P1)&amt;0x1f;
p=&amt;iic_buf[0];
Read24c02(p,0,96);
//ADD=1;
frameok=0;
bufp=0x1000; //接收缓冲区指针
send_string("rCF card contr 2004-10-29");
Send512();
SoftRST();
SetupCard();
Write_Sctr();
for(l=4096;l<51200;l++)
{Read_Sctr(0,0,l/256,l>256);
Send512();
}
while(1)
{
wdgclr=!wdgclr;
if(frameok)
{receive();frameok=0;}
}//while(1)
}
//*****************************************
// 串口中断服务程序
//*****************************************
void send(void) interrupt 4
{
uchar d;
if(!TI &amt;&amt; RI &amt;&amt; !frameok)
{RI=0;
d=SBUF;
if(pointer==0)
{if(d==ADD)
{subchk=d;*bufp++=d;TB8=1;senden=1;
SBUF=d;while(!TI);TI=0;
senden=0;SM2=0;TB8=0;pointer++;
}
}
else
{if(pointer==4104)
{
if(d==subchk)
{senden=1;SBUF=subchk;while(!TI);senden=0;TI=0;frameok=1;}
else
{senden=1;SBUF=~subchk;while(!TI);TI=0;senden=0;}
SM2=1;pointer=0;
bufp=0x1000;
}
else
{
*bufp++=d;subchk+=d;pointer++;
}
}
}//end if
}
//*************************************
void timer1() interrupt 1
{TL0=V_TL0;
TH0=V_TH0;
ms++;
if(ms>zhepe)
{timout=1;
ms=0;
}
}