在蓝桥杯单片机比赛中,有几个常用外设,只要将这些外设学会就可以应对比赛。
省赛考点:LED、蜂鸣器、继电器、数码管、独立键盘、矩阵键盘、实时时钟、数模\模数转换、EEPROM储存器、温度传感器、定时计数器、中断等
国赛考点:LED、蜂鸣器、继电器、数码管、独立键盘、矩阵键盘、实时时钟、数模\模数转换、EEPROM储存器、温度传感器、定时计数器、中断、超声波距离传感器、NE555、串口通信(第十届)等
#include "reg52.h"
#include "iic.h"
#include "onewire.h"
#include "ds1302.h"
//矩阵按键
sfr P4 = 0xc0;
sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;
sbit C1 = P4^4;
sbit C2 = P4^2;
sbit C3 = P3^5;
sbit C4 = P3^4;
void scankeys()
{
R1 = 0;
R2 = R3 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if (C1 == 0)
{
delay(1000);
if (C1 == 0)
{
//添加所需功能
while(C1 == 0);
}
}
else if (C2 == 0)
{
delay(1000);
if (C2 == 0)
{
//添加所需功能
while(C2 == 0);
}
}
else if (C3 == 0)
{
delay(1000);
if (C3 == 0)
{
//添加所需功能
while(C3 == 0);
}
}
else if (C4 == 0)
{
delay(1000);
if (C4 == 0)
{
//添加所需功能
while(C4 == 0);
}
}
R2 = 0;
R1 = R3 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if (C1 == 0)
{
delay(1000);
if (C1 == 0)
{
//添加所需功能
while(C1 == 0);
}
}
else if (C2 == 0)
{
delay(1000);
if (C2 == 0)
{
//添加所需功能
while(C2 == 0);
}
}
else if (C3 == 0)
{
delay(1000);
if (C3 == 0)
{
//添加所需功能
while(C3 == 0);
}
}
else if (C4 == 0)
{
delay(1000);
if (C4 == 0)
{
//添加所需功能
while(C4 == 0);
}
}
R3 = 0;
R1 = R2 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if (C1 == 0)
{
delay(1000);
if (C1 == 0)
{
//添加所需功能
while(C1 == 0);
}
}
else if (C2 == 0)
{
delay(1000);
if (C2 == 0)
{
//添加所需功能
while(C2 == 0);
}
}
else if (C3 == 0)
{
delay(1000);
if (C3 == 0)
{
//添加所需功能
while(C3 == 0);
}
}
else if (C4 == 0)
{
delay(1000);
if (C4 == 0)
{
//添加所需功能
while(C4 == 0);
}
}
R4 = 0;
R1 = R2 = R3 = 1;
C1 = C2 = C3 = C4 = 1;
if (C1 == 0)
{
delay(1000);
if (C1 == 0)
{
//添加所需功能
while(C1 == 0);
}
}
else if (C2 == 0)
{
delay(1000);
if (C2 == 0)
{
//添加所需功能
while(C2 == 0);
}
}
else if (C3 == 0)
{
delay(1000);
if (C3 == 0)
{
//添加所需功能
while(C3 == 0);
}
}
else if (C4 == 0)
{
delay(1000);
if (C4 == 0)
{
//添加所需功能
while(C4 == 0);
}
}
}
//数码管
void select_HC573(unsigned char n)
{
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;
}
}
void delay(unsigned int t)
{
while(t--);
}
void display_smg(unsigned char pos,unsigned char value)
{
select_HC573(7);
P0 = 0xff;
select_HC573(6);
P0 = 0x01 << pos;
select_HC573(7);
P0 = value;
}
void closeall()
{
select_HC573(6);
P0 = 0xff;
select_HC573(7);
P0 = 0xff;
}
//实时时钟
write_1302[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
read_1302[7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
timer[7] = {0x00,0x59,0x06}; //秒,分,时,日,月,周,年
void timeconfing()
{
unsigned char i = 0;
Write_Ds1302_Byte(0x8e,0x00);
for (i = 0;i < 3;i ++)
{
Write_Ds1302_Byte(write_1302[i],timer[i]);
}
Write_Ds1302_Byte(0x8e,0x80);
}
void time_show()
{
unsigned char i = 0;
for (i = 0;i < 3;i ++)
{
timer[i] = Read_Ds1302_Byte(read_1302[i]);
}
Write_Ds1302_Byte(0x8e,0x80);
}
duanma[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
void display_1302time()
{
display_smg(0,duanma[time[2] / 16]);
delay(300);
display_smg(1,duanma[time[2] % 16]);
delay(300);
display_smg(2,0xff);
delay(300);
display_smg(3,duanma[time[1] / 16]);
delay(300);
display_smg(4,duanma[time[1] % 16]);
delay(300);
display_smg(5,0xff);
delay(300);
display_smg(6,duanma[time[1] / 16]);
delay(300);
display_smg(7,duanma[time[1] % 16]);
delay(300);
closeall();
delay(300);
}
//BCD码的加减
unsigned char Timeradd(unsigned char dat)
{
dat = dat + 1;
switch(dat)
{
case 10:
dat = 16;break; //BCD的10
case 26:
dat = 32;break; //BCD的20
case 42:
dat = 48;break; //BCD的30
case 58:
dat = 64;break; //BCD的40
case 74:
dat = 80;break; //BCD的50
case 90:
dat = 96;break; //BCD的60
}
return dat;
}
unsigned char Timerminus(unsigned char dat)
{
dat = dat - 1;
switch(dat)
{
case 79:
dat = 73;break;
case 63:
dat = 57;break;
case 47:
dat = 41;break;
case 31:
dat = 25;break;
case 15:
dat = 9;break;
case -1:
dat = 89;break;
}
return dat;
}
//温度
void read_temperature()
{
unsigned char LSB,MSB;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
delay(10000);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB = Read_DS18B20();
MSB = Read_DS18B20();
init_ds18b20();
temp = 0x0000;
temp = MSB;
temp = (temp << 8) | LSB;
if((temp & 0xf800) == 0x0000)
{
temp >>= 4;
temp *= 10;
temp += (LSB & 0x0f) * 0.625; //这个是实际温度的十倍
//若一直显示不出来可将onewire.c中的延迟时间都增加十倍
}
}
//PCF8591
void write_8591(unsigned char dat)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x40);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
void read_8591()
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(addr); //只有A/D功能是0x01光敏电阻,0x03电位器;A/D和D/A功能都有则0x41光敏电阻,0x43电位器
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
msg = IIC_RecByte();
IIC_WaitAck();
IIC_SendAck(0);
IIC_WaitAck();
IIC_Stop();
}
//AT24C02
void write_C02(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();
}
void read_C02(unsigned char addr)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
msg = IIC_RecByte();
IIC_WaitAck();
IIC_SendAck(0);
IIC_WaitAck();
IIC_Stop();
}
//NE555
void init_time()
{
TMOD = 0x16;
TH0 = 0xff; //八位重装计数
TL0 = 0xff;
TH1 = (65535 - 50000) / 256;
TL1 = (65535 - 50000) % 256; //50ms
EA = 1;
ET0 = 1;
ET1 = 1;
TR0 = 1;
TR1 = 1;
}
void service_f() interrupt 1
{
count_f ++;
}
void service_t() interrupt 3
{
TH1 = (65535 - 50000) / 256;
TL1 = (65535 - 50000) % 256; //50ms
count ++;
if (count == 20)
{
f = count_f; //频率
count = 0;
count_f = 0;
}
}
//超声波
#include "intrins.h"
sbit TX = P1^0;
sbit RX = P1^1;
void delay12()
{
_nop_();
_nop_();
unsigned int i = 33;
while(--i);
}
void send_wave()
{
unsigned char i ;
for(i = 0;i < 8;i ++)
{
TX = 1;
delay12();
TX = 0;
delay12();
}
}
void distance()
{
unsigned int time = 0;
TMOD &= 0x0f;
TL1 = 0x00;
TH1 = 0x00;
send_wave();
TR1 = 1;
while((RX == 1) | (TF1 == 0));
TR1 = 1;
if (TF1 == 0)
{
time = TH1;
time <<= 8;
time = time | TL1;
d = ((time /10) *17) + 3; //单位cm
}
else
{
TF1 = 0;
d = 999; //超量程
}
}
//串口通信
sbit AUXR = 0x8e;
void init_uart()
{
TMOD = 0x21;
TH1 = 0xfd;
TL1 = 0xfd;
TR1 = 1;
ES = 1;
EA = 1;
AUXR = 0x00;
SCON = 0x50;
}
void servixe_uart() interrupt 4
{
if (RI == 1)
{
dat = SBUF;
RI = 0;
}
}
void sendbyte(unsigned char dat)
{
SBUF = dat;
while(TI == 0);
TI = 0;
}
void sendstring(unsigned char *str)
{
while(*str != '\0')
{
sendbyte(*str);
str ++;
}
}
void main()
{
while(1)
{}
}