第11届蓝桥杯单片机省赛首场竞赛代码解析
目录
一,题目
二,题目难点及分析
1,固定的模块:
2,改变的地方:
3,我觉得的难点:
三,代码参考:
main.c
IIC.c
IIC.H
四,有不完美的地方,请见谅。
一,题目
二,题目难点及分析
1,固定的模块:
PCF8591和24C02模块,不懂的同学可以去看看小蜜蜂的强化题目写一下:
【备赛宝典】小蜜蜂老师关于蓝桥杯单片机大赛的独家教程及资源大汇总-小蜜蜂笔记
2,改变的地方:
与前面几届的题目不同的主要是按键变成了矩阵键盘,矩阵键盘我写的十分简单,例如S12,当行R4=0,其余’行列‘为1,只要C2=0时,S12就按键按下:
R4 = 0;
R1 = R2= R3 = 1;
C1 = C2 = C3 = C4 = 1;
if (C2 == 0) // "S12"
{
Delay(100);
if (C2 == 0)
其他的基本上没有什么改变,不会的可以看看我的代码,或者找老师请教。
3,我觉得的难点:
应该是判断Vpp < param(参数),计数器加1:
我的想法是设置两个变量stat_volt开始电压和old_volt大于param的先前电压,只要满足(old_volt > param && param > SMG_volt),便可以加1。
三,代码参考:
main.c
#include "STC15.H"
#include "IIC.h"
#define uchar unsigned char
#define uint unsigned int
sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;
sbit C1 = P3^4;
sbit C2 = P3^5;
sbit C3 = P4^2;
sbit C4 = P4^4;
uchar code SMG_NoDot[18]={0xc0,0xf9,
0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
uchar code SMG_Dot[10]={0x40,0x79,
0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
uint DAC_value = 0;
float DAC_volt = 0;
uint SMG_volt = 0;
uint param = 0;
uchar stat_led = 0xff;
uchar count_v = 0;
uchar mode = 3;
uchar count = 0;
uint stat_volt = 0;
uint old_volt = 0;
uchar dat_error = 0;
uchar F_time = 0;
uchar dat_24c02 = 0;
void Delay(uint t)
{
while(t--);
}
void Select_HC573(uchar n,uchar dat)
{
P2 = (P2 & 0x1f) | 0x00;
P0 = dat;
switch(n)
{
case 4:
P2 = (P2 & 0x1f) | 0x80;
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0;
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;
break;
case 0:
P2 = (P2 & 0x1f) | 0x00;
break;
}
P2 = (P2 & 0x1f) | 0x00;
}
void Choose_SMG(uchar dat,uchar pos)
{
Select_HC573(6,0x01 << pos);
Select_HC573(7,dat);
Delay(500);
Select_HC573(6,0x01 << pos);
Select_HC573(7,0xff);
}
void Display_SMG()
{
switch(mode)
{
case 1:
Choose_SMG(0xc1,0); //1100 0001 "U"
Delay(100);
Choose_SMG(SMG_Dot[SMG_volt / 100],5);
Delay(100);
Choose_SMG(SMG_NoDot[(SMG_volt / 10) % 10],6);
Delay(100);
Choose_SMG(SMG_NoDot[SMG_volt % 10],7);
Delay(100);
break;
case 2:
Choose_SMG(0x8C,0); //1000 1100 "P"
Delay(100);
Choose_SMG(SMG_Dot[param / 100],5);
Delay(100);
Choose_SMG(SMG_NoDot[(param / 10) % 10],6);
Delay(100);
Choose_SMG(SMG_NoDot[param % 10],7);
Delay(100);
break;
case 3:
Choose_SMG(0xc8,0); //1100 1000 "n"
Delay(100);
if(count_v > 9)
{
Choose_SMG(SMG_NoDot[(count_v / 10) % 10],6);
}
Delay(100);
Choose_SMG(SMG_NoDot[count_v % 10],7);
Delay(100);
break;
}
}
void Init_Timer()
{
TH0 = (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
TMOD = 0x01;
ET0 = 1;
TR0 = 1;
EA = 1;
}
void Service_Timer0() interrupt 1
{
TH0 = (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
if(stat_volt == 0)
{
stat_volt = 1;
old_volt = SMG_volt;
}
else
{
if (old_volt > param && param > SMG_volt)
{
count_v++;
if (count_v >= 100)
{
count_v = 0;
}
if(count_v % 2 == 0)
{
stat_led |= 0x02;
Select_HC573(4,stat_led);
}
else
{
stat_led &= ~0x02;
Select_HC573(4,stat_led);
}
}
old_volt = SMG_volt;
}
if(F_time == 1)
{
count++;
if(count >= 100)
{
if(SMG_volt < param)
{
stat_led &= ~0x01;
Select_HC573(4,stat_led);
F_time = 0;
}
}
}
}
void write_24c02(uchar addree,uchar dat)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addree);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
uchar read_24c02(uchar addree)
{
uchar tmp;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addree);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
tmp = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return tmp;
}
uchar Read_PCF8591_AIN()
{
uchar tmp;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x03);
I2CWaitAck();
Display_SMG();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
tmp = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return tmp;
}
void Vpp_work()
{
uchar i;
for(i = 0;i < 3;i++)
{
DAC_value += Read_PCF8591_AIN();
}
DAC_value = DAC_value / 3;
DAC_volt = DAC_value * (5.0 / 255);
SMG_volt = DAC_volt * 100;
if(SMG_volt < param)
{
if(F_time == 0)
{
F_time = 1;
}
}
else
{
F_time = 0;
count = 0;
stat_led |= 0x01;
Select_HC573(4,stat_led);
}
Display_SMG();
Select_HC573(4,stat_led);
}
void Scan_keys()
{
R4 = 0;
R1 = R2= R3 = 1;
C1 = C2 = C3 = C4 = 1;
if(C2 == 0) // "S12"
{
Delay(100);
if(C2 == 0)
{
dat_error = 0;
if(mode == 3)
{
mode = 1;
}
else if(mode == 1)
{
mode = 2;
}
else if(mode == 2)
{
mode = 3;
dat_24c02 = param / 10;
write_24c02(0x00,dat_24c02);
}
while(C2 == 0)
{
Vpp_work();
}
}
}
if(C1 == 0) // "S16"
{
Delay(100);
if(C1 == 0)
{
if(mode == 2)
{
dat_error = 0;
if(param < 500)
{
param = param + 50;
}
else
{
param = 0;
}
}
else
{
dat_error++;
}
while(C1 == 0)
{
Vpp_work();
}
}
}
R3 = 0;
R1 = R2 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if(C1 == 0) // "S17"
{
Delay(100);
if(C1 == 0)
{
if(mode == 2)
{
dat_error = 0;
if(param <= 500)
{
param = param - 50;
}
else
{
param = 500;
}
}
else
{
dat_error++;
}
while(C1 == 0)
{
Vpp_work();
}
}
}
if(C2 == 0) //"S13"
{
Delay(100);
if(C2 == 0)
{
if(mode == 3)
{
dat_error = 0;
count_v = 0;
}
else
{
dat_error++;
}
while(C2 == 0)
{
Vpp_work();
}
}
}
}
void key_err()
{
if(dat_error >= 3)
{
stat_led &= ~0x04;
Select_HC573(4,stat_led);
}
else
{
stat_led |= 0x04;
Select_HC573(4,stat_led);
}
}
void Init_System()
{
Select_HC573(0,0x00);
Select_HC573(5,0x00);
Select_HC573(4,0xff);
Select_HC573(6,0xff);
Select_HC573(7,0xff);
dat_24c02 = read_24c02(0x00);
if(dat_24c02 > 500 || dat_24c02 % 5 != 0)
{
dat_24c02 = 0;
}
param = dat_24c02 * 10;
}
void main()
{
Init_System();
Init_Timer();
while(1)
{
Scan_keys();
Vpp_work();
key_err();
}
}
IIC.c
#include "STC15.H"
#include "intrins.h"
sbit sda = P2^1;
sbit scl = P2^0;
#define DELAY_TIME 5
//
static void I2C_Delay(unsigned char n)
{
do
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
while(n--);
}
//
void I2CStart(void)
{
sda = 1;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 0;
I2C_Delay(DELAY_TIME);
scl = 0;
}
//
void I2CStop(void)
{
sda = 0;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 1;
I2C_Delay(DELAY_TIME);
}
//
void I2CSendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++){
scl = 0;
I2C_Delay(DELAY_TIME);
if(byt & 0x80){
sda = 1;
}
else{
sda = 0;
}
I2C_Delay(DELAY_TIME);
scl = 1;
byt <<= 1;
I2C_Delay(DELAY_TIME);
}
scl = 0;
}
//
unsigned char I2CReceiveByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++){
scl = 1;
I2C_Delay(DELAY_TIME);
da <<= 1;
if(sda)
da |= 0x01;
scl = 0;
I2C_Delay(DELAY_TIME);
}
return da;
}
//
unsigned char I2CWaitAck(void)
{
unsigned char ackbit;
scl = 1;
I2C_Delay(DELAY_TIME);
ackbit = sda;
scl = 0;
I2C_Delay(DELAY_TIME);
return ackbit;
}
//
void I2CSendAck(unsigned char ackbit)
{
scl = 0;
sda = ackbit;
I2C_Delay(DELAY_TIME);
scl = 1;
I2C_Delay(DELAY_TIME);
scl = 0;
sda = 1;
I2C_Delay(DELAY_TIME);
}
IIC.H
#ifndef IIC_H
#define IIC_H
void I2CStart(void);
void I2CStop(void);
void I2CSendByte(unsigned char byt);
unsigned char I2CReceiveByte(void);
unsigned char I2CWaitAck(void);
void I2CSendAck(unsigned char ackbit);
#endif
四,有不完美的地方,请见谅。
作者:humanfireworks