📄 12.c
字号:
/**********************************************
显示和键盘都已经正常,键盘采用的是中断方式
2008.7.2
**************************************/
#include <P89V51.h>
#include <absacc.h>
#include <intrins.h>
#include <stdlib.h>
#include <stdio.h>
#define uchar unsigned char
//SYSTEM ADDRESS ALLOCATION ******************
#define KEYCOLUM XBYTE[0xEFFF]
#define KEYROW XBYTE[0xDFFF]
#define ALARM XBYTE[0xCFFF]
#define HC245C1 XBYTE[0xBFFF]
#define HC245C2 XBYTE[0xAFFF]
#define HC573C1 XBYTE[0x9FFF]
#define HC573C2 XBYTE[0x8FFF]
#define HC573C3 XBYTE[0x7FFF]
#define ADCS XBYTE[0x6FFF]
#define DACS XBYTE[0x5FFF]
#define DACLOAD XBYTE[0x4FFF]
//***************************************
//static unsigned char keyin=0;
/*-------------LCD1602 definitions and functions--------------*/
#define nops() {_nop_();_nop_();_nop_();}
typedef bit BOOL;
#define FALSE (bit)0
#define TRUE (bit)1
sbit lcd_cs = P2^0; //控制位
sbit lcd_rw = P2^1;
sbit lcd_rs = P2^2;
#define DataPort P0
#define DataDirPort P0
#define StatePort P0
#define Busy 0x80 // 忙判别位
uchar keystate,keyin;
unsigned char ucKeyState,flag,c_0,c_1,c_2;
unsigned int n=0,b_out,tick=0,second=0, minute=0;
unsigned char mai[8]={0x11,0x33,0x22,0x66,0x44,0xcc,0x88,0x99};
void delay(long t)
{
while(t)
t--;
}
code unsigned char* WrtieLcdErr = "Display char outof range.";
// ------ Private function prototypes --------------------------
static BOOL WaitTillNotBusy();
static BOOL LocateXY(unsigned char posx, unsigned char posy);
static BOOL LcdWData(unsigned char dataW);
static BOOL LcdWCMD(unsigned char CMD);
BOOL LCDInit() ;
BOOL DisplayOneChar(unsigned char x ,unsigned char y ,unsigned char Wdata) ;
BOOL DisplayString(unsigned char posx, unsigned char posy, unsigned char* str);
unsigned char keyscan(void);
unsigned char Gatkey(char keystate);
BOOL WaitTillNotBusy()
{
unsigned int delay = 0xffff;
DataDirPort = 0xff;
lcd_cs = 1;
lcd_rs = 0;
lcd_rw = 1;
while( (StatePort & Busy) && delay)
delay--;
lcd_cs = 0;
if (!delay)
return FALSE ;
return TRUE;
}
BOOL LocateXY( unsigned char posx,unsigned char posy)
{
posy &= 0x01;
if (posy == 1)
posx |= 0x40;
posx |= 0x80;
return LcdWCMD(posx);
}
BOOL LcdWCMD(unsigned char CMD)
{
unsigned char i=1;
if (!WaitTillNotBusy()) // 检测忙信号?
return FALSE;
DataPort = CMD;
lcd_rs = 0;
lcd_rw = 0;
lcd_cs = 1;
while(i++);
lcd_cs = 0;
return TRUE;
}
BOOL LcdWData( unsigned char dataW )
{
unsigned char i = 1;
if (!WaitTillNotBusy()) // 检测忙信号?
return FALSE;
DataPort = dataW;
lcd_rs = 1;
lcd_rw = 0;
lcd_cs = 1;
while(i++);
lcd_cs = 0;
return TRUE;
}
// LCD输出用函数
//LCDInit--LCD初始化
//DisplayOneChar(x,y,char) --在指定x,y显示一个字符
//DisplayString(x,y,str)--在指定位置x,y开始显示一个字符串
BOOL LCDInit()
{
// 显示模式设置,光标移动设置,显示开及光标设置,显示清屏
return (LcdWCMD( 0x38) && LcdWCMD( 0x06) && LcdWCMD( 0x0c) && LcdWCMD( 0x01));
}
BOOL DisplayOneChar(unsigned char x ,unsigned char y ,unsigned char Wdata)
{
if( (x >= 0 && x < 16) && (y >= 0 && y < 2) )
return (LocateXY( x, y ) && LcdWData( Wdata )) ;// 定位显示地址,写字符
else
return ( LCDInit() && DisplayString(0, 0, WrtieLcdErr)); //显示越界消息
}
BOOL DisplayString(unsigned char posx, unsigned char posy, unsigned char* str)
{
while ( (*str) != '\0' )
{
if (!DisplayOneChar(posx, posy, (*str)))
return FALSE;
str++;
posx++;
if( posx == 16 )
{
posx = 0;
posy++;
}
}
return TRUE;
}
/*--------------End of LCD1602 macros and functions------------------*/
/*-------------- ----SPI protocols----------------------------------- */
void SpiInit(void)
{
SPCR = 0x51;
SPSR = 0x00;
}
void SpiClose(void) {SPCR = 0x00;}
/*----------------End of SPI protocols---------------------------*/
//-----------ADC MCP3208 functions--------------------
// ReadAD(chx)读AD,chx为通道号
//chx=0x00----0x07对应AD0---AD7通道
unsigned int ReadAD(unsigned char chx)
{
unsigned int lsb,msb;
char sbuf;
lsb=0;msb=0;
ADCS = 0x00;
sbuf = 0x06 | (chx>>2);
SPDAT = sbuf;
while(!(SPSR&0x80) );
SPSR = 0x00;
sbuf = SPDAT;
sbuf = (chx&0x03)<<6;
SPDAT = sbuf;
while(!(SPSR&0x80) );
SPSR = 0x00;
sbuf = SPDAT;
msb = sbuf&0x0F;
sbuf = 0x00;
SPDAT = sbuf;
while(!(SPSR&0x80) );
SPSR = 0x00;
lsb = SPDAT;
XBYTE[0xFFFF] = 0x00;
return msb*256+lsb;
}
//------------End ADC MCP3208 functions-----------------
//-----------------DAC MCP4922 functions----------------------
void DACout( unsigned char DACH, unsigned int DAValue)
{
unsigned char msb,lsb,temp;
XBYTE[0xFFFF] = 0;
DAValue&=0x0FFF;
temp = (DAValue/256)&0x0F;
DACS = 0x00;
if(DACH==1)
{
msb =0x70|temp;
lsb = (unsigned char)(DAValue & 0xFF) ;
}
else if(DACH==2)
{
msb =0xF0|temp;
lsb = (unsigned char)(DAValue & 0xFF) ;
}
else
{ }
SPDAT = msb;
while(!(SPSR&0x80) );
SPSR = 0x00;
SPDAT = lsb;
while(!(SPSR&0x80) );
SPSR = 0x00;
XBYTE[0xFFFF] = 0;
DACLOAD = 0x00;
nops();
XBYTE[0xFFFF] = 0;
}
//**********************按键中断响应**********************
void Int1_keyscan( ) interrupt 0
{
unsigned char ucSKey;
unsigned int uiI;
EA=0;
for (uiI=0;uiI<100;uiI++); //延时,去掉抖动
if(INT1==1)
goto end01;
for (uiI=0;uiI<100;uiI++); //延时,去掉抖动
if(INT1==1)
goto end01; //关闭外部中断
LcdWCMD( 0x01) ; //显示清屏
keyscan(); //获取按键状态
ucSKey=Gatkey(keystate);
ucKeyState=ucSKey;
//DisplayOneChar(1,1,keyin); //显示按键对应的字符
//delay(500);
end01:;
KEYROW=0xE0;
EA=1; // 开启中断
}
//********************************平衡************************
void BLB(void)
{
int value_buf[8],temp;
char j,i;
for(i=0;i<8;i++)
{
temp = ReadAD(0x01);
if((temp>10)&&(temp<4500))
{
value_buf[i]=temp; //获取采样值
}
delay(3);
}
for(j=0;j<7;j++) //采样值由小到大排列,排序采用冒泡法
{
for(i=0;i<8-j;i++)
{
if(value_buf[i]>value_buf[i+1])
{
temp=value_buf[i];
value_buf[i]=value_buf[i+1];
value_buf[i+1]=temp;
}
}
}
b_out = value_buf[3];
}
void deal_BLB(void)
{
if(b_out<1300)
{
c_0++;
if(c_0>15)flag=1;
}
if(b_out>1350)
{
c_1++;
if(c_1>15)flag = 0;
}
if((b_out<1350)&&(b_out>1300))
{
c_2++;
c_0=0;
c_1=0;
flag = 2;
}
}
void T0INT( ) interrupt 1
{
TH0 = 0x3C;
TL0 = 0xAF;
tick ++;
if(tick>=19)
{
tick =0;
second++ ;
if(second>=60)
{
second=0;
minute++;
}
}
BLB(); deal_BLB();
}
//*****************获取按键状态函数******************
unsigned char keyscan(void)
{
uchar recode,sccode;
KEYROW=0xE0; //将行都设置为低电平
recode=KEYCOLUM; //获取列的状态
if((recode&0x0F)!=0x0F) //判断是否有键按下和延时去抖动
{
// delay(60);
if((recode&0x0F)!=0x0F)
{
sccode=0xFE; //设置行扫描的初始值
while((sccode&0x20)!=0) //判断并逐行扫描
{
KEYROW=sccode;
recode=KEYCOLUM;
if((recode&0x0F)!=0x0F)
{
recode=(recode&0x0F)|0xF0; //记录列号
sccode=~sccode; //记录行号
sccode=sccode<<4; //把行号方到高四位
keystate=(sccode)+(~recode); //记录行列状态,高四位为行号,低四位为列号
return keystate;
break;
}
else
sccode=(sccode<<1)|0x01; //行扫描后没找到按键状态则转到下一行
}
}
}
return(0);
}
//**********************按键对应的显示字符**********************************
unsigned char Gatkey(char keystate)
{
switch (keystate)
{
case 0x11: keyin='a';
break;
case 0x12: keyin='b';
break;
case 0x14: keyin='c';
break;
case 0x18: keyin='d';
break;
case 0x21: keyin='e';
break;
case 0x22: keyin='f';
break;
case 0x24: keyin='g';
break;
case 0x28: keyin='h';
break;
case 0x41: keyin='i';
break;
case 0x42: keyin='j';
break;
case 0x44: keyin='k';
break;
case 0x48: keyin='l';
break;
case 0x81: keyin='m';
break;
case 0x82: keyin='n';
break;
case 0x84: keyin='0';
break;
case 0x88: keyin='p';
break;
case 0x01: keyin='q';
break;
case 0x02: keyin='r';
break;
case 0x04: keyin='s';
break;
case 0x08: keyin='t';
break;
default: keyin='N' ;
}
return keyin;
}
void Setpwm(char channel, unsigned char pwmval)
{
switch (channel )
{
case 0:
CCAP0L = pwmval;
CCAP0H = pwmval;
break;
case 1:
CCAP1L = pwmval;
CCAP1H = pwmval;
break;
default:
CCAP0L = pwmval;
CCAP0H = pwmval;
}
}
//*****************************************
void back(long speed, int no)
{
int i;
for(i=0;i<no;i++)
{
HC573C1 = mai[i%8];
delay(speed);
}
}
void go(long speed, int no)
{
int i;
for(i=no;i>0;i--)
{
HC573C1 = mai[i%8];
delay(speed);
}
}
void go_left(long speed, int no) //750为90度转弯
{
int i;
for(i=no;i>0;i--)
{
HC573C1 = mai[i%8]&0x0F+0x10;
delay(speed);
}
}
void go_right(long speed, int no) //750为90度转弯
{
int i;
for(i=no;i>0;i--)
{
HC573C1 = mai[i%8]&0xF0+0x01;
delay(speed);
}
}
void deal_go(void)
{
char mid;
mid=HC245C1%4;
if(mid==2)go_left(250,30);
if(mid==1)go_right(250,30);
if(mid==3)go(250,50);
if(mid==0)go(250,50);
}
void deal_bi(void)
{
char mid;
mid=HC245C2%4;
if(mid==2)go_left(250,50);
if(mid==1)go_right(250,30);
if(mid==3)go(250,50);
if(mid==0)go(250,30);
}
//*****************************************
void main()
{
unsigned int ADs,c,i;
unsigned int b1=0,b2;
char ADval[10];
unsigned int BB=3000;
SpiInit();
LCDInit();
DisplayString(0,0,"Hello World");
// delay(10000);
HC573C1 = 0x01;
HC573C2 = 0x0F;
KEYROW = 0x00;
P1 = 0x01;
TMOD = 0x01;
TL0 = 0xAF;
TH0 = 0x3C;
ET0 = 1;
TR0 = 1;
EA = 1;
EX0 = 1;
CMOD = 0x02;
CCAPM0 = 0x4A;
CL =0;
CCAP0H = 16;
CCON = 0x40;
LcdWCMD( 0x01) ; //显示清屏
/*
b1 = (HC245C1/16)%4;
while(b1==3)
{
deal_go();
b1 = (HC245C1/16)%4;
}
delay(50000);
go_right(250,750);
delay(50000);
b1 = (HC245C1/16)%4;
while(b1==3)
{
deal_bi();
b1 = (HC245C1/16)%4;
}
delay(50000);
go_left(250,750);
delay(50000);
b1 = (HC245C1/16)%4;
while(b1==3)
{
deal_bi();
b1 = (HC245C1/16)%4;
}
delay(50000);
go_left(250,750);
i=1100;
while(i)
{
if(HC245C2%4==3)
{
HC573C1 = mai[i%8];
delay(250);
i--;
}
if(HC245C2%4==2)go_left(250,10);
if(HC245C2%4==1)go_right(250,10);
}
delay(50000);
go_right(250,750);
delay(50000);
go(250,800);
LcdWCMD( 0x01) ;
while(1){
DisplayString(11,0,"m s ");
sprintf(ADval,"%d",second);
DisplayString(13,0,ADval);
sprintf(ADval,"%d",minute);
DisplayString(10,0,ADval);
}
*/
HC573C1 = 0x00;
EA = 0;
go(180,1420);
EA = 1;
while(1)
{
LcdWCMD( 0x01);
sprintf(ADval,"%d",b_out);
DisplayString(10,0,ADval);
//delay(100);
if(flag==0)go(250,8);
if(flag==1)back(250,8);
if(flag==2)
{HC573C1 = 0x11;
delay(70000);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -