主函數
#include "stc15f2k60s2.h"
#include "key.h"
#include "hardware.h"
#include "iic.h"
#include "delay.h"
typedef unsigned char uchar;
typedef unsigned int uint;
bit Read_adc_flag;
bit led1_count_flag;
uchar test_flag;
uchar led_value=0xff;
uchar key_val; //按鍵值
uint AD_val; //電壓值
int VP=300; //電壓引數
uchar count_val=0; //計數值
uchar error_count; //錯誤計數
uchar Display_mode; //介面選擇
uchar code SMG_duan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
uchar SMG_wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar Display1[8]; //介面1
uchar Display2[8]; //介面2
uchar Display3[8]; //介面3
void key_process(); //按鍵功能函數
void Timer0Init(void); //1毫秒@12.000MHz
void Display1_pro(); //介面1處理常式
void Display2_pro(); //介面2處理常式
void Display3_pro(); //介面3處理常式
void judge();
void main()
{
uchar j;
All_init();
Timer0Init();
test_flag=Read_eeprom(0x09); //讀取指定地址的值
if(test_flag==8) //可取任意值,確保第一次上電,VP=3V
VP=Read_eeprom(0x00)*10;
else
{
VP=300;
Write_eeprom(0x09,8);
delayms(10);
}
while(1)
{
key_process();
Display1_pro();
Display2_pro();
Display3_pro();
judge();
Ledlight(led_value);
switch(j) //保證每次只加1
{
case 0:
if(AD_val>VP)
{
j++;
}
break;
case 1:
if(AD_val<VP)
{
j=0;
count_val++;
}
break;
}
}
}
void judge()
{
uchar flag1,flag2,flag3;
if(AD_val<VP)
led1_count_flag=1;
else
led1_count_flag=0;
if(count_val%2!=0) //判斷奇偶
led_value&=0xfd;
else
led_value|=0x02;
if(Display_mode!=1) //無效按鍵
{
if((key_val==16)||(key_val==17))
error_count++;
}
else
{
if((key_val==16)||(key_val==17))
error_count=0;
}
if(Display_mode!=2)
{
if(key_val==13)
error_count++;
}
else
{
if(key_val==13)
error_count=0;
}
if((key_val==4)||(key_val==5)||(key_val==6)||(key_val==7))
flag1=1;
if((key_val==8)||(key_val==9)||(key_val==10)||(key_val==11))
flag2=1;
if((key_val==14)||(key_val==15)||(key_val==18)||(key_val==19))
flag3=1;
if((flag1==1)||(flag2==1)||(flag3==1))
{
flag1=0; flag2=0; flag3=0;
error_count++;
}
if(error_count>=3)
{
led_value&=0xfb;
}
else
led_value|=0x04;
}
#define fun(x) (int)(5*x/255.0*100+0.5) //數位電壓x轉換為模擬電壓的公式
void Display1_pro() //介面1
{
uint temp;
if(Read_adc_flag) //100ms讀一次資料
{
temp=Read_pcf8591(0x03);
Read_adc_flag=0;
AD_val=fun(temp);
}
Display1[0]=0x3e;
Display1[1]=0x00;
Display1[2]=0x00;
Display1[3]=0x00;
Display1[4]=0x00;
Display1[5]=SMG_duan[AD_val/100]|0x80;
Display1[6]=SMG_duan[AD_val/10%10];
Display1[7]=SMG_duan[AD_val%10];
}
void Display2_pro() //介面2
{
Display2[0]=0x73;
Display2[1]=0x00;
Display2[2]=0x00;
Display2[3]=0x00;
Display2[4]=0x00;
Display2[5]=SMG_duan[VP/100]|0x80;
Display2[6]=SMG_duan[VP/10%10];
Display2[7]=SMG_duan[VP%10];
}
void Display3_pro() //介面3
{
Display3[0]=0x37;
Display3[1]=0x00;
Display3[2]=0x00;
Display3[3]=0x00;
Display3[4]=0x00;
Display3[5]=0x00;
Display3[6]=SMG_duan[count_val/10];
Display3[7]=SMG_duan[count_val%10];
}
void key_process()
{
uchar temp;
key_val=Key_init();
switch(key_val)
{
case 12: //介面切換
error_count=0;
Display_mode++;
if(Display_mode==3)
Display_mode=0;
break;
case 13: //清零
if(Display_mode==2)
count_val=0;
break;
case 16: //"加"
if(Display_mode==1)
{
VP+=50;
if(VP>500)
VP=0;
temp=VP/10;
Write_eeprom(0x00,temp);
delayms(10);
}
break;
case 17: //"減"
if(Display_mode==1)
{
VP-=50;
if(VP<0)
VP=500;
temp=VP/10;
Write_eeprom(0x00,temp);
delayms(10);
}
break;
}
}
void Timer0Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x80; //定時器時鐘1T模式
TMOD &= 0xF0; //設定定時器模式
TL0 = 0x20; //設定定時初值
TH0 = 0xD1; //設定定時初值
TF0 = 0; //清除TF0標誌
TR0 = 1; //定時器0開始計時
EA=1;
ET0=1;
}
void timer0() interrupt 1
{
static smg_count;
uchar adc_count;
uint led1_count;
uchar i;
adc_count++;
smg_count++;
if(led1_count_flag)
{
led1_count++;
if(led1_count>5000)
{
led_value&=0xfe;
}
}
else
{
led_value|=0x01;
led1_count=0;
}
if(smg_count==2)
{
smg_count=0;
P2=P2&0x1f|0xc0; P0=SMG_wei[i];
P2=P2&0x1f;
if(Display_mode==0)
{
P2=P2&0x1f|0xe0; P0=~Display1[i];
P2=P2&0x1f;
}
if(Display_mode==1)
{
P2=P2&0x1f|0xe0; P0=~Display2[i];
P2=P2&0x1f;
}
if(Display_mode==2)
{
P2=P2&0x1f|0xe0; P0=~Display3[i];
P2=P2&0x1f;
}
i++;
if(i==8)
i=0;
}
if(adc_count==100)
{
adc_count=0;
Read_adc_flag=1;
}
}
按鍵部分
#include "key.h"
unsigned char Key_init()
{
static unsigned char key_state=0;
unsigned char key1,key2;
unsigned char key_press;
unsigned char key_val;
P30=0; P31=0; P32=0; P33=0; P34=1; P35=1; P42=1; P44=1;
if(P34==0) key1=0xe0;
if(P35==0) key1=0xd0;
if(P42==0) key1=0xb0;
if(P44==0) key1=0x70;
if((P34==1)&&(P35==1)&&(P42==1)&&(P44==1))
key1=0xf0;
P30=1; P31=1; P32=1; P33=1; P34=0; P35=0; P42=0; P44=0;
if(P30==0) key2=0x0e;
if(P31==0) key2=0x0d;
if(P32==0) key2=0x0b;
if(P33==0) key2=0x07;
if((P30==1)&&(P31==1)&&(P32==1)&&(P33==1))
key2=0x0f;
key_press = key1|key2;
switch(key_state)
{
case 0:
if(key_press!=0xff)
key_state = 1;
break;
case 1:
if(key_press!=0xff)
{
if(key_press==0x7e) key_val=7;
if(key_press==0x7d) key_val=6;
if(key_press==0x7b) key_val=5;
if(key_press==0x77) key_val=4;
if(key_press==0xbe) key_val=11;
if(key_press==0xbd) key_val=10;
if(key_press==0xbb) key_val=9;
if(key_press==0xb7) key_val=8;
if(key_press==0xde) key_val=15;
if(key_press==0xdd) key_val=14;
if(key_press==0xdb) key_val=13;
if(key_press==0xd7) key_val=12;
if(key_press==0xee) key_val=19;
if(key_press==0xed) key_val=18;
if(key_press==0xeb) key_val=17;
if(key_press==0xe7) key_val=16;
key_state = 2;
}
else
key_state = 0;
break;
case 2:
if(key_press==0xff)
key_state = 0;
break;
}
return key_val;
}
led模組
#include "hardware.h"
void All_init()
{
P2=(P2&0x1f)|0x80; //關閉led
P0=0xff;
P2=P2&0x1f;
P2=(P2&0x1f)|0xA0; //關閉蜂鳴器、繼電器
P0=0x00;
P2=P2&0x1f;
}
void Ledlight(unsigned char led_val)
{
P0=0xff;
P2=(P2&0x1f)|0x80;
P0=led_val;
P2=P2&0x1f;
}
iic模組
/*
程式說明: IIC匯流排驅動程式
軟體環境: Keil uVision 4.10
硬體環境: CT107微控制器綜合實訓平臺(12MHz)
日 期: 2011-8-9
*/
#include "iic.h"
//匯流排啟動條件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
somenop;
SDA = 0;
somenop;
SCL = 0;
}
//匯流排停止條件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
somenop;
SDA = 1;
}
/*IIC匯流排協定規定,每傳送一個位元組資料後,都要有一個應答訊號,以確定資料傳送是否被對方收到,
應答訊號由接收裝置產生,在SCL為高電平期間,接收裝置將SDA拉為低電平表示資料傳輸正確,即產生了應答。*/
//應答位控制
void IIC_Ack(unsigned char ackbit) //當ackbit為1時,表示微控制器對從裝置傳送來資料的應答
//當ackbit為0時,表示主機接收了最後一個位元組,因此不再應答,結束通訊
{
if(ackbit)
{
SDA = 0;
}
else
{
SDA = 1;
}
somenop;
SCL = 1;
somenop;
SCL = 0;
SDA = 1;
somenop;
}
//等待應答
bit IIC_WaitAck(void)
{
SDA = 1;
somenop;
SCL = 1;
somenop;
if(SDA) //在SCL為高電平期間,因為接收裝置未將SDA拉低,所以預設未接收到應答,結束IIC通訊
{
SCL = 0;
IIC_Stop();
return 0;
}
else //接收到應答,返回1,繼續下一個資料位元組的傳輸
{
SCL = 0;
return 1;
}
}
//通過I2C匯流排傳送資料
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(byt&0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
somenop;
SCL = 1;
byt <<= 1;
somenop;
SCL = 0;
}
}
//從I2C匯流排上接收資料
unsigned char IIC_RecByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 1;
somenop;
da <<= 1;
if(SDA)
da |= 0x01;
SCL = 0;
somenop;
}
return da;
}
void Write_eeprom(unsigned char addr,unsigned char dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
unsigned char Read_eeprom(unsigned char addr)
{
unsigned char temp;
ET0=0;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_Ack(0);
IIC_Stop();
ET0=1;
return temp;
}
unsigned char Read_pcf8591(unsigned char addr)
{
unsigned char temp;
ET0=0;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_Ack(0);
IIC_Stop();
ET0=1;
return temp;
}
(iic.h檔案中定義的somenop為5個_nop_(),程式設計時應改為25個)
延時模組
#include "delay.h"
void Delay1ms() //@12.000MHz
{
unsigned char i, j;
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
void delayms(unsigned char ms)
{
unsigned char i;
for(i=0;i<ms;i++)
Delay1ms();
}
以上就是程式碼全部內容,歡迎交流~