> 文章列表 > 蓝桥杯单片机模块代码汇总

蓝桥杯单片机模块代码汇总

蓝桥杯单片机模块代码汇总

目录

 

1.HC573锁存器选择

2.系统初始化关闭LED、蜂鸣器和继电器

3.LED

4.蜂鸣器和继电器

5.数码管

6.定时器按键扫描

7.DS18B20(基于2023年第十四届底层代码

8.DS1302(基于2023年第十四届底层代码)

9.PCF8591(基于2023年第十四届底层代码)

10.超声波PCA版(可节省出一个定时器)

11.NE555测量频率


 

 

1.HC573锁存器选择

void Select_Hc573(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;}P2 = P2 & 0x1f;
}

2.系统初始化关闭LED、蜂鸣器和继电器

void Sys_Init()
{P0 = 0x00;Select_Hc573(5);P0 = 0xff;Select_Hc573(4);
}

3.LED

void Led(unsigned addr,enable)//LED底层代码
{static unsigned char temp = 0x00;static unsigned char temp_old = 0xff;if(enable)temp |= 0x01 << addr;elsetemp &= ~(0x01 << addr);if(temp != temp_old){P0 = ~temp;Select_Hc573(4);temp_old = temp;}
}

4.蜂鸣器和继电器

void Beep(unsigned addr,enable)
{static unsigned char temp = 0x00;static unsigned char temp_old = 0xff;if(enable)temp |= 0x01 << addr;elsetemp &= ~(0x01 << addr);if(temp != temp_old){P0 = temp;Select_Hc573(5);temp_old = temp;}
}

5.数码管

code unsigned char SMG[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};void Delay_ms(unsigned int t)		//@12.000MHz
{while(t--){unsigned char i, j;i = 12;j = 169;do{while (--j);} while (--i);}
}void Select_Bit(unsigned char pos,dat)
{P0 = 0x01 << pos;Select_Hc573(6);P0 = dat;Select_Hc573(7);Delay_ms(1);P0 = 0xff;Select_Hc573(7);
}void Display_temp()//温度数据界面
{Select_Bit(0,SMG[10]);Select_Bit(5,SMG[temp / 100]);Select_Bit(6,SMG[temp / 10 % 10] - 0x80);Select_Bit(7,SMG[temp % 10]);
}

注意:共阳数码管-0x80为加上小数点,共阴数码管+0x80为加上小数点。

6.定时器按键扫描

以独立按键为例,矩阵键盘同理

void Timer2Init(void)		//10毫秒@12.000MHz
{AUXR &= 0xFB;		//定时器时钟12T模式T2L = 0xF0;		//设置定时初值T2H = 0xD8;		//设置定时初值AUXR |= 0x10;		//定时器2开始计时IE2 |= (1 << 2);EA = 1;
}void Timer2_Service() interrupt 12
{Key_Scan();//每隔10ms扫描一次按键
}void Key_Scan()
{static unsigned char cnt0 = 0;//按键计时消抖static unsigned char cnt1 = 0;//按键计时消抖static unsigned char cnt2 = 0;//按键计时消抖static unsigned char cnt3 = 0;//按键计时消抖if(S7 == 0)//记录按键低电平时间{cnt0++;}if(S7 == 1)//按键释放/按键未按下/按键按下的抖动{if(cnt0 > 100)//说明是长按{//长按执行的内容}else if(cnt0 > 2)//说明是短按{//短按执行内容}cnt0 = 0;//清除计数变量}if(S6 == 0)//记录按键低电平时间{cnt1++;}if(S6 == 1)//按键释放/按键未按下/按键按下的抖动{if(cnt1 > 100)//说明是长按{//长按执行的内容}else if(cnt1 > 2)//说明是短按{//短按执行内容}cnt1 = 0;//清除计数变量}if(S5 == 0)//记录按键低电平时间{cnt2++;}if(S5 == 1)//按键释放/按键未按下/按键按下的抖动{if(cnt2 > 100)//说明是长按{//长按执行的内容}else if(cnt2 > 2)//说明是短按{//短按执行内容}cnt2 = 0;//清除计数变量}if(S4 == 0)//记录按键低电平时间{cnt3++;}if(S4 == 1)//按键释放/按键未按下/按键按下的抖动{if(cnt3 > 100)//说明是长按{//长按执行的内容}else if(cnt3 > 2)//说明是短按{//短按执行内容}cnt3 = 0;//清除计数变量}
}

7.DS18B20(基于2023年第十四届底层代码)

onewire.c

/*	# 	单总线代码片段说明1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求,进行代码调试和修改。
*///
#include <STC15F2K60S2.H>
#include <onewire.H>sbit DQ = P1^4;void Delay_OneWire(unsigned int t)  
{unsigned char i;while(t--){for(i=0;i<12;i++);}
}//
void Write_DS18B20(unsigned char dat)
{unsigned char i;for(i=0;i<8;i++){DQ = 0;DQ = dat&0x01;Delay_OneWire(5);DQ = 1;dat >>= 1;}Delay_OneWire(5);
}//
unsigned char Read_DS18B20(void)
{unsigned char i;unsigned char dat;for(i=0;i<8;i++){DQ = 0;dat >>= 1;DQ = 1;if(DQ){dat |= 0x80;}	    Delay_OneWire(5);}return dat;
}//
bit init_ds18b20(void)
{bit initflag = 0;DQ = 1;Delay_OneWire(12);DQ = 0;Delay_OneWire(80);DQ = 1;Delay_OneWire(10); initflag = DQ;     Delay_OneWire(5);return initflag;
}

onewire.h

#ifndef __onewire_h
#define __onewire_hvoid Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);#endif

温度读取代码

unsigned int read_wd()//读取温度
{unsigned char LSB,MSB;unsigned int Temp;init_ds18b20();Write_DS18B20(0xcc);Write_DS18B20(0x44);init_ds18b20();Write_DS18B20(0xcc);Write_DS18B20(0xbe);LSB = Read_DS18B20();MSB = Read_DS18B20();Temp = MSB << 8 | LSB;return (Temp * 0.0625);
}

注意:×0.0625为保留0位小数,×0.625为保留1为小数,×6.25为保留2位小数。保留1位和2位小数实际为一个百位数和一个千位数,在显示的时候只是人为添加了小数点而已。

8.DS1302(基于2023年第十四届底层代码)

ds1302.c

/*	# 	DS1302代码片段说明1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求,进行代码调试和修改。
*/								//
#include <STC15F2K60S2.H>
#include <ds1302.H>
#include <intrins.H>sbit SCK = P1^7;
sbit SDA = P2^3;
sbit RST = P1^3;void Write_Ds1302(unsigned  char temp) 
{unsigned char i;for (i=0;i<8;i++)     	{ SCK = 0;SDA = temp&0x01;temp>>=1; SCK=1;}
}   //
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{RST=0;	_nop_();SCK=0;	_nop_();RST=1; 	_nop_();  Write_Ds1302(address);	Write_Ds1302(dat);		RST=0; 
}//
unsigned char Read_Ds1302_Byte ( unsigned char address )
{unsigned char i,temp=0x00;RST=0;	_nop_();SCK=0;	_nop_();RST=1;	_nop_();Write_Ds1302(address);for (i=0;i<8;i++) 	{		SCK=0;temp>>=1;	if(SDA)temp|=0x80;	SCK=1;} RST=0;	_nop_();SCK=0;	_nop_();SCK=1;	_nop_();SDA=0;	_nop_();SDA=1;	_nop_();return (temp);			
}

ds1302.h

#ifndef __ds1302_h
#define __ds1302_hvoid Write_Ds1302(unsigned  char temp) ;
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte ( unsigned char address );#endif

写时间,读时间代码

code unsigned char write_addr[] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//写地址
code unsigned char read_addr[] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};//读地址unsigned char time[] = {0x50,0x59,0x16};//初始化时间void write_time()//写时间
{Write_Ds1302_Byte(0x8e,0x00);for(i = 0;i < 3;i++)Write_Ds1302_Byte(write_addr[i],time[i]);Write_Ds1302_Byte(0x8e,0x80);
}void read_time()//读时间
{for(i = 0;i < 3;i++)time[i] = Read_Ds1302_Byte (read_addr[i]);
}

BCD码转十进制(转化为十进制加减后再还原为BCD码)

int bcd_shi(int bcd)//BCD码转十进制
{return (bcd - (bcd >> 4) * 6);
}

十进制转BCD码 

int shi_bcd(int shi)//十进制转BCD码
{return (shi+(shi / 10) * 6);
}

9.PCF8591(基于2023年第十四届底层代码)

iic.c

/*	#   I2C代码片段说明1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求,进行代码调试和修改。
*/#include <STC15F2K60S2.H>
#include <iic.H>
#include <intrins.H>sbit scl = P2^0;
sbit sda = P2^1;#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_hstatic void I2C_Delay(unsigned char n);
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

读取光敏电阻电压代码

unsigned int read_PCF8591()//读取光敏电阻电压
{unsigned int Temp;I2CStart();I2CSendByte(0x90);I2CWaitAck();I2CSendByte(0x01);I2CWaitAck();I2CStart();I2CSendByte(0x91);I2CWaitAck();Temp = I2CReceiveByte();I2CSendAck(1);I2CStop();return Temp;
}

读取滑动变阻器电压代码

unsigned int PCF8591_Read()
{unsigned int temp;IIC_Start();IIC_SendByte(0x90);IIC_WaitAck();IIC_SendByte(0x03);IIC_WaitAck();IIC_Start();IIC_SendByte(0x91);IIC_WaitAck();temp = IIC_RecByte();IIC_SendAck(1);IIC_Stop();return temp;
}

输出电压代码

void PCF8591_Write(dat)
{IIC_Start();IIC_SendByte(0x90);IIC_WaitAck();IIC_SendByte(0x40);IIC_WaitAck();IIC_SendByte(dat);IIC_WaitAck();IIC_Stop();
}

注意:读取光敏电阻和滑动变阻器电压直接得到的是一个0~255的数,需要用如下代码转换:

read_PCF8591() / 51.0 * 100;

同理,输出电压时,应该为0~255的数。

只AD时,可只用0x01,0x03。

只DA时,可只用0x40。

既要AD又要DA时,需用0X41,0X43。

10.超声波PCA版(可节省出一个定时器)

sbit TX = P1^0;
sbit RX = P1^1;void Delay12us()		//@12.000MHz
{unsigned char i;_nop_();_nop_();i = 33;while (--i);
}void Ut_Wave_Init()
{char i;for(i = 0;i < 8;i++){TX = 1;Delay12us();TX = 0;Delay12us();}
}unsigned int Send()
{unsigned int time;CMOD = 0x00;CH = CL = 0x00;Ut_Wave_Init();CR = 1;while((RX == 1) && (CF == 0));CR = 0;if(CF == 0){time = CH << 8 | CL;return (time * 0.017);}else{CF = 0;return 999;}
}

11.NE555测量频率

unsigned int count,Fre;void Time_Init()
{TMOD = 0x05;TH0 = 0x00;TL0 = 0x00;TH1 = (65535 - 50000) / 256;TL1 = (65535 - 50000) % 256;TR0 = TR1 = 1;ET0 = ET1 = 1;EA = 1;
}void Service_Time1() interrupt 3
{count++;if(count == 20){Fre = TH0 << 8 | TL0;count = 0;TL0 = 0;TH0 = 0;}
}