|
#include<math.h>
#include<absacc.h>
#include<intrins.h>
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define BUSY 0x80 //常量定義
#define DATAPORT P0
#define ADCDELAY 5
sbit LCM_RS=P2^0;
sbit LCM_RW=P2^1;
sbit LCM_EN=P2^2;
sbit CS =P1^2; //ADC0832 chip seclect
sbit CLK =P1^3; //ADC0832 clock signal
sbit SDI =P1^1; //ADC0832 k in
sbit SDO =P1^0; //ADC0832 k out
uchar ad_data; //采樣值存儲(chǔ)
unsigned char press_bai=0; //顯示值百位
unsigned char press_shi=0; //顯示值十位
unsigned char press_ge=0; //顯示值個(gè)位
unsigned char press_dot=0; //顯示值十分位
uchar code str0[]={"Weight: . kg. "};
uchar HighRH = 0;
uchar HighRL = 0;
uchar LowRH = 0;
uchar LowRL = 0;
unsigned int a;
uchar rate;
sbit PWMOUT = P1^0;
uchar step, rec_data,flag;
void ADCInit(void); //初始化TLC2543
uint StartConversion(uchar channl); //開(kāi)始轉(zhuǎn)換,同時(shí)選擇通道,同時(shí)返回上一次采樣值
void delay(uint);
void lcd_wait(void); //檢測(cè)忙子程序
void delay_LCM(uint); //延時(shí)子程序
void initLCM(void); //初始化子程序
void WriteCommandLCM(uchar WCLCM,uchar BusyC); //寫指令到LCM子程序
void WriteDataLCM(uchar WDLCM); //寫數(shù)據(jù)到LCM子程序
void DisplayOneChar(uchar X,uchar Y,uchar DData); //顯示指定坐標(biāo)的一個(gè)字符子函數(shù)
void DisplayListChar(uchar X,uchar Y,uchar code *DData); //顯示指定坐標(biāo)的一串字符子函數(shù)
void display(void); //系統(tǒng)顯示子函數(shù)
void ConfigPWM(uchar rate);
void alarm(void);
void data_pro(void);
void ConfigPWM(uchar dc);
void key_setPWM(void);
uchar duty_cycle(uchar ad_data);
void chuankou_init();
/**********main funcation************/
void main(void)
{
delay(50);
initLCM( );
chuankou_init();
WriteCommandLCM(0x01,1); //清屏顯示
DisplayListChar(0,0,str0);
delay(10);
EA = 1;
ConfigPWM(rate);
while(1)
{
ad_data =StartConversion(0); //采樣值存儲(chǔ)單元初始化為0
alarm();
data_pro();
display();
a=duty_cycle(ad_data);
ConfigPWM(a);
key_setPWM();
if(a!=rate)
{
ConfigPWM(rate);
}
if(RI==1)//串口
{
RI=0;
rec_data=SBUF;
step=rec_data*2;
SBUF=rec_data;
}
}
}
void TIME_INIT()
{
TMOD|=0X02;
IT0=1;
IT1=1;
TR1=1;
EX1=1;
EX0=1;
ET0=1;
TR0=1;
EA=1;
}
void chuankou_init()
{
SCON|=0X50;
TMOD|=0X20;
PCON|=0X80;
TH1=0XFA;
TL1=0XFA;
TR1=1;
SM0=0;
SM1=1;
REN=1;
EA=1;
ES=1;
}
/********延時(shí)K*1ms,12.000mhz**********/
void delay(uint x)
{
uchar i;
while(x--)
{
for(i = 0;i < 120;i++)
{;}
}
}
/**********寫數(shù)據(jù)到ICM子函數(shù)************/
void WriteCommandLCM(uchar WCLCM,uchar BusyC)
{
if(BusyC)
lcd_wait(); //檢測(cè)忙信號(hào)
DATAPORT=WCLCM;
LCM_RS=0;
LCM_RW=0;
LCM_EN=1;
_nop_();
_nop_();
_nop_();
LCM_EN=0;
}
/**********????LCM???************/
void WriteDataLCM(uchar WDLCM)
{
lcd_wait( );
DATAPORT=WDLCM;
LCM_RS=1; //選中數(shù)據(jù)寄存器
LCM_RW=0; //寫模式
LCM_EN=1;
_nop_();
_nop_();
_nop_();
LCM_EN=0;
}
/***********lcm內(nèi)部等待程序*************/
void lcd_wait(void)
{
DATAPORT=0xff; //讀LCD前若單片機(jī)輸出低電平,而讀出LCD為高電平,則沖突,Proteus仿真會(huì)有顯示邏輯黃色
LCM_EN=1;
LCM_RS=0;
LCM_RW=1;
_nop_();
_nop_();
_nop_();
while(DATAPORT&BUSY)
{
LCM_EN=0;
_nop_();
_nop_();
LCM_EN=1;
_nop_();
_nop_();
}
LCM_EN=0;
}
/**********LCM??????***********/
void initLCM( )
{
DATAPORT=0;
delay(15);
WriteCommandLCM(0x38,0); //三次顯示模式,不檢測(cè)忙信號(hào)
delay(5);
WriteCommandLCM(0x38,0);
delay(5);
WriteCommandLCM(0x38,0);
delay(5);
WriteCommandLCM(0x38,1); //8bit數(shù)據(jù)傳送,兩行顯示,5*7字型,檢測(cè)忙信號(hào)
WriteCommandLCM(0x08,1); //關(guān)閉顯示,檢測(cè)忙信號(hào)
WriteCommandLCM(0x01,1); //清屏,檢測(cè)忙信號(hào)
WriteCommandLCM(0x06,1); //顯示光標(biāo)右移設(shè)置
WriteCommandLCM(0x0c,1); //顯示屏打開(kāi),光標(biāo)不顯示,不閃爍,檢測(cè)忙信號(hào)
}
/****??????????????****/
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
Y&=1;
X&=15;
if(Y)X|=0x40; //若Y為1(顯示第二行)地址譯碼+0x40
X|=0x80; //指令碼為地址碼+0x80
WriteCommandLCM(X,0);
WriteDataLCM(DData);
}
/*******??????????????*****/
void DisplayListChar(uchar X,uchar Y,uchar code *DData)
{
uchar ListLength=0;
Y&=0x01;
X&=0x0f;
while(X<16)
{
DisplayOneChar(X,Y,DData[ListLength]);
ListLength++;
X++;
}
}
/*****************???????*****************/
void display(void)
{
WriteCommandLCM(0x0c,1); //顯示屏打開(kāi),光標(biāo)不顯示,不閃爍,檢測(cè)忙信號(hào)
DisplayListChar(0,0,str0);
DisplayOneChar(7,0,press_bai+0x30);
DisplayOneChar(8,0,press_shi+0x30);
DisplayOneChar(9,0,press_ge +0x30);
DisplayOneChar(10,0,056);
DisplayOneChar(11,0,press_dot+0x30);
}
void Delay_ADC(uchar ms)
{
uchar i;
for(; ms > 0; ms--)
for(i = 5; i > 0; i--);
}
void ADCInit(void) //初始化TLC2543
{
CS = 1;
CLK = 0;
SDI = 0;
SDO = 1;
}
uint StartConversion(uchar channl) //開(kāi)始轉(zhuǎn)換,同時(shí)選擇通道,同時(shí)返回上一次采樣值
{
uint dat = 0;
uchar i;
CS = 0;
SDI = 0;
for(i = 0; i < 12; i++) //通道選擇
{
dat <<= 1; //左移一位
if(channl & 0x80)
SDI = 1;
else
SDI = 0;
channl <<= 1; //左移一位
CLK = 1;
if(SDO)
dat += 1;
Delay_ADC(ADCDELAY);
CLK = 0;
}
CS = 1;
return dat;
}
void data_pro(void)
{
unsigned int temp;
float press;
int vary=ad_data; //y=(115-15)/(243-13)*X+15kpa
//press=24+ad_data/2.67;
press=((10.0/28.1)*vary)+9.3; //測(cè)試時(shí)補(bǔ)償值為9.3
temp=(int)(press*10); //放大10倍,便于后面計(jì)算
press_bai=temp/1000;
press_shi=(temp%1000)/100;
press_ge=((temp%1000)%100)/10;
press_dot=((temp%1000)%100)%10;
}
uchar duty_cycle(uchar ad_data)
{
uchar rate;
rate= 100*ad_data/256;
return(rate);
}
/*??????dc,??20Hz????*/
void ConfigPWM(uchar dc)
{
unsigned long tmp; //臨時(shí)變量
uint high, low;
tmp = 11059200/12/20; //計(jì)算一個(gè)周期所需的計(jì)數(shù)值
high = (tmp*dc)/100; //計(jì)算高電平所需計(jì)數(shù)值
low = tmp - high; //計(jì)算低電平所需計(jì)數(shù)值
high = 65536 - high + 12; //計(jì)算高電平的定時(shí)器重載值并補(bǔ)償中斷延時(shí)
low = 65536 - low + 12; //計(jì)算低電平的定時(shí)器重載值并補(bǔ)償中斷延時(shí)
HighRH = (uchar)(high >>8); //高電平重載值拆分為高低字節(jié)
HighRL = (uchar)high;
LowRH = (uchar)(low >> 8); //低電平重載值拆分為高低字節(jié)
LowRL = (uchar)low;
TMOD &= 0xF0; //清0 T0的控制位
TMOD |= 0x01; //配置T0的模式為 1
TH0 = HighRH; //加載T0重載值
TL0 = HighRL;
ET0 = 1; //使能T0中斷
TR0 = 1; //啟動(dòng)T0
}
void init0() interrupt 0
{
step++;
if(step==200)
{
step=0;
}
}
/*???0????*/
void init1() interrupt 2
{
step--;
if(step==0)
{
step=0;
}
}
void chuankou() interrupt 4
{
RI=0;
rec_data=SBUF;
step=rec_data*2;
flag=1;
}
|
|