前言
第三届省赛的蓝桥杯代码部分是比较简单的,因为举办得比较早,所以比赛的形式可能也有所不同,我在这里就主要讲解的是代码部分,其他的题目如果读者感兴趣的话可自行去了解。
如果基础不太好的读者呢可去看我的一个讲得很详细的文章,这个文章很适合初学者去学,把基础打好之后,做其他的也就信手拈来了。
蓝桥杯单片机STC15F2K60S2第十三届省赛代码详细讲解(附完整代码)
题目
过多的我就不赘述了,因为在我第十三届省赛代码那里我已经写过了,所以这里我就直接放出完整代码了。
完整代码
iic.c
/* # I2C代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include "iic.h"
#include "intrins.h"
#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);
}
float Read_Output(unsigned char Channle)
{
unsigned char ADC;
float Byte;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(Channle);
I2CWaitAck();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
ADC=I2CReceiveByte();
I2CSendAck(1);
Byte=ADC*5/255;
return Byte;
}
iic.h
#ifndef __IIC_H__
#define __IIC_H__
#include <stc15.h>
#define sda P21
#define scl P20
float Read_Output(unsigned char Channle);
#endif
display.c
#include <STC15F2K60S2.H>
code unsigned char Number[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90
};
code unsigned char FNumber[]={
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10
};
void Delayms(int ms) //@12.000MHz
{
unsigned char data i, j;
int k=0;
for(k=0;k<ms;k++)
{
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
}
void Select_HC573(unsigned char Number)
{
switch(Number)
{
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;
}
P2=(P2 &0x1f)|0x00;
}
void System_Init(void)
{
P0=0x00;
Select_HC573(5);
Select_HC573(6);
P0=0xff;
Select_HC573(4);
}
void Display_Number(unsigned char Pos,unsigned char Data)
{
P0=0x01<<Pos-1;
Select_HC573(6);
P0=Number[Data];
Select_HC573(7);
Delayms(1);
P0=0x01<<Pos-1;
Select_HC573(6);
P0=0xff;
Select_HC573(7);
}
void Display_FNumber(unsigned char Pos,unsigned char Data)
{
P0=0x01<<Pos-1;
Select_HC573(6);
P0=FNumber[Data];
Select_HC573(7);
Delayms(1);
P0=0x01<<Pos-1;
Select_HC573(6);
P0=0xff;
Select_HC573(7);
}
void Display_LED(unsigned char Number,unsigned char State)
{
static unsigned char temp=0xff;
if(State)
{
switch(Number)
{
case 1:temp &=0xfe;break;
}
}
else
{
switch(Number)
{
case 1:temp |=0x01;break;
}
}
P0=temp;
Select_HC573(4);
}
void Display_Relay(unsigned char State)
{
static unsigned char temp=0x00;
if(State)
{
temp |=0x10;
}
else
{
temp &=0x00;
}
P0=temp;
Select_HC573(5);
}
display.h
#ifndef __DISPLAY_H__
#define __DISPLAY_H__
void System_Init(void);
void Delayms(int ms); //@12.000MHz
void Display_Number(unsigned char Pos,unsigned char Data);
void Display_LED(unsigned char Number,unsigned char State);
void Display_FNumber(unsigned char Pos,unsigned char Data);
void Display_Relay(unsigned char State);
#define ON 1
#define OFF 0
#endif
main.c
#include <STC15F2K60S2.H>
#include "display.h"
#include "iic.h"
void Key_Board(void);
void Show_Switch(void);
void PCF(void);
void Timer0_Init(void); //20毫秒@12.000MHz
unsigned char Switching=0;
int total=0;
int Money=0;
unsigned char Count;
unsigned char OutFlag=0;
void main(void)
{
System_Init();
Timer0_Init();
while(1)
{
Key_Board();
Show_Switch();
PCF();
}
}
void Key_Board(void)
{
unsigned char Key;
P44=0;P3 |=0x0f;
Key=P3;Key &=0x03;
if(Key !=0x03)
{
Delayms(5);
if(Key !=0x03)
{
switch(Key)
{ //S6
case 0x01:OutFlag=0;
Switching=1;
TR0=0;Display_Relay(OFF);
break;
case 0x02:
if(OutFlag==0)
{
OutFlag=1;
TR0=1;
Display_Relay(ON);
}
break;
}
}
while(Key !=0x03)
{
Key=P3;Key &=0x03;
Show_Switch();
}
}
}
void Show_Switch(void)
{
if(Switching==0)
{
Display_FNumber(2,0);Display_Number(3,5);Display_Number(4,0);
Display_Number(5,total/10000);Display_FNumber(6,total/1000%10);Display_Number(7,total/100%10);Display_Number(8,total/10%10);
if(total == 99999)
{
Switching=1;
}
}
else
{
Display_FNumber(2,0);Display_Number(3,5);Display_Number(4,0);
Display_Number(5,Money/10000);Display_FNumber(6,Money/1000%10);Display_Number(7,Money/100%10);Display_Number(8,Money/10%10);
}
}
void PCF(void)
{
if(Read_Output(0x01)<1.25)Display_LED(1,ON);
else Display_LED(1,OFF);
}
void Timer0_Isr(void) interrupt 1
{
Count++;
if(Count==50)
{
Count=0;
total+=100;
Money=total*0.5;
}
}
void Timer0_Init(void) //20毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xE0; //设置定时初始值
TH0 = 0xB1; //设置定时初始值
TF0 = 0; //清除TF0标志
// TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA=1;
}