蓝桥杯单片机第十届国赛 真题+代码

 

 

 

 

 

 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);
}void Write_PCF8591(unsigned char dat)
{I2CStart();I2CSendByte(0x90);I2CWaitAck();I2CSendByte(0x40);I2CWaitAck();I2CSendByte(dat);I2CWaitAck();I2CStop();
}void Writr_AT24C02(unsigned char dat)
{I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(0x00);I2CWaitAck();I2CSendByte(dat);I2CWaitAck();I2CStop();
}unsigned char Read_AT24C02()
{unsigned char temp;I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(0x00);I2CWaitAck();I2CStart();I2CSendByte(0xa1);I2CWaitAck();temp = I2CReceiveByte();I2CSendAck(1);I2CStop();return temp;
}

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);
void Write_PCF8591(unsigned char dat);
void Writr_AT24C02(unsigned char dat);
unsigned char Read_AT24C02();#endif

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;
}unsigned int Read_temp()
{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 * 6.25;
}

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);
unsigned int Read_temp();#endif

sys.c

#include <STC15F2K60S2.H>
#include "sys.h"
#include "intrins.h"void Delay12us()		//@12.000MHz
{unsigned char i;_nop_();_nop_();i = 33;while (--i);
}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_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;
}void Sys_Init()
{P0 = 0x00;Select_Hc573(5);P0 = 0xff;Select_Hc573(4);
}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);
}

sys.h

#ifndef __sys_h
#define __sys_hvoid Delay_ms(unsigned int t);
void Select_Hc573(char n);
void Sys_Init();
void Select_Bit(unsigned char pos,dat);
void Delay12us();#endif

main.c

#include <STC15F2K60S2.H>
#include "sys.h"
#include "onewire.h"
#include "iic.h"
#include "stdio.h"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;code unsigned char SMG[] = { ~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,~0x39,~0x38,~0x67,~0x73};sbit TX = P1^0;
sbit RX = P1^1;unsigned char i;
unsigned char key_val;//键值
unsigned int dis;//距离
unsigned int temp;//温度
unsigned char count=1;//变更次数
char param_temp = 30;//温度参数
char param_dis = 35;//距离参数
char param_temp_old = 30,param_dis_old = 35;
bit flag_10ms,flag_500ms;
bit mode;//大界面切换	0-数据界面	1-参数界面
unsigned char mode_dat;//数据界面切换	0-温度	1-距离	2-变更次数
bit mode_param;//参数界面切换	0-温度	1-距离
bit flag_dac_open = 1;
unsigned char str[10];
unsigned char Rec[10];
unsigned char index;//索引
unsigned char index_old;
unsigned char count1;void PCA_Init()
{CCON = 0;CMOD |= 0x08;
}void Send()//发送超声波
{for(i = 0;i < 8;i++){TX = 1;Delay12us();TX = 0;Delay12us();}CH = CL = 0;CR = 1;while(RX && !CF);CR = 0;if(!CF){dis = (CH << 8 | CL)* 0.017 / 12;}else{dis = 99;CF = 0;}
}void Display_temp()//温度界面
{Select_Bit(0,SMG[10]);Select_Bit(4,SMG[temp / 1000]);Select_Bit(5,SMG[temp /100 % 10] - 0x80);Select_Bit(6,SMG[temp / 10 % 10]);Select_Bit(7,SMG[temp % 10]);
}void Display_dis()//距离界面
{Select_Bit(0,SMG[11]);Select_Bit(6,SMG[dis / 10]);Select_Bit(7,SMG[dis % 10]);
}void Display_count()//变更次数界面
{Select_Bit(0,SMG[12]);if(count > 99)	Select_Bit(5,SMG[count / 100]);if(count > 9)	Select_Bit(6,SMG[count / 10]);Select_Bit(7,SMG[count % 10]);
}void DIsplay_Param_temp()//温度参数界面
{Select_Bit(0,SMG[13]);Select_Bit(3,SMG[1]);Select_Bit(6,SMG[param_temp / 10]);Select_Bit(7,SMG[param_temp % 10]);
}void DIsplay_Param_dis()//距离参数界面
{Select_Bit(0,SMG[13]);Select_Bit(3,SMG[2]);Select_Bit(6,SMG[param_dis / 10]);Select_Bit(7,SMG[param_dis % 10]);
}void Timer2Init(void)		//10毫秒@12.000MHz
{AUXR &= 0xFB;		//定时器时钟12T模式T2L = 0xF0;		//设置定时初值T2H = 0xD8;		//设置定时初值AUXR |= 0x10;		//定时器2开始计时IE2 = 1 << 2;
}void Timer2_isr() interrupt 12
{flag_10ms = 1;if(++count1 > 100){count1 = 0;flag_500ms = 1;}
}unsigned char Key_Scan()//按键扫描获取键值
{static unsigned int cnt13 = 0;static unsigned int cnt12 = 0;static unsigned char cnt16 = 0;static unsigned char cnt17 = 0;if(flag_10ms)//10ms扫描一次{R3 = 0;R1 = R2 = R4 = C1 = C2 = C3 = C4 = 1;if(C3 == 0)	{cnt13++;if(cnt13 > 100)	temp = 130;}if(C3 == 1){if(cnt13 > 2 && cnt13 < 100)	temp = 13;cnt13 = 0;}if(C4 == 0)	cnt17++;if(C4 == 1){if(cnt17 > 2)	temp = 17;cnt17 = 0;}R4 = 0;R1 = R2 = R3 = C1 = C2 = C3 = C4 = 1;if(C3 == 0)	{cnt12++;if(cnt12 > 100)	temp = 120;		}if(C3 == 1){if(cnt12 > 2 && cnt12 < 100)	temp = 12;cnt12 = 0;}if(C4 == 0)	cnt16++;if(C4 == 1){if(cnt16 > 2)	temp = 16;cnt16 = 0;}flag_10ms = 0;}return temp;
}
void Key_Pro()//键值处理函数
{switch(key_val){case 12 :if(!mode){if(++mode_dat > 2)	mode_dat = 0;}else	mode_param = ~mode_param;break;case 13:mode = ~mode;if(!mode)	mode_param = 0;else	mode_dat = 0;if(!mode)//数据的存储{if(param_temp_old != param_temp){count++;param_temp_old = param_temp;	}else	if(param_dis_old != param_dis){count++;param_dis_old = param_dis;	}Writr_AT24C02(count);}break;case 16:if(mode){if(!mode_param){	param_temp -= 2;if(param_temp < 0)	param_temp = 98;}else{param_dis -= 5;if(param_dis < 0)	param_dis = 95;}}break;case 17:if(mode){if(!mode_param){	param_temp += 2;if(param_temp > 99)	param_temp = 0;}else{param_dis += 5;if(param_dis > 99)	param_dis = 0;}}break;case 120:count = 0;break;case 130:flag_dac_open ^= 1;break;	}
}void Display()//数码管显示函数
{if(!mode){switch(mode_dat){case 0:Display_temp();break;case 1:Display_dis();break;case 2:Display_count();break;}}else{if(!mode_param)	DIsplay_Param_temp();else	DIsplay_Param_dis();}
}void UartInit(void)		//4800bps@12.000MHz
{SCON = 0x50;		//8位数据,可变波特率AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12TAUXR &= 0xFE;		//串口1选择定时器1为波特率发生器TMOD &= 0x0F;		//设定定时器1为16位自动重装方式TL1 = 0xCC;		//设定定时初值TH1 = 0xFF;		//设定定时初值ET1 = 0;		//禁止定时器1中断TR1 = 1;		//启动定时器1ES = 1;
}void Send_Byte(unsigned char dat)
{SBUF = dat;while(!TI);TI = 0;
}void Send_String(unsigned char *dat)
{while(*dat != '\0')Send_Byte(*dat++);
}void Uart_isr() interrupt 4
{if(RI){Rec[index] = SBUF;index++;RI = 0;}
}
bit ok,error_flag;
void Uart_Pro()
{
//	if(flag_500ms)
//	{
//		if(index > 0)
//		{
//			if(index_old != index)//上一次的索引和这一次的索引不一样的话就刷新,且不进入判断
//			{
//				index_old = index;//刷新
//				ok = 0;//	1-进行字符判断	0-不进行判断
//			}
//			else	ok = 1;
//		}
//		flag_500ms = 0;
//	}
//	if(ok)
//	{
//		if(index == 4)
//		{
//			if(Rec[0] == 'S' && Rec[1] == 'T' && Rec[2] == '\r' && Rec[3] == '\n')
//			{
//				sprintf(str,"$%d,%.2f\r\n",dis,((float)temp )/ 100);
//				Send_String(str);
//				sprintf(str,"\r\n");
//				Send_String(str);
//			}
//			else flag = 1;
//		}
//		else if(index == 6)
//		{
//			if(Rec[0] == 'P' && Rec[1] == 'A' && Rec[2] == 'R' && Rec[3] == 'A' && Rec[4] == '\r' && Rec[5] == '\n')
//			{
//				sprintf(str,"#%d,%d\r\n",(int)param_temp,(int)param_dis);
//				Send_String(str);
//			}
//			else	flag = 1;
//		}
//		else	flag = 1;
//		if(flag)
//		{
//			sprintf(str,"ERROR\r\n");
//			Send_String(str);
//			flag=0;
//		}
//		index = 0;
//		ok = 0;
//	}if(Rec[index - 1] == '\n'){if(index == 4){if(Rec[0] == 'S' && Rec[1] == 'T' && Rec[2] == '\r' && Rec[3] == '\n'){sprintf(str,"$%d,%.2f\r\n",dis,((float)temp )/ 100);Send_String(str);}}else if(index == 6){if(Rec[0] == 'P' && Rec[1] == 'A' && Rec[2] == 'R' && Rec[3] == 'A' && Rec[4] == '\r' && Rec[5] == '\n'){sprintf(str,"#%d,%d\r\n",(int)param_temp,(int)param_dis);Send_String(str);}}else{sprintf(str,"ERROR\r\n");Send_String(str);}index = 0;}
}void Dac_Pro()
{if(flag_dac_open){if(dis <= param_dis)	Write_PCF8591(2 * 51);else	Write_PCF8591(4 * 51);}else	Write_PCF8591(20);
}void Led(unsigned char addr,enable)
{static unsigned char temp = 0x00;static unsigned char temp_old = 0xff;if(enable)	temp |= 0x01 << addr;else	temp &= ~(0x01 << addr);if(temp != temp_old){P0 = ~temp;Select_Hc573(4);temp_old = temp;}
}void Led_Pro()
{if(	((float)temp) / 100 > param_temp	)	Led(0,1);else	Led(0,0);if(dis < param_dis)	Led(1,1);else	Led(1,0);if(flag_dac_open)	Led(2,1);else	Led(2,0);
}void main()
{Sys_Init();PCA_Init();Timer2Init();UartInit();EA = 1;Read_temp();Delay_ms(750);count = Read_AT24C02();while(1){if(flag_500ms){Send();flag_500ms = 0;}temp = Read_temp();key_val = Key_Scan();Uart_Pro();Key_Pro();Display();Dac_Pro();Led_Pro();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/12235.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【【51单片机DA转换模块】】

爆改直流电机&#xff0c;DA转换器 main.c #include <REGX52.H> #include "Delay.h" #include "Timer0.h"sbit DAP2^1;unsigned char Counter,Compare; //计数值和比较值&#xff0c;用于输出PWM unsigned char i;void main() {Timer0_Init();whil…

后台管理系统中刷新业务功能的实现

实现 下载vueuse npm i vueuse/core在header组件中引入并给全屏按钮绑定点击事件 <el-button type"default" click"toggle" icon"FullScreen" circle></el-button>import { useFullscreen } from vueuse/coreconst { toggle } u…

【Java】分支结构习题

【Java】分支结构 文章目录 【Java】分支结构题1 &#xff1a;数字9 出现的次数题2 &#xff1a;计算1/1-1/21/3-1/41/5 …… 1/99 - 1/100 的值。题3 &#xff1a;猜数字题4 &#xff1a;牛客BC110 X图案题5 &#xff1a;输出一个整数的每一位题6 &#xff1a; 模拟三次密码输…

[SQL挖掘机] - 内连接: inner join

介绍: 内连接是一种多表连接方式&#xff0c;用于将两个或多个表中的数据通过共同的列值进行匹配&#xff0c;并返回满足连接条件的匹配行。简单来说&#xff0c;内连接能够将相关联的数据组合在一起&#xff0c;以便进行更复杂和全面的数据分析。 内连接的工作原理如下&…

bash: 睡觉的冒号;是不是两个点?

文章目录 简介躺着的冒号是两个点正常冒号总结简介 在bash里冒号和躺着的冒号的用法不一样一定要注意别用错。 躺着的冒号是两个点 难道正常的不是两个点)的作用: A sequence expression takes the form {x…y[…incr]}, where x and y are either integers or single cha…

排序算法、

描述 由小到大输出成一行&#xff0c;每个数字后面跟一个空格。 输入 三个整数 输出 输入三个整数&#xff0c;按由小到大的顺序输出。 输入样例 1 2 3 1 输出样例 1 1 2 3 输入样例 2 4 5 2 输出样例 2 2 4 5 代码一&#xff08;如下&#xff09;&#xff1…

pytest+allure运行出现乱码的解决方法

pytestallure运行出现乱码的解决方法 报错截图&#xff1a; 这里的截图摘自 悟翠人生 小伙伴的https://blog.csdn.net/weixin_45435918/article/details/107601721一文。 这是因为没有安装allure运行环境或者没有配置allure的环境变量导致&#xff0c;解决方案&#xff1a; 1…

各系统的目录信息路径

Windows系统: 查看系统版本——C:\boot.ini IIS配置文件——C:\windows\system32\inetsrv\MetaBase.xml 存储Windows系统初次安装的密码——C:\windows\repair\sam Mysql配置——C:\ProgramFiles\mysql\my.ini MySQL root密码——C:\P…

LaTex使用技巧20:LaTex修改公式的编号和最后一行对齐

写论文发现公式编号的格式不对&#xff0c;要求是如果是多行的公式&#xff0c;公式编号和公式的最后一行对齐。 我原来使用的是{equation}环境。 \begin{equation} \begin{aligned} a&bc\\ &cd \end{aligned} \end{equation}公式的编号没有和最后一行对齐。 查了一…

CAN转EtherNet/IP网关can协议是什么意思

你是否曾经遇到过不同的总线协议难以互相通信的问题&#xff1f;远创智控的YC-EIP-CAN网关为你解决了这个烦恼&#xff01; 远创智控YC-EIP-CAN通讯网关是一款自主研发的设备&#xff0c;它能够将各种CAN总线和ETHERNET/IP网络连接起来&#xff0c;解决不同总线协议之间的通信…

SpringBoot项目部署在Windows与Centos上

文章目录 Windows部署一、github上下载文件winsw二、文件目录三、编辑xml文件四、安装服务五、启动服务六、把jar包放到项目外面七、添加限制内存 Linux部署一、准备二、服务三、操作 Windows部署 windows部署服务借鉴于此篇博文 一、github上下载文件winsw 点击链接下载下图…

uniapp使用HQChart的k线,用webSocket更新数据

项目&#xff1a;不借用HQChart的各种接口数据&#xff0c;即数据后端返回&#xff0c;但是数据格式要和原数据格式一样。 //k线图 CreateHQChartKLine(){var chartHeightuni.upx2px(this.ChartHeight);let hqchartCtrlthis.$refs.HQChartCtrl;hqchartCtrl.KLine.Option.Type&…

【触觉智能Purple Pi OH开发板体验】开箱体验:开源主板Purple Pi RK3566 上手指北

前言 前段时间收到来自【电子发烧友】的一款开发板&#xff0c;名叫&#xff1a;PurplePi&#xff0c;216G售价仅249元。它使用的芯片是rk3566&#xff0c;适配的OpenHarmony版本为3.2 Release 是目前最便宜的OpenHarmony标准系统开源开发板&#xff0c;并且软硬件全部开源&am…

QT 使用串口

目录 1.1.1 添加库&#xff0c;添加类 1.1.2 定义串口 1.1.3 搜索串口 1.1.4 设置和打开串口 1.1.5 读取数据 1.1.6 发送数据 1.1.7 关闭串口 1.1.1 添加库&#xff0c;添加类 首先&#xff0c;QT5 是自带 QSerialPort(Qt5 封装的串口类)这个类的&#xff0c;使用时…

中级工程师职称评审条件

一.评审范围 全省范围具有合法生产&#xff0c;经营手续的中小企业局和非公有制经济从事工程师工作专业技术人员和高技能人员&#xff0c;均可申报 当年达到法定退休或已办退休…

sql dateadd函数的用法有哪些

SQL的DATEADD函数用于在日期或时间上添加一个指定的间隔&#xff0c;并返回结果。 DATEADD函数的语法如下&#xff1a; DATEADD(datepart, number, date) 其中&#xff0c;datepart是指定要添加的间隔的部分&#xff0c;number是要添加的数量&#xff0c;date是要添加间隔的日…

【深度学习笔记】Softmax 回归

本专栏是网易云课堂人工智能课程《神经网络与深度学习》的学习笔记&#xff0c;视频由网易云课堂与 deeplearning.ai 联合出品&#xff0c;主讲人是吴恩达 Andrew Ng 教授。感兴趣的网友可以观看网易云课堂的视频进行深入学习&#xff0c;视频的链接如下&#xff1a; 神经网络和…

每日一题——有序链表去重

题目 删除给出链表中的重复元素&#xff08;链表中元素从小到大有序&#xff09;&#xff0c;使链表中的所有元素都只出现一次。 例如&#xff1a;给出的链表为1→1→2,返回1→2。 给出的链表为1→1→2→3→3,返回1→2→3。 数据范围&#xff1a;链表长度满足 0≤n≤100&#…

学习笔记|百度文心千帆大模型平台测试及页面交互简易代码

目前百度文心一言的内测资格申请相当拉胯&#xff0c;提交申请快3个月&#xff0c;无任何音讯。不知道要等到什么时候。 百度适时开放了百度文心千帆大模型平台&#xff0c;目前可以提交申请测试&#xff0c;貌似通过的很快&#xff0c;已取得测试申请资格&#xff0c;可以用起…

Oracle恢复删除的数据

不下心删除了生产库的数据或者不小心删除了一部分数据&#xff0c;如何恢复找回。 Oracle恢复删除数据的方法 方案一 利用oracle提供的闪回方法进行数据恢复&#xff0c;适用于delete删除方式 首先获取删除数据的时间点&#xff1a; select * from v$sql where sql_text l…