当前位置: 首页 > article >正文

【蓝桥杯—单片机】第十届省赛真题代码题解题笔记 | 省赛 | 真题 | 代码题 | 刷题 | 笔记

第十届省赛真题代码部分

  • 前言
  • 赛题代码思路笔记
    • 竞赛板配置
      • 内部振荡器频率设定
      • 键盘工作模式跳线
      • 扩展方式跳线
      • 连接频率测量功能的跳线帽
    • 建立模板
    • 明确初始状态
    • 显示功能部分
      • 频率显示界面
        • 第一部分
        • 第二部分
        • 第三部分
      • 电压显示界面
        • 第一部分
        • 第二部分
        • 第三部分
    • 按键功能部分
      • S4:“显示界面切换”按键
      • S5:“输出模式切换”按键
      • S6:“LED指示灯功能控制”按键
      • S7:“数码管显示功能控制”按键
    • LED指示灯功能部分
      • L1和L2
      • L3
      • L4
      • L5
  • 最终代码
    • User文件
      • main.c
    • Driver文件
      • Init.c
      • LED.c
      • Seg.c
      • Key.c
      • iic.c

前言

本文是对蓝桥杯第十届省赛真题的代码题做的解题笔记,只记录了代码的思路,大模板用的是B站西风老师的2024年版大模板,具体内容就不再重复记录了。

思路参考西风第十五讲内容(资料链接已经在下方给出)

https://www.bilibili.com/video/BV1TR4y1k7iz?p=23&vd_source=e2191f89c557f5ac44bb6c7aa3967c7c

关于蓝桥杯第十届省赛真题可以在官网查看(资料链接已经在下方给出)

https://www.lanqiao.cn/courses/2786/learning/?id=100643&compatibility=false

赛题代码思路笔记

竞赛板配置

根据赛题要求完成竞赛板的配置

在这里插入图片描述
在这里插入图片描述

内部振荡器频率设定

在stc中更改输入用户程序运行时的IRC频率为12MHz
在这里插入图片描述

键盘工作模式跳线

配置为BTN按键模式
在这里插入图片描述

扩展方式跳线

配置为IO模式
在这里插入图片描述

连接频率测量功能的跳线帽

建立模板

根据赛题中的硬件框图确定本赛题的框架
在这里插入图片描述
如图,在Driver文件夹里建立LED、数码管、按键、iic、onewire模块,在User文件夹中建立主函数模块(大模板参考西风老师的2024版大模板)。
在这里插入图片描述

明确初始状态

在这里插入图片描述

显示功能部分

在这里插入图片描述
在这里插入图片描述
由题可知,数码管显示一共两个界面。
可以引入一个变量Seg_Disp_Mode来标记当前显示界面,因为只有两个界面,所以可以定义为bit型而不是unsigned char型以此来节省空间。

bit Seg_Disp_Mode;     //数码管显示模式变量 0-频率显示界面 1-电压显示界面

再在信息处理函数的数码管部分中对当前显示模式进行判断。
判断完成后在各部分写入供该界面显示的代码。

if(Seg_Disp_Mode == 0)//频率显示界面
	{
		
	}
	else//电压显示界面
	{
    }

频率显示界面

在这里插入图片描述
由题目可知,数据界面由三部分组成:

  1. 第一部分为提示符部分,是数码管的第一位,在该界面下全程显示字母F。
  2. 第二部分为熄灭部分,是数码管的第2到4位,在该界面下全程熄灭。
  3. 第三部分为频率显示部分,是数码管的第5到8位,在该界面下根据实时监测的频率不同显示数字实时变动。

在Driver文件夹下的Seg模块中的显示数组中加入用于表示熄灭的0xff,表示字母,表示字母C的0xc6,表示字母P的0x8c。

code unsigned char seg_dula[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xff, 0x8e,0xc1};//0-9,10-熄灭,11-F,12-U

更改主模块中对应数码管控制列表中的值来控制数码管的显示情况。

第一部分

标识部分对应的数码管为第一位,更改主模块中对应数码管控制列表Seg_Buf中第一位对应的数,使其对应上Seg模块中的显示数组中的字母F。

Seg_Buf[0] = 11;//F
第二部分

熄灭部分,是数码管的第2到4位,全程为熄灭状态,在创建主函数中的Seg_Buf列表时其中的元素已经置为对应Seg模块中的显示数组中的熄灭,所以不要再做额外的更改。

第三部分

关于实时频率部分,模板已经给出,不再赘述。
在数码管中显示,只需要对实时频率数据进行取余和取整操作即可。

Seg_Buf[3] = Freq / 10000 % 10;
Seg_Buf[4] = Freq / 1000 % 10;
Seg_Buf[5] = Freq / 100 % 10;
Seg_Buf[6] = Freq / 10 % 10;
Seg_Buf[7] = Freq  % 10;

在这里插入图片描述
除此以外,仍需要注意的是,显示数据高位为0时,做熄灭处理。
设置一个循环,对频率显示部分进行逐位获取,该位为0是熄灭处理,直到获取到第一个非零数据时,不再熄灭。
按照上面的思路,当获取的频率值为0时,数码管全部熄灭,不行。要让频率部分最小也能显示一位,那就直接跳过最后一位,只获取前7位。

unsigned char i=3;

while(Seg_Buf[i] == 0)
	{
		Seg_Buf[i] = 10;	
		if(++i ==7) break;
	}

电压显示界面

在这里插入图片描述
在这里插入图片描述

由题目可知,参数设置界面由三部分组成:

  1. 第一部分为标识部分,是数码管的第1位,在该界面下全程显示字母U。
  2. 第二部分为熄灭部分,是数码管的第2到5位,在该界面下全程熄灭。
  3. 第三部分为电压显示部分,是数码管的第6到8位。
第一部分

标识部分对应的数码管为第一位,更改主模块中对应数码管控制列表Seg_Buf中第一位对应的数,使其对应上Seg模块中的显示数组中的字母P。

Seg_Buf[0] = 12;//U
第二部分

在上一个界面中第4到8位数码管点亮,在此界面中,第6到8位数码管点亮。为了避免界面切换时第4位和第5位数码管仍处于点亮状态,可以直接对第4位和第5位数码管进行操作。

Seg_Buf[3] = 10;
Seg_Buf[4] = 10;
第三部分

建立一个变量Voltage存储获取的实时电压数据。

float Voltage;        //实时电压数据

电压值为模拟量,显示值为数字量,调用AD转换相关函数读取对应位置的电压值。
需要注意的是,AD读取出来的是以255为长度量化的电压值,所以需要进行转换。将0-255的范围转算成0-5的范围,需要除以51。

Voltage = Ad_Read(0x43) / 51.0;

显示数据是小数点前有一位数的两位小数。
实时电压数据存储在float型的Voltage中,小数前只有一位,将Voltage强制类型转换成unsigned char型可以直接取出。
unsigned char型的Voltage小数点后的数直接被抹去,要取出小数点后的数,可以将float型的Voltage转换成unsigned int型,再进行乘除的运算依次取出需要用的位置的数。

Seg_Buf[5] = (unsigned char)Voltage;
Seg_Buf[6] = (unsigned int)(Voltage * 100) /10 % 10;
Seg_Buf[7] = (unsigned int)(Voltage * 100)% 10;

小数点在Seg_Point对应位置为1时点亮,Seg_Disp_Mode在1时要求小数点点亮,所以可以直接用Seg_Disp_Mode给Seg_Point对应位置赋值。

Seg_Point[5] = Seg_Disp_Mode;

按键功能部分

在这里插入图片描述
在大模板主模块的按键处理函数中,用Key_Down判断按键按下的值。因为题目中按键涉及到4、5、6、7,所以可以添加一个switch对当前按下的按键进行一个判断。
判断完成后在各部分写入供该按键需要实现的功能的代码即可。

void Key_Proc()
{
	if (Key_Flag)return;
	Key_Flag = 1;							  // 设置标志位,防止重复进入
	Key_Val = Key_Read();					  // 读取按键值
	Key_Down = Key_Val & (Key_Old ^ Key_Val); // 检测下降沿
	Key_Up = ~Key_Val & (Key_Old ^ Key_Val);  // 检测上升沿
	Key_Old = Key_Val;						  // 更新按键状态
	
	switch(Key_Down)
	{
		case 4:
			
		break;
		
		case 5:
			
		break;
		
		case 6:
			
		break;
		
		case 7:
			
		break;
	}

S4:“显示界面切换”按键

在这里插入图片描述
该按键按下后实现了界面的切换。
在显示功能部分,我们已经定义了一个变量Seg_Disp_Mode来标记当前显示的界面,当Seg_Disp_Mode为0时是数据界面,为1时是参数设置界面。
因为变量Seg_Disp_Mode是bit型数据,只在0和1之间变换,所以可以直接用异或来运算。

Seg_Disp_Mode ^= 1;

S5:“输出模式切换”按键

在这里插入图片描述
该按键按下后实现了输出模式的切换。
由题可知,输出模式只有两个,可以定义一个bit型的变量来标记当前输出模式。

bit OutPut_Mode;      //输出模式 0-固定电压 1-变化电压

和S4的Seg_Disp_Mode的变换类似,按下按键后OutPut_Mode只在0和1之间变换,可以直接用异或来运算。

OutPut_Mode ^= 1;

再定义一个float型变量存储输出电压值。

float Voltage_Output;  //输出电压

S6:“LED指示灯功能控制”按键

在这里插入图片描述

该按键按下后实现了LED指示灯的开关。
只有可和关两个功能,可以定义一个bit型的变量Led_Enable_Flag来标记当前状态。

bit Led_Enable_Flag = 1;     //指示灯功能控制标志 1-点亮 0-熄灭

按键按下后Led_Enable_Flag在0和1之间切换,可以直接用异或运算。

Led_Enable_Flag ^= 1;

在调用LED显示相关的函数时,添加前置条件。

if(Led_Enable_Flag == 1) 
		Led_Disp(Slow_Down % 8, ucLed[Slow_Down % 8]);							   // 更新LED显示
else 
		Led_Disp(Slow_Down % 8,0);

S7:“数码管显示功能控制”按键

在这里插入图片描述

S7与S6类似,不再赘述。

bit Seg_Enable_Flag = 1;      //数码管功能控制标志 1-点亮 0-熄灭
Seg_Enable_Flag ^= 1;
if(Seg_Enable_Flag == 1) 
		Seg_Disp(Slow_Down % 8, Seg_Buf[Slow_Down % 8], Seg_Point[Slow_Down % 8]); // 更新数码管显示
else 
		Seg_Disp(Slow_Down % 8, 10, 0);

LED指示灯功能部分

在这里插入图片描述

L1和L2

在这里插入图片描述
L1和L2的点亮状态和当前处于电压测试还是频率测试相关。在显示功能部分,我们已经给这两个显示界面一个变量Seg_Disp_Mode来标记(Seg_Disp_Mode为0是频率显示界面,为1时是电压显示界面)。
所以,当Seg_Disp_Mode为0是L1熄灭,L2点亮;Seg_Disp_Mode为1是L1点亮,L2熄灭。
且L1和L2互斥,不存在两个同时点亮的情况。
可以建立一个循环,对Led显示数据存放数组ucLed中的0位(L1)和1位(L2)进行扫描。
由题目得,当Seg_Disp_Mode为0时,要求ucLed[0]为0,ucLed[1]为1;当Seg_Disp_Mode为1时,要求ucLed[0]为1,ucLed[1]为0。可知,Seg_Disp_Mode和ucLed(在0-1的范围内)索引值相等时,置0;反之置为1。
根据上述建立条件判断和赋值语句。

unsigned char i;

for(i=0;i<2;i++) ucLed[i] = (i != Seg_Disp_Mode);

L3

在这里插入图片描述
L3点亮(ucLed[2]为1)的条件只有两个,即实时电压值(Voltage) 大于等于1.5且小于等于2.5 或 大于等于3.5 时。
根据条件写出条件判断语句((Voltage >= 1.5 && Voltage < 2.5) || (Voltage >= 3.5)),当逻辑为真时,给ucLed[2]赋值为1,点亮L3。

ucLed[2] = ((Voltage >= 1.5 && Voltage < 2.5) || (Voltage >= 3.5));

L4

在这里插入图片描述
与L3类似,不再赘述。

ucLed[3] = ((Freq >= 1000 && Freq < 5000) || (Freq >= 10000));

L5

在这里插入图片描述
L5与输出模式(OutPut_Mode)相关。
当输出固定电压(OutPut_Mode为0)时,L5熄灭(ucLed[4]为0);当输出实时电压(OutPut_Mode为1)时,L5点亮(ucLed[4]为1)。

ucLed[4] = OutPut_Mode;

最终代码

User文件

main.c

/*头文件声明区域*/
#include <STC15F2K60S2.H>
#include "Init.h"
#include "Key.h"
#include "Seg.h"
#include "Led.h"
#include "iic.h"

/*变量声明区域*/
unsigned char Key_Val,Key_Down,Key_Up,Key_Old;
unsigned char Seg_Buf[8] = {10, 10, 10, 10, 10, 10, 10, 10}; // 数码管显示数据
unsigned char Seg_Point[8] = {0, 0, 0, 0, 0, 0, 0, 0};		 // 数码管小数点数据
unsigned char Seg_Pos;										 // 数码管扫描位置
unsigned char ucLed[8] = {0, 0, 0, 0, 0, 0, 0, 0};			 // LED显示数据
unsigned int Slow_Down;										 // 减速计数器
bit Seg_Flag, Key_Flag;										 // 数码管和按键的标志位
unsigned int Time_1s;										 // 1秒钟计数器
unsigned int Freq;											 // 频率计算变量
bit Seg_Disp_Mode;     //数码管显示模式变量 0-频率显示界面 1-电压显示界面
float Voltage;        //实时电压数据
bit OutPut_Mode;      //输出模式 0-固定电压 1-变化电压
float Voltage_Output;  //输出电压
bit Seg_Enable_Flag = 1;      //数码管功能控制标志 1-点亮 0-熄灭
bit Led_Enable_Flag = 1;     //指示灯功能控制标志 1-点亮 0-熄灭

/*按键处理函数*/
void Key_Proc()
{
	if (Key_Flag)return;
	Key_Flag = 1;							  // 设置标志位,防止重复进入
	Key_Val = Key_Read();					  // 读取按键值
	Key_Down = Key_Val & (Key_Old ^ Key_Val); // 检测下降沿
	Key_Up = ~Key_Val & (Key_Old ^ Key_Val);  // 检测上升沿
	Key_Old = Key_Val;						  // 更新按键状态
	
		switch(Key_Down)
	{
		case 4:
			Seg_Disp_Mode ^= 1;
		break;
		
		case 5:
			OutPut_Mode ^= 1;
		break;
		
		case 6:
			Led_Enable_Flag ^= 1;
		break;
		
		case 7:
			Seg_Enable_Flag ^= 1;
		break;
	}
}

/* 信息处理函数 */
void Seg_Proc()
{
	unsigned char i=3;
	
	if (Seg_Flag)return;
	Seg_Flag = 1; // 设置标志位
	
	Voltage = Ad_Read(0x43) / 51.0;
	if(OutPut_Mode == 0) Voltage_Output = 2;
	else Voltage_Output = Voltage;
		
	Seg_Point[5] = Seg_Disp_Mode;
	if(Seg_Disp_Mode == 0)//频率显示界面
	{
		Seg_Buf[0] = 11;//F
		Seg_Buf[3] = Freq / 10000 % 10;
		Seg_Buf[4] = Freq / 1000 % 10;
		Seg_Buf[5] = Freq / 100 % 10;
		Seg_Buf[6] = Freq / 10 % 10;
		Seg_Buf[7] = Freq  % 10;
		while(Seg_Buf[i] == 0)
		{
			Seg_Buf[i] = 10;
			if(++i ==7) break;
		}
	}
	else//电压显示界面
	{
		Seg_Buf[0] = 12;//U
		Seg_Buf[3] = 10;
		Seg_Buf[4] = 10;
		Seg_Buf[5] = (unsigned char)Voltage;
		Seg_Buf[6] = (unsigned int)(Voltage * 100) /10 % 10;
		Seg_Buf[7] = (unsigned int)(Voltage * 100)% 10; 
	}
}

/* 其他显示函数 */
void Led_Proc() 
{
	unsigned char i;
	
	/*DA转换*/
	Da_Write(Voltage_Output * 51);
	
	/*LED相关*/
	for(i=0;i<2;i++) ucLed[i] = (i != Seg_Disp_Mode);
	ucLed[2] = ((Voltage >= 1.5 && Voltage < 2.5) || (Voltage >= 3.5));
	ucLed[3] = ((Freq >= 1000 && Freq < 5000) || (Freq >= 10000));
	ucLed[4] = OutPut_Mode;
}

/* 定时器0初始化函数 */
void Timer0_Init(void)
{
	AUXR &= 0x7F; // 设置定时器时钟12T模式
	TMOD &= 0xF0; // 设置定时器模式为16位定时器
	TMOD |= 0x05;
	TL0 = 0; // 设置定时器初始值
	TH0 = 0; // 设置定时器初始值
	TF0 = 0; // 清除TF0标志位
	TR0 = 1; // 启动定时器
}

/* 定时器1初始化函数 */
void Timer1_Init(void)
{
	AUXR &= 0xBF; // 设置定时器时钟12T模式
	TMOD &= 0x0F; // 设置定时器模式为16位定时器
	TL1 = 0x18;	  // 设置定时器初始值
	TH1 = 0xFC;	  // 设置定时器初始值
	TF1 = 0;	  // 清除TF1标志位
	TR1 = 1;	  // 启动定时器
	ET1 = 1;	  // 使能定时器1中断
	EA = 1;		  // 开启全局中断
}

/* 定时器1中断服务函数 */
void Timer1_Isr(void) interrupt 3
{
	/*数码管400ms的减速*/
	if (++Slow_Down == 400) 
	{
		Seg_Flag = Slow_Down = 0; // 更新数码管显示标志位
	}
	
	/*按键10ms的减速*/
	if (Slow_Down % 10 == 0)
	{
		Key_Flag = 0; // 更新按键处理标志位
	}
	
	/*1s的计数*/
	if (++Time_1s == 1000)  
	{
		Time_1s = 0;		   // 重置1秒钟计数器
		Freq = TH0 << 8 | TL0; // 计算频率
		TH0 = 0;			   // 重置定时器0的值
		TL0 = 0;
	}
	
	/*信息处理*/
	if(Seg_Enable_Flag == 1) 
		Seg_Disp(Slow_Down % 8, Seg_Buf[Slow_Down % 8], Seg_Point[Slow_Down % 8]); // 更新数码管显示
	else 
		Seg_Disp(Slow_Down % 8, 10, 0);
	if(Led_Enable_Flag == 1) 
		Led_Disp(Slow_Down % 8, ucLed[Slow_Down % 8]);							   // 更新LED显示
	else 
		Led_Disp(Slow_Down % 8,0);
}

/* 主函数 */
// 系统初始化,设置定时器和串口,然后进入主循环。
void main()
{
	Sys_Init();	// 系统初始化
	Timer1_Init();	// 初始化定时器1
	Timer0_Init();
	while (1)
	{
		Key_Proc();	 // 处理按键
		Seg_Proc();	 // 更新数码管显示
		Led_Proc();	 // 更新LED显示
	}
}

Driver文件

Init.c

#include "init.h"

void Sys_Init()
{
	P0 = 0xff;
	P2 = P2 & 0x1f | 0x80;
	P2 &= 0x1f;
	
	P0 = 0x00;
	P2 = P2 & 0x1f | 0xA0;
	P2 &= 0x1f;
}

LED.c

#include "LED.h"

void LED_Disp(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;
		P2 = P2 & 0x1f | 0x80;
	  P2 &= 0x1f;
		temp_old = temp;
	}
}

Seg.c

#include "Seg.h"

code unsigned char seg_dula[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0x88,0xc6,0x8c};//0-9为数字,10为熄灭,11为A,12为C,13为P
code unsigned char seg_wela[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void Seg_Disp(unsigned char wela,dula,point)
{
	P0 = 0xff;
	P2 = P2 & 0x1f | 0xe0;
	P2 &= 0x1f;
	
	P0 = seg_wela[wela];
	P2 = P2 & 0x1f | 0xc0;
	P2 &= 0x1f;
	
	P0 = seg_dula[dula];
	if(point) P0 &= 0x7f;
	P2 = P2 & 0x1f | 0xe0;
	P2 &= 0x1f;
}

Key.c

#include "Key.h"

unsigned char Key_Read()
{
	unsigned char temp = 0;
	
	P44 = 0;P42 = 1;P35 = 1;P34 = 1;
	if(P30 == 0) temp = 7;
	if(P31 == 0) temp = 6;
	if(P32 == 0) temp = 5;
	if(P33 == 0) temp = 4;
	
	P44 = 1;P42 = 0;P35 = 1;P34 = 1;
	if(P30 == 0) temp = 11;
	if(P31 == 0) temp = 10;
	if(P32 == 0) temp = 9;
	if(P33 == 0) temp = 8;
	
	P44 = 1;P42 = 1;P35 = 0;P34 = 1;
	if(P30 == 0) temp = 15;
	if(P31 == 0) temp = 14;
	if(P32 == 0) temp = 13;
	if(P33 == 0) temp = 12;
	
	P44 = 1;P42 = 1;P35 = 1;P34 = 0;
	if(P30 == 0) temp = 19;
	if(P31 == 0) temp = 18;
	if(P32 == 0) temp = 17;
	if(P33 == 0) temp = 16;
	
	return temp;
}

iic.c

#include "iic.h"
#include "intrins.h"
#define DELAY_TIME 10
sbit scl = P2 ^ 0;
sbit sda = P2 ^ 1;

//
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);
}

unsigned char Ad_Read(unsigned char addr)
{
	unsigned char temp;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	temp = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	return temp;
}

void Da_Write(unsigned char dat)
{
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x41);
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
}


http://www.kler.cn/a/535760.html

相关文章:

  • 寒假2.5
  • python:csv文件批量导入mysql
  • 【实战篇】巧用 DeepSeek,让 Excel 数据处理更高效
  • Linux命令总结
  • 点(线)集最小包围外轮廓效果赏析
  • PostgreSQL函数自动Commit/Rollback所带来的问题
  • React 设计模式:实用指南
  • GPU — 8 卡 GPU 服务器与 NVLink/NVSwitch 互联技术
  • 【AI】DeepSeek来了!!!
  • tolua[一]框架搭建,运行example
  • 【Day33 LeetCode】动态规划DP Ⅵ 背包问题
  • SQL Server的安装和简单使用
  • SQL精度丢失:CAST(ce.fund / 100 AS DECIMAL(10, 2)) 得到 99999999.99
  • 【Uniapp-Vue3】z-paging插件组件实现触底和下拉加载数据
  • 【Elasticsearch】random_sampler聚合
  • Leecode刷题C语言之全排列②
  • Spring Boot + Spring AI快速体验
  • Polardb三节点集群部署安装--附虚拟机
  • Linux 设备驱动分类(快速理解驱动架构)
  • 《大模型面试宝典》(2025版) 发布了
  • 国自然地区基金|基于深度学习多模态影像组学智能诊断非酒精性脂肪肝病的研究|基金申请·25-02-06
  • C#项目引用VB.NET 类库项目,生成一个EXE,这是什么原理
  • 【前端】【面试】【复习详解】【react】react生命周期--函数式全解
  • 深度剖析FFmpeg视频解码后的帧处理到Qt显示 从AVFrame到QImage的转换(一)
  • “卫星-无人机-地面”遥感数据快速使用及地物含量计算的实现方法
  • 【正点原子K210连载】第六十七章 音频FFT实验 摘自【正点原子】DNK210使用指南-CanMV版指南