题目
mian.c
#include<stc15f2k60s2.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
int read_vol( );
uchar read_vre(unsigned char add);
void write_vre(uchar add, uchar dat);
#define s0 0x00
#define s1 0x01
#define s2 0x02
uchar state = s0;
uchar disstate = s0;
uchar count_state = s0;
uchar led_state = s0;
uint count_error = 0;
//uchar keymap[4][4] = {{0x81, 0x41, 0x21, 0x11}, {0x82, 0x42, 0x22, 0x12}, {0x84, 0x44, 0x24, 0x14}, {0x88, 0x48, 0x28, 0x18}};
char vre;
uint vol;
uchar count_negedge = 0;
uchar semg_bit[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
uchar semg[14] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90,
0xc1, 0x8c, 0xab, 0xff};
uchar semg_temp[8] = {13, 13, 13, 13, 13, 13, 13, 13};
void Timer0Init(void) //2毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x9A; //设置定时初值
TH0 = 0xA9; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA = 1;
ET0 = 1;
}
void display()
{
int i;
P0 = 0xff; P2 = 0xc0;
_nop_();_nop_();
P0 = 0xff; P2 = 0xe0;
_nop_();_nop_();
P2 = 0x00;
if( (disstate == s0) || (disstate == s1) )
{
if(i == 5) {P2 = 0xe0; P0 = semg[semg_temp[i]] & 0x7f;}
else {P2 = 0xe0; P0 = semg[semg_temp[i]];}
P2 = 0xc0; P0 = semg_bit[i];
}
else
{
if(i == 5)
{
if(semg_temp[i] == 0) {P2 = 0xe0; P0 = semg[13];}
else {P2 = 0xe0; P0 = semg[semg_temp[i]];}
}
else {P2 = 0xe0; P0 = semg[semg_temp[i]];}
P2 = 0xc0; P0 = semg_bit[i];
}
P2 = 0x00; P0 = 0xff;
//_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
i++;
if(i == 8) i = 0;
}
void led()
{
static int time_count = 0;
P0 = 0xff; P2 = 0x80;
_nop_();_nop_();
switch(led_state)
{
case s0: //等待Vin < vp的时间大于等于5秒,实际上等于5秒时就应该进入s1
{
if(vol < vre * 10)
{
time_count++;
if(time_count == 500*5)
led_state = s1;
else
led_state = s0;
}
else
{
led_state = s0;
time_count = 0;
}
} break;
case s1: //vin < vp时间大于等于5秒,点亮led1, 同时等待vin < vp将led1熄灭
{
if(vol >= vre * 10)
{
led_state = s0;
time_count = 0;
P2 = 0x80; P00 = 0;
}
else
{
led_state = s1;
P2 = 0x80; P00 = 0;
}
} break;
default: led_state = s0; break;
}
if(count_negedge % 2 == 1) {P2 = 0x80; P01 = 0;}
else {P2 = 0x80; P01 = 1;}
if(count_error >= 3) {P2 = 0x80; P02 = 0;}
else {P2 = 0x80; P02 = 1;}
P2 = 0x80; P0 = P0 | 0xf8;
//_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
P2 = 0x00; P0 = 0xff;
}
void display_led() interrupt 1
{
uchar i;
if(i == 50)
{
vol = read_vol();
i = 0;
}
led();
display();
i++;
}
char keybordscan()
{
uchar keyrow, keycolumn, keycode;
char keyvalue_temp, i, j;
static char keyvalue = -10,keystate = s0;
P44 = 0;P42 = 0;P3 = 0x0f;
keycolumn = P3 & 0x0f;
P44 = 1;P42 = 1;P3 = 0xf0;
if(!P44) keyrow = 0x70;
else if(!P42) keyrow = 0xb0;
else if(P3!=0xf0) keyrow = P3 & 0xf0;
else keyrow = 0xf0;
keycode = ~(keycolumn | keyrow);
switch(keystate)
{
case s0:
if(keycode)
keystate = s1;
else
keyvalue = -10;
break;
case s1:
{
if(keycode)
{
for(i = 0; i<4; i++)
for(j = 0; j<4; j++)
if( keycode == ( (0x80>>j) | (0x01<<i) ) )
{
keyvalue_temp = i*4 + j;
keyvalue = keyvalue_temp;
break;
}
else ;
keystate = s2;
}
else
keystate = s0;
} break;
case s2:
{
keyvalue = -10;
if(!keycode) keystate = s0;
else keystate = s2;
} break;
default:
keystate = s0;
break;
}
//semg_temp[2] = (keyvalue + 10) / 10;
//semg_temp[3] = (keyvalue + 10) % 10;
return keyvalue;
}
void counter_negedge( )
{
//semg_temp[2] = vol/100;
//semg_temp[3] = (vol - semg_temp[2] * 100)/10;
//semg_temp[4] = vol % 10;
switch(count_state)
{
case s0:
{
if(vol <= vre * 10)
count_state = s0;
else //测得电压vin大于参考电压vp,进入S1状态,等待测得电压Vin小于vp
count_state = s1;
} break;
case s1:
{
if(vol >= vre * 10)
count_state = s1;
else //s1状态测得电压vin小于参考电压vp,计数值加一,回到S0状态
{
count_negedge++;
count_state = s0;
}
} break;
default: count_state = s0; break;
}
}
void menu(char keyvalue)
{
switch(state)
{
case s0: //测电压界面,显示在定时器0
{
semg_temp[0] = 10;
semg_temp[5] = vol/100;
semg_temp[6] = (vol - semg_temp[5] * 100)/10;
semg_temp[7] = vol % 10;
if(keyvalue == 14)
{
disstate = s1;
state = s1;
count_error = 0;
}
else if( (keyvalue != 14) && (keyvalue != -10) )
count_error++;
else ;
} break;
case s1: //修改参考电压界面,显示在定时器0
{
semg_temp[0] = 11;
semg_temp[5] = vre/10;
semg_temp[6] = vre % 10;
semg_temp[7] = 0;
if(keyvalue == 14)
{
disstate = s2;
state = s2;
count_error = 0;
write_vre(0, vre);
}
else if(keyvalue == 15)
{
vre = vre + 5;
if(vre > 50)
vre = 0;
count_error = 0;
write_vre(0, vre);
}
else if(keyvalue == 11)
{
vre = vre - 5;
if(vre < 0)
vre = 50;
count_error = 0;
write_vre(0, vre);
}
else if( (keyvalue != -10) && (keyvalue != 11) && (keyvalue != 14) && (keyvalue != 15) )
count_error++;
else ;
} break;
case s2: //计数界面,显示在定时器0
{
semg_temp[0] = 12;
semg_temp[5] = count_negedge/100;
semg_temp[6] = (count_negedge - semg_temp[5] * 100)/10;
semg_temp[7] = count_negedge % 10;
counter_negedge( );
if(keyvalue == 10)
{
count_negedge = 0;
count_error = 0;
}
else if(keyvalue == 14)
{
disstate = s0;
state = s0;
count_error = 0;
}
else if( (keyvalue != -10) && (keyvalue != 10) && (keyvalue != 14) )
count_error++;
} break;
default:
{
disstate = s0;
state = s0;
} break;
}
}
void init_all()
{
P2 = 0xc0; P0 = 0xff;
P2 = 0xe0; P0 = 0xff;
P2 = 0xa0; P0 = 0x00;
P2 = 0x80; P0 = 0xff;
}
void main()
{
char keyvalue;
init_all();
Timer0Init();
vre = read_vre(0);
if( (vre % 5 != 0) || (vre > 50) || (vre < 0) )
vre = 30;
while(1)
{
keyvalue = keybordscan();
menu(keyvalue);
}
}
IIC.c
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include<stc15f2k60s2.h>
#include "intrins.h"
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
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;
}
bit IIC_WaitAck(void)
{
SDA = 1;
somenop;
SCL = 1;
somenop;
if(SDA)
{
SCL = 0;
IIC_Stop();
return 0;
}
else
{
SCL = 0;
return 1;
}
}
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;
}
}
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_vre(unsigned char add,unsigned char dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
unsigned char read_vre(unsigned char add)
{
unsigned char dat;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
dat=IIC_RecByte();
IIC_Stop();
return dat;
}
int read_vol( )
{
int dat;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
dat=IIC_RecByte();
IIC_Stop();
dat=dat*1.96078;
return dat;
}