1 赛题
2 程序
2.1 main.c
#include "stc15f2k60s2.h"
#include "iic.h"
#define uint8_t unsigned char
#define uint16_t unsigned int
//74HC138
#define Y4C P2 = (P2 & 0x1f) | 0x80
#define Y5C P2 = (P2 & 0x1f) | 0xa0
#define Y6C P2 = (P2 & 0x1f) | 0xd0
#define Y7C P2 = (P2 & 0x1f) | 0xe0
#define OFF P2 = (P2 & 0x1f) | 0x00
//Key_Scan of statement
#define S1 0
#define S2 1
#define S3 2
#define S4 3
uint8_t state = 0;
uint8_t Key = 0;
bit flag_S7_1s = 0;//S7长按标志位
bit LED_model = 1;//0-禁用LED,1-启用LED
//数码管
uint8_t num[]={ //0-9,10-'OFF',11-'F',12-'N',13-'U',14-'-'
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff,0x8E,0xc8,0xc1,0xbf};
uint8_t DispBuff[8] = {10,10,10,10,10,10,10,10};
//UI界面
uint8_t UI_model = 0;//0-频率;1-周期;2-电压
bit UI_Volt = 0;//0-通道1;1-通道2
//NE555
long freq = 0;
long freq_buff = 0;//缓存
//adc
bit flag_AD = 0;
uint16_t Volt = 0;
uint16_t Volt_buff = 0;//电压缓存
uint8_t Rd_Rb = 1;//1-RD1,3-Rb3
void All_Init(void);
void Timer0Init(void); //计时器@12.000MHz
void Timer1Init(void); //1毫秒@12.000MHz
void Display(void);
uint8_t Key_Scan(void);
void Fre_Show(void);
void Cycle_Show(void);
void Set_S4(void);
void AD_Show(void);
void Set_S5(void);
void Set_S5(void);
void Set_S6(void);
void Set_S5(void);
void Set_S7(void);
void Delay5us(void); //@12.000MHz
void LED_Set(void);
void main(void)
{
All_Init();
Timer0Init();
Timer1Init();
Fre_Show();
EA = 1;
while(1)
{
switch(Key)
{
case 4:Key = 0;Set_S4();break;
case 5:Key = 0;Set_S5();break;
case 6:Key = 0;Set_S6();break;
case 7:Key = 0;Set_S7();break;
default:break;
}
if(UI_model == 0)
Fre_Show();
else if(UI_model == 1)
Cycle_Show();
else if(UI_model == 2)
{
if(Rd_Rb == 1)
{
if(flag_AD)
{
EA = 0;
Volt = Read_Rd1();
EA = 1;
Volt = Volt * 10 / 51 *10;
AD_Show();
}
}
else
{
if(flag_AD)
{
EA = 0;
Volt = Read_Rb3();
EA = 1;
Volt = Volt * 10 / 51 *10;
AD_Show();
}
}
}
LED_Set();
}
}
void LED_Set(void)
{
uint8_t LED = 0xe0;
uint16_t Volt_Rd3;
if(LED_model)
{
EA = 0;
Volt_Rd3 = Read_Rb3();
EA = 1;
Volt_Rd3 = Volt_Rd3 * 10 / 51 *10;
if(Volt_Rd3 > Volt_buff)
LED = (LED & 0xfe) | 0x00;
else
LED = (LED & 0xfe) | 0x01;
if(freq > freq_buff)
LED = (LED & 0xfd) | 0x00;
else
LED = (LED & 0xfd) | 0x02;
switch(UI_model)
{
case 0:LED = (LED & 0xe3) | 0x18;break;
case 1:LED = (LED & 0xe3) | 0x14;break;
case 2:LED = (LED & 0xe3) | 0x0c;break;
}
Y4C;
P0 = LED;
OFF;
}
else
{
Y4C;
P0 = 0xff;
OFF;
}
}
void Set_S7(void)//分别存在0x03和0x04
{
static uint8_t index =0;
while(state == S3);
if(flag_S7_1s == 0)
{
freq_buff = freq;
}
else
{
flag_S7_1s = 0;
LED_model = ~LED_model;
Y4C;
P0=1<<index;
OFF;
index++;
index&=0x07;
}
}
void Set_S6(void)
{
EA = 0;
Volt_buff = Read_Rb3();
EA = 1;
}
void Set_S5(void)//分别存在0x01和0x02
{
if(UI_model == 2)
{
if(Rd_Rb == 1)
Rd_Rb = 3;
else
Rd_Rb = 1;
}
}
void Set_S4(void)
{
UI_model++;
if(UI_model == 3)
UI_model = 0;
if(UI_model == 2)
Rd_Rb = 1;
}
void AD_Show(void)
{
DispBuff[0] = 13;
DispBuff[1] = 14;
DispBuff[2] = Rd_Rb;
DispBuff[3] = 10;
DispBuff[4] = 10;
DispBuff[5] = Volt / 100;
DispBuff[6] = Volt /10 % 10;
DispBuff[7] = Volt % 10;
}
void Cycle_Show(void)
{
uint8_t buff[7],i=7,j=0;
long Freq_b,cycle;
Freq_b = freq;
cycle = 1000000 / Freq_b;
for(;i != 0;i--)
{
buff[i-1] = cycle % 10;
cycle = cycle / 10;
}
i = 0;
while((buff[i] == 0)&&(i != 6))
{
i++;
}
DispBuff[0] = 12;
for(j= 0;j != i;j++)
{
DispBuff[j+1] = 10;//灭零
}
for(;j<=6;j++)
{
DispBuff[j+1] = buff[j];
}
}
void Fre_Show(void)
{
uint8_t buff[7],i=7,j=0;
long Freq_b;
Freq_b = freq;
for(;i != 0;i--)
{
buff[i-1] = Freq_b % 10;
Freq_b = Freq_b / 10;
}
i = 0;
while((buff[i] == 0)&&(i != 6))
{
i++;
}
DispBuff[0] = 11;
for(j= 0;j != i;j++)
{
DispBuff[j+1] = 10;//灭零
}
for(;j<=6;j++)
{
DispBuff[j+1] = buff[j];
}
}
void T1_Interrupt() interrupt 3
{
static uint8_t Key_cnt = 0,AD_cnt = 0;
static uint16_t freq_cnt = 0;//每0.5s返回一次频率值
AD_cnt++;
if(AD_cnt >= 200)
{
AD_cnt = 0;
flag_AD = 1;
}
if(freq_cnt == 0)
{
freq_cnt ++;
TR0 = 1;
}
else if(freq_cnt > 0 && freq_cnt < 1000)
{
freq_cnt ++;
}
else
{
freq_cnt = 0;
TR0 = 0;
freq = (long)TH0*256+(long)TL0;
TH0 = 0;
TL0 = 0;
}
//按键
Key_cnt ++;
if(Key_cnt == 10)
{
Key_cnt = 0;
if(Key == 0)
Key = Key_Scan();
}
//数码管
Display();
}
void Display(void)
{
static uint8_t index = 0;
Y7C;
P0 = 0xff;
OFF;
Y6C;
P0 = 1 << index;
OFF;
if(UI_model != 2)
{
Y7C;
P0 = num[DispBuff[index]];
OFF;
}
else
{
if(index != 5)
{
Y7C;
P0 = num[DispBuff[index]];
OFF;
}
else
{
Y7C;
P0 = num[DispBuff[index]] & 0x7f;
OFF;
}
}
index++;
index &= 0x07;
}
uint8_t Key_Scan(void)
{
static uint8_t cnt_1s = 0;//长按键
uint8_t locate;
uint8_t num = 0;
EA = 0;
P3 &= 0xff;
locate = P3 & 0x0f;
EA = 1;
switch(state)
{
case S1:{
if(locate != 0x0f)
{
state = S2;
break;
}
else
break;
}
case S2:{
if(locate != 0x0f)
{
state = S3;
switch(locate)
{
case 0x0e:num = 7;break;
case 0x0d:num = 6;break;
case 0x0b:num = 5;break;
case 0x07:num = 4;break;
default:break;
}
break;
}
else
{
state = S1;
break;
}
}
case S3:{
if((locate != 0x0f)&&(cnt_1s < 100))//进入长按扫描
{
cnt_1s ++;
break;
}
else if((locate != 0x0f)&&(cnt_1s >= 100))
{
cnt_1s = 0;
if(locate == 0x0e)
{
flag_S7_1s = 1;//S7长按标志位
state = S4;
}
else
state = S4;
break;
}
else
{
cnt_1s = 0;
state = S1;
break;
}
}
case S4:{
if(locate != 0x0f)
break;
else
{
state = S1;
break;
}
}
}
return num;
}
void Timer0Init(void) //计时器@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x05; //设置为计数器模式
TL0 = 0x00; //设置定时初值
TH0 = 0x00; //设置定时初值
TF0 = 0; //清除TF0标志
//TR0 = 1; //计时器0开始计时
//主动操控
}
void Timer1Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x20; //设置定时初值
TH1 = 0xD1; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1; //定时器1中断启动
}
void All_Init(void)
{
Y4C;
P0 = 0xff;
OFF;
Y5C;
P0 = 0xaf;
OFF;
}
void Delay5us() //@12.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 12;
while (--i);
}
1.1 iic.c
#include "iic.h"
#define DELAY_TIME 5
//I2C总线内部延时函数
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//I2C总线启动信号
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//I2C总线停止信号
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//发送应答或非应答信号
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit;
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//I2C总线发送一个字节数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//I2C总线接收一个字节数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
unsigned char Read_Rd1(void)
{
unsigned char dat;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x01);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
dat = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return dat;
}
unsigned char Read_Rb3(void)
{
unsigned char dat;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
dat = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return dat;
}
2.3 iic.h
#ifndef _IIC_H
#define _IIC_H
#include "stc15f2k60s2.h"
#include "intrins.h"
sbit SDA = P2^1;
sbit SCL = P2^0;
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
unsigned char Read_Rd1(void);
unsigned char Read_Rb3(void);
#endif