蓝桥杯单片机组第十二届省赛第二批次
前言
第十二届省赛涉及知识点:NE555频率数据读取,NE555频率转换周期,PCF8591同时测量光敏电阻和电位器的电压、按键长短按判断。本试题涉及模块较少,题目不难,基本上准备充分的都能完整的实现每一个功能,并且板子上都能实现,一个恶心的地方就是通过PCF8591只采集一条通道的电压值是没有问题的,但是同时采集两条通道的时候,会出现问题,在另一篇文章已经给出了解决方法:
PCF8591一次测量多个通道导致数值不准确解决方法
附件:蓝桥杯单片机组第十二届省赛第二批次
一、阅读题目,了解性能需求
可以得出以下信息:
- 板子上需要将P34与SIGNAL通过跳线帽短接读取NE555产生的频率。
NE555部分已经详细地讲过如何实现了,可以点击下方传送门查阅:
传送门:NE555模块
- 数码管显示的频率、周期和电压值都是实际值,题目中说到的采集频率和电压只有在LED灯有用。
二、底层函数搭建
1.初始化
Init.h
#ifndef __Init_H__
#define __Init_H__void Init();#endif
Init.c
#include <STC15F2K60S2.H>
void Init()
{P0 = 0xff;P2 = P2 & 0x1f | 0x80;P2 &= 0x1f;P0 = 0x00;P2 = P2 & 0x1f | 0xa0;P2 &= 0x1f;
}
2.NE555和独立按键
由于NE555是通过P34引脚测量的,所以需要修改独立按键的底层代码。(屏蔽P34)
Key.h
#include <STC15F2K60S2.H>
#ifndef __Key_H__
#define __Key_H__unsigned char KeyDisp();#endif
Key.c
#include <STC15F2K60S2.H>unsigned char KeyDisp()
{unsigned char temp = 0;P44 = 0;P42 = 1;P35 = 1;if(P30 == 0)temp = 7;if(P31 == 0)temp = 6;if(P32 == 0)temp = 5;if(P33 == 0)temp = 4; return temp;
}
定时器部分
void Timer0_Init(void) //0毫秒@12.000MHz
{TMOD &= 0xF0; //设置定时器模式TMOD |= 0x05;TL0 = 0; //设置定时初始值TH0 = 0; //设置定时初始值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时
}void Timer1_Init(void) //1毫秒@12.000MHz
{AUXR &= 0xBF; //定时器时钟12T模式TMOD &= 0x0F; //设置定时器模式TL1 = 0x18; //设置定时初始值TH1 = 0xFC; //设置定时初始值TF1 = 0; //清除TF1标志TR1 = 1; //定时器1开始计时ET1 = 1; //使能定时器1中断EA = 1;
}void Timer1_Isr(void) interrupt 3
{systick++;if(++SegPos == 8)SegPos = 0;SegDisp(SegPos, SegBuf[SegPos], SegPoint[SegPos]);if(++Time_1s == 1000){Time_1s = 0;f = (TH0 << 8) | TL0;TH0 = TL0 = 0;}
}
2.数码管部分
数码管底层代码引入
Seg.h
#ifndef __Seg_H__
#define __Seg_H__void SegDisp(unsigned char wela, unsigned char dula, unsigned char point);#endif
Seg.c
#include <STC15F2K60S2.H>code unsigned char Seg_Table[] =
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0xff, //空
0xbf, //-
0x8e, //F
0xc1, //U
0xc8 //n
};void SegDisp(unsigned char wela, unsigned char dula, unsigned char point)
{P0 = 0xff;P2 = P2 & 0x1f | 0xe0;P2 &= 0x1f;P0 = (0x01 << wela);P2 = P2 & 0x1f | 0xc0;P2 &= 0x1f;P0 = Seg_Table[dula];if(point)P0 &= 0x7f;P2 = P2 & 0x1f | 0xe0;P2 &= 0x1f;
}
3.Led部分
Led.h
#ifndef __Led_H__
#define __Led_H__void LedDisp(unsigned char *ucLed);#endif
Led.c
#include <STC15F2K60S2.H>void LedDisp(unsigned char *ucLed)
{unsigned char i, temp = 0x00;static unsigned char temp_old = 0xff;for(i = 0; i < 8; i++)temp |= (ucLed[i] << i);if(temp != temp_old){P0 = ~temp;P2 = P2 & 0x1f | 0x80;P2 &= 0x1f;temp_old = temp;}
}
4.PCF8591部分
注:本篇文章中解决多通道读取采用的是连续读取两次电压值,舍弃第一个电压值的方法。
pcf8591.h
#ifndef __pcf8591_H__
#define __pcf8591_H__unsigned char AD_Read(unsigned char add);#endif
pcf8591.c
#include <STC15F2K60S2.H>
#include <intrins.h>/* # I2C代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求,进行代码调试和修改。
*/
#define DELAY_TIME 5
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 add)
{unsigned char temp;I2CStart();I2CSendByte(0x90);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CStart();I2CSendByte(0x91);I2CWaitAck();temp = I2CReceiveByte(); I2CSendAck(1);I2CStop();// 再次读取I2CStart();I2CSendByte(0x90);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CStart();I2CSendByte(0x91);I2CWaitAck();temp = I2CReceiveByte();I2CSendAck(1);I2CStop();return temp;
}
5.main.c
#include <STC15F2K60S2.H>
#include "Init.h"
#include "LED.h"
#include "Key.h"
#include "Seg.h"
#include "pcf8591.h"/* 变量声明区 */
unsigned char Key_Slow; //按键减速变量 10ms
unsigned char Key_Val, Key_Down, Key_Up, Key_Old; //按键检测四件套
unsigned int Seg_Slow; //数码管减速变量 500ms
unsigned char Seg_Buf[] = {10,10,10,10,10,10,10,10,10,10};//数码管缓存数组
unsigned char Seg_Pos;//数码管缓存数组专用索引
unsigned char Seg_Point[8] = {0,0,0,0,0,0,0,0};//数码管小数点使能数组
unsigned char ucLed[8] = {0,0,0,0,0,0,0,0};//LED显示数据存放数组
unsigned int Time_1s, f;/* 按键处理函数 */
void Key_Proc()
{if(Key_Slow) return;Key_Slow = 1; //按键减速Key_Val = Key();Key_Down = Key_Val & ~Key_Old; Key_Up = ~Key_Val & Key_Old;Key_Old = Key_Val;}/* 信息处理函数 */
void Seg_Proc()
{if(Seg_Slow) return;Seg_Slow = 1; //数码管减速}/* 其他显示函数 */
void Led_Proc()
{}/* 定时器0只用于计数 */
void Timer0_Init(void) //1毫秒@12.000MHz
{TMOD &= 0xF0; //设置定时器模式TMOD |= 0x05;TL0 = 0; //设置定时初始值TH0 = 0; //设置定时初始值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时
}/* 定时器1用于计时 */
void Timer1_Init(void) //1毫秒@12.000MHz
{AUXR &= 0xBF; //定时器时钟12T模式TMOD &= 0x0F; //设置定时器模式TL1 = 0x18; //设置定时初始值TH1 = 0xFC; //设置定时初始值TF1 = 0; //清除TF1标志TR1 = 1; //定时器1开始计时ET1 = 1;EA = 1;
}/* 定时器1中断服务函数 */
void Timer1_Server() interrupt 3
{/* NE555 */if(++Time_1s == 1000){Time_1s = 0;f = (TH0 << 8) | TL0;TH0 = TL0 = 0;}
}void main()
{Init();Timer0_Init();Timer1_Init();while(1){Key_Proc(); Seg_Proc();Led_Proc();}
}
三、数码管部分
老样子,定义SegMode变量来控制三个页面,SegMode值为0时为频率显示页面,为1时为周期设置界面,为2时为电压显示界面
在数码管Seg.c底层函数的段码表已经包含F、N、U和-的段码表了
1.频率显示页面
NE555测量频率的上限值是五位数,题目要求七位显示频率数据,要求高位为0熄灭,可以直接默认前两位数码管熄灭,再对后五个数码管进行高位熄灭,高位熄灭的实现逻辑如下:
unsigned char i = 0;
while(SegBuf[i] == 0)//循环条件:SegBuf[i]不为0时退出
{SegBuf[i] = 10;if(++i == 7)break;
}
数码管实现如下:
void SegProc()
{unsigned char i;switch(SegMode){case 0:SegPoint[5] = 0;SegBuf[0] = 12;SegBuf[1] = 10;SegBuf[2] = 10;SegBuf[3] = f / 10000 % 10;SegBuf[4] = f / 1000 % 10;SegBuf[5] = f / 100 % 10;SegBuf[6] = f / 10 % 10;SegBuf[7] = f % 10;i = 3;while(!SegBuf[i]){SegBuf[i] = 10;if(++i == 7)break;}break;}
}
2.周期显示页面
从题目可以得到,显示的周期是频率的倒数,也就是T= 1 f \frac{1}{f} f1,单位为us,而1s = 100 0000us,所以转换周期时要省上10 6 ^6 6。代码实现如下:
case 1:T = 1000000 / f;SegBuf[0] = 14;SegBuf[1] = T / 1000000 % 10;SegBuf[2] = T / 100000 % 10;SegBuf[3] = T / 10000 % 10;SegBuf[4] = T / 1000 % 10;SegBuf[5] = T / 100 % 10;SegBuf[6] = T / 10 % 10;SegBuf[7] = T % 10;i = 1;while(!SegBuf[i]){SegBuf[i] = 10;if(++i == 7)break;}
break;
3.电压显示页面
电压读取
这边给出两种方法
方法一:定义float型变量
idata float RD1_100x, RB2_100x;
idata bit ChannelMode;void ADCProc()
{RD1_100x = AD_Read(0x01) / 51.0; RB2_100x = AD_Read(0x03) / 51.0;
}void SegProc()
{case 2:SegBuf[0] = 13;SegBuf[1] = 11;SegBuf[2] = !ChannelMode ? 1 : 3;SegBuf[3] = 10;SegBuf[4] = 10;SegBuf[5] = !ChannelMode ? RD1_100x % 10 : RB2_100x % 10;SegPoint[5] = 1;SegBuf[6] = !ChannelMode ? RD1_100x * 10 % 10: RB2_100x * 10 % 10;SegBuf[7] = !ChannelMode ? RD1_100x * 100 % 10 : RB2_100x * 100 % 10;break;
}
方法二:定义unsigned int型变量接受读取的电压值放大100倍后的值
idata u16 RD1_100x, RB2_100x;
void ADCProc()
{RD1_100x = AD_Read(0x01) * 100 / 51; RB2_100x = AD_Read(0x03) * 100 / 51;
}
void SegProc()
{case 2:SegBuf[0] = 13;SegBuf[1] = 11;SegBuf[2] = !ChannelMode ? 1 : 3;SegBuf[3] = 10;SegBuf[4] = 10;SegBuf[5] = !ChannelMode ? RD1_100x / 100 : RB2_100x / 100;SegPoint[5] = 1;SegBuf[6] = !ChannelMode ? RD1_100x / 10 % 10 : RB2_100x / 10 % 10;SegBuf[7] = !ChannelMode ? RD1_100x % 10 : RB2_100x % 10;break;
}
4.数码管完整代码:
void SegProc()
{unsigned char i;if(Seg_Slow) return;Seg_Slow = 1; //数码管减速switch(SegMode){case 0:SegPoint[5] = 0;SegBuf[0] = 12;SegBuf[1] = 10;SegBuf[2] = 10;SegBuf[3] = f / 10000 % 10;SegBuf[4] = f / 1000 % 10;SegBuf[5] = f / 100 % 10;SegBuf[6] = f / 10 % 10;SegBuf[7] = f % 10;i = 3;while(!SegBuf[i]){SegBuf[i] = 10;if(++i == 7)break;}break;case 1:T = 1000000 / f;SegBuf[0] = 14;SegBuf[1] = T / 1000000 % 10;SegBuf[2] = T / 100000 % 10;SegBuf[3] = T / 10000 % 10;SegBuf[4] = T / 1000 % 10;SegBuf[5] = T / 100 % 10;SegBuf[6] = T / 10 % 10;SegBuf[7] = T % 10;i = 1;while(!SegBuf[i]){SegBuf[i] = 10;if(++i == 7)break;}break;case 2:SegBuf[0] = 13;SegBuf[1] = 11;SegBuf[2] = !ChannelMode ? 1 : 3;SegBuf[3] = 10;SegBuf[4] = 10;SegBuf[5] = !ChannelMode ? RD1_100x / 100 : RB2_100x / 100;SegPoint[5] = 1;SegBuf[6] = !ChannelMode ? RD1_100x / 10 % 10 : RB2_100x / 10 % 10;SegBuf[7] = !ChannelMode ? RD1_100x % 10 : RB2_100x % 10;break;}
}
四、按键部分
S4和S5的实现很简单,直接给出代码
S6的功能是任意界面下按下S6后,保存电位器的电压数据到电位器缓存变量中。
idata u16 RD1_100x, RB2_100x;
idata u16 RB2_100x_keep, f_keep;void KeyProc()
{KeyVal = KeyDisp();KeyDown = KeyVal & ~KeyOld;KeyUp = ~KeyVal & KeyOld;KeyOld = KeyVal;switch(KeyDown){case 4:if(++SegMode == 3){SegMode = 0;ChannelMode = 0;}break;case 5:ChannelMode ^= 1;break;case 6:RB2_100x_keep = RB2_100x;break;}
}
S7的功能是短按保存频率,长按打开/关闭Led
这个也是很常考的点了,也很简单
先定义一个Time_1000ms的unsigned int型变量放入定时器1中定时,当超过1000ms时置为1000(防止长按太久数据溢出),然后在设置一个按下S7的变量idata bit型变量CountFlag,当S7按下,CountFlag置1,定时器开始计时,松开S7,CountFlag置为0,计数值清零
注意:NE555和长按S7都是以定时1s为判断,因此定义变量时不要重复定义!
void KeyProc()
{KeyVal = KeyDisp();KeyDown = KeyVal & ~KeyOld;KeyUp = ~KeyVal & KeyOld;KeyOld = KeyVal;if(KeyDown == 7)CountFlag = 1;if(KeyUp == 7){CountFlag = 0;if(Time_1000ms >= 1001){LedFlag = !LedFlag;}elsef_keep = f;}
}void Timer1_Isr(void) interrupt 3
{systick++;if(++SegPos == 8)SegPos = 0;SegDisp(SegPos, SegBuf[SegPos], SegPoint[SegPos]);if(++Time_1s == 1000){Time_1s = 0;f = (TH0 << 8) | TL0;TH0 = TL0 = 0;}if(CountFlag){if(++Time_1000ms >= 1001)Time_1000ms = 1001;}elseTime_1000ms = 0;
}
按键完整代码
void KeyProc()
{KeyVal = KeyDisp();KeyDown = KeyVal & ~KeyOld;KeyUp = ~KeyVal & KeyOld;KeyOld = KeyVal;if(KeyDown == 7)CountFlag = 1;if(KeyUp == 7){CountFlag = 0;if(Time_1000ms >= 1001){LedFlag = !LedFlag;}elsef_keep = f;}switch(KeyDown){case 4:if(++SegMode == 3){SegMode = 0;ChannelMode = 0;}break;case 5:ChannelMode ^= 1;break;case 6:RB2_100x_keep = RB2_100x;break;}
}
五、Led部分
Led的实现完全没有难度
直接给出代码
void LedProc()
{if(LedFlag == 0){ucLed[0] = (RB2_100x > RB2_100x_keep);ucLed[1] = (f > f_keep);ucLed[2] = (SegMode == 0);ucLed[3] = (SegMode == 1);ucLed[4] = (SegMode == 2);}else{ucLed[0] = 0;ucLed[1] = 0;ucLed[2] = 0;ucLed[3] = 0;ucLed[4] = 0;}LedDisp(ucLed);
}
六、完整代码
#include <STC15F2K60S2.H>
#include "Init.h"
#include "LED.h"
#include "Key.h"
#include "Seg.h"
#include "pcf8591.h"/* 变量声明区 */
typedef unsigned char u8;
typedef unsigned int u16;idata u8 KeyVal, KeyDown, KeyUp, KeyOld;
idata u8 SegPos;
idata u8 SegMode;idata u16 f, Time_1s;
idata u16 T;
idata u16 RD1_100x, RB2_100x;
idata u16 RB2_100x_keep, f_keep;
idata u16 Time_1000ms;pdata u8 SegBuf[8] = {10,10,10,10,10,10,10,10};
pdata u8 SegPoint[8] = {0,0,0,0,0,0,0,0};
pdata u8 ucLed[8] = {0,0,0,0,0,0,0,0};idata bit ChannelMode;
idata bit CountFlag;
idata bit LedFlag;/* 按键处理函数 */
void Key_Proc()
{if(Key_Slow) return;Key_Slow = 1; //按键减速KeyVal = KeyDisp();KeyDown = KeyVal & ~KeyOld;KeyUp = ~KeyVal & KeyOld;KeyOld = KeyVal;if(KeyDown == 7)CountFlag = 1;if(KeyUp == 7){CountFlag = 0;if(Time_1000ms >= 1001){LedFlag = !LedFlag;}elsef_keep = f;}switch(KeyDown){case 4:if(++SegMode == 3){SegMode = 0;ChannelMode = 0;}break;case 5:ChannelMode ^= 1;break;case 6:RB2_100x_keep = RB2_100x;break;}
}/* 信息处理函数 */
void Seg_Proc()
{unsigned char i;if(Seg_Slow) return;Seg_Slow = 1; //数码管减速switch(SegMode){case 0:SegPoint[5] = 0;SegBuf[0] = 12;SegBuf[1] = 10;SegBuf[2] = 10;SegBuf[3] = f / 10000 % 10;SegBuf[4] = f / 1000 % 10;SegBuf[5] = f / 100 % 10;SegBuf[6] = f / 10 % 10;SegBuf[7] = f % 10;i = 3;while(!SegBuf[i]){SegBuf[i] = 10;if(++i == 7)break;}break;case 1:T = 1000000 / f;SegBuf[0] = 14;SegBuf[1] = T / 1000000 % 10;SegBuf[2] = T / 100000 % 10;SegBuf[3] = T / 10000 % 10;SegBuf[4] = T / 1000 % 10;SegBuf[5] = T / 100 % 10;SegBuf[6] = T / 10 % 10;SegBuf[7] = T % 10;i = 1;while(!SegBuf[i]){SegBuf[i] = 10;if(++i == 7)break;}break;case 2:SegBuf[0] = 13;SegBuf[1] = 11;SegBuf[2] = !ChannelMode ? 1 : 3;SegBuf[3] = 10;SegBuf[4] = 10;SegBuf[5] = !ChannelMode ? RD1_100x / 100 : RB2_100x / 100;SegPoint[5] = 1;SegBuf[6] = !ChannelMode ? RD1_100x / 10 % 10 : RB2_100x / 10 % 10;SegBuf[7] = !ChannelMode ? RD1_100x % 10 : RB2_100x % 10;break;}
}/* 其他显示函数 */
void Led_Proc()
{if(LedFlag == 0){ucLed[0] = (RB2_100x > RB2_100x_keep);ucLed[1] = (f > f_keep);ucLed[2] = (SegMode == 0);ucLed[3] = (SegMode == 1);ucLed[4] = (SegMode == 2);}else{ucLed[0] = 0;ucLed[1] = 0;ucLed[2] = 0;ucLed[3] = 0;ucLed[4] = 0;}LedDisp(ucLed);
}/* 定时器0只用于计数 */
void Timer0_Init(void) //1毫秒@12.000MHz
{TMOD &= 0xF0; //设置定时器模式TMOD |= 0x05;TL0 = 0; //设置定时初始值TH0 = 0; //设置定时初始值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时
}/* 定时器1用于计时 */
void Timer1_Init(void) //1毫秒@12.000MHz
{AUXR &= 0xBF; //定时器时钟12T模式TMOD &= 0x0F; //设置定时器模式TL1 = 0x18; //设置定时初始值TH1 = 0xFC; //设置定时初始值TF1 = 0; //清除TF1标志TR1 = 1; //定时器1开始计时ET1 = 1;EA = 1;
}/* 定时器1中断服务函数 */
void Timer1_Server() interrupt 3
{/* NE555 */if(++Time_1s == 1000){Time_1s = 0;f = (TH0 << 8) | TL0;TH0 = TL0 = 0;}if(CountFlag){if(++Time_1000ms >= 1001)Time_1000ms = 1001;}elseTime_1000ms = 0;
}void main()
{Init();Timer0_Init();Timer1_Init();while(1){Key_Proc(); Seg_Proc();Led_Proc();}
}
本篇文章中的代码已经通过4T测试
其余模块代码请自行添加到工程中即可运行,本篇文章仅提供一种实现思路,如有模块代码无法实现或者与题目要求相违,请移步评论区指出或私信我,看到会及时回复。
每周会更新两篇模拟赛、省赛或国赛的文章,敬请期待。
相关文章:
蓝桥杯单片机组第十二届省赛第二批次
前言 第十二届省赛涉及知识点:NE555频率数据读取,NE555频率转换周期,PCF8591同时测量光敏电阻和电位器的电压、按键长短按判断。 本试题涉及模块较少,题目不难,基本上准备充分的都能完整的实现每一个功能,并…...
React Native 原理
React Native 是一个跨平台移动应用开发框架,它允许开发者使用 JavaScript 和 React 来开发 iOS 和 Android 原生应用。React Native 的核心原理是通过 桥接(Bridge) 技术,使用 JavaScript 来控制原生组件,并将应用逻辑…...
C++简易贪食蛇项目
一.案例介绍 二.制作思路 三.墙模块 #include "wall.h" //初始化墙 void initWall() { for (int i 0; i < HEIGHT; i) { for (int j 0; j < WIDTH;j) { if (i 0 || j 0 || i HEIGHT - 1 || j WIDTH - 1) …...
C++蓝桥杯基础篇(七)
片头 嗨~小伙伴们,大家好!今天我们来一起学习蓝桥杯基础篇(七),学习相关字符串的知识,准备好了吗?咱们开始咯! 一、字符与整数的联系——ASCII码 每个常用字符都对应一个-128~127的…...
Sass基础
目录 什么是sass? Sass的安装 Sass的编译 Sass的语法: Sass的基本使用: 一、Sass变量: 二、嵌套语法: 三、import的使用: 四、mixin混入和include: 五、extend: 六、注释 七、if和if: 八、for: 总结: 什么是sas…...
Linux文档编辑相关命令详解
Linux文档编辑相关命令 1. grep grep (global regular expression) 命令用于查找文件里符合条件的字符串或正则表达式。 1.1 语法 grep [options] pattern [files] 1.2 常用选项 -i:忽略大小写进行匹配。-v:反向查找,只打印不匹配的行。-…...
QT实现简约美观的动画Checkbox
*最终效果: * 一共三个文件: main.cpp , FancyCheckbox.h , FancyCheckbox.cpp main.cpp #include <QApplication> #include "FancyCheckbox.h" #include <QGridLayout> int main(int argc, char *argv[]) {QApplication a(argc, argv);QWidget* w new…...
每日学习Java之一万个为什么?[MySQL面试篇]
分析SQL语句执行流程中遇到的问题 前言1 MySQL是怎么在一台服务器上启动的2 MySQL主库和从库是同时启动保持Alive的吗?3 如果不是主从怎么在启动的时候保证数据一致性4 ACID原则在MySQL上的体现5 数据在MySQL是通过什么DTO实现的6 客户端怎么与MySQL Server建立连接…...
git笔记
定义:分布式版本控制工具,免费开源的,快速高效的处理从小到大的项目,git占地面积小,性能快,有廉价的本地库 安装:官网最新版 全部点下一步就行 版本控制工具:使用中央服务器&#…...
Full GC 排查
在 Java 中,Full GC(完全垃圾回收)会对整个堆(包括年轻代和老年代,甚至可能包括永久代/元空间)进行垃圾回收,通常会导致较长的停顿(STW,Stop-The-World)。如果…...
VS2022远程调试Ubuntu中的C++程序
前言 最近想基于星火大模型的SDK开发第一些应用。但是,发现星火的SDK当中Linux版本的比较丰富,Windows 版本支持的比较少。但是,从调试的IDE而言,Visual Studio又是最方便的。所以,考虑采用Visual Studio Ubuntu的形式…...
Flutter 学习之旅 之 flutter 使用 flutter_screenutil 简单进行屏幕适配
Flutter 学习之旅 之 flutter 使用 flutter_screenutil 简单进行屏幕适配 目录 Flutter 学习之旅 之 flutter 使用 flutter_screenutil 简单进行屏幕适配 一、简单介绍 二、简单介绍 flutter_screenutil 三、安装 carousel_slider 四、简单案例实现 五、关键代码 六、补…...
【华为OD机考】华为OD笔试真题解析(16)--微服务的集成测试
题目描述 现在有n个容器服务,服务的启动可能有一定的依赖性(有些服务启动没有依赖),其次,服务自身启动加载会消耗一些时间。 给你一个 n n n \times n nn的二维矩阵useTime,其中useTime[i][i]10表示服务…...
NCCL AI 分布式训练集合通讯库技术基本原理
目录 文章目录 目录AI 分布式训练NCCL 的简介NCCL 的核心功能NCCL 的基本工作流程NCCL 的集合通信操作方式NCCL 的 API 编程示例 AI 分布式训练 在一个最初的 AI 模型训练场景中,由于模型自身的程序体积、输入的参数量以及样本的数据量都比较有限,一张 …...
算法-回溯篇01-组合
组合 力扣题目链接 题目描述 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 解题思路 刚开始做回溯的题目,关于回溯的相关知识推荐大家去看代码随想录的视频。 做了几道题,感觉回溯题…...
泵吸式激光可燃气体监测仪:快速精准守护燃气管网安全
在城市化进程加速的今天,燃气泄漏、地下管网老化等问题时刻威胁着城市安全。如何实现精准、高效的可燃气体监测,守护“城市生命线”,成为新型基础设施建设的核心课题。泵吸式激光可燃气体监测仪,以创新科技赋能安全监测࿰…...
Lumoz Chain正式上线:AI 时代的新算力破局者
新的叙事和技术突破永远是推动行业前行的核心动力。当下,AI Agent无疑是最炙手可热的赛道之一。 当加密世界将目光投向AI领域时,大多数项目仍停留在以AI为工具或应用场景的层面,试图通过集成AI模型或优化链上功能来吸引用户。然而࿰…...
算法之排序算法
排序算法 ♥常见排序算法知识体系详解♥ | Java 全栈知识体系 算法 - 排序 | CS-Notes 面试笔记 十大经典排序算法总结 | JavaGuide...
Java面试第七山!《MySQL索引》
一、索引的本质与作用 索引是帮助MySQL高效获取数据的数据结构,类似于书籍的目录。它通过减少磁盘I/O次数(即减少数据扫描量)来加速查询,尤其在百万级数据场景下,索引可将查询效率提升数十倍。 核心作用:…...
基于 Rust 与 GBT32960 规范的编解码层
根据架构设计,实现编解码层的代码设计 Cargo.toml 加入二进制序列化支持 # 序列化支持 ... bincode "1.3" # 添加二进制序列化支持 bytes-utils "0.1" # 添加字节处理工具 开始编码 错误处理(error.rs&#x…...
二、Redis 安装与基本配置:全平台安装指南 服务器配置详解
Redis 安装与基本配置:全平台安装指南 & 服务器配置详解 Redis 作为高性能的内存数据库,其安装和配置是使用 Redis 的第一步。本篇文章将全面介绍 Redis 的安装方式,覆盖 Windows、Linux、Docker 环境,并详细讲解 Redis 的基础配置,包括 持久化、日志、端口设置等。此…...
⭐算法OJ⭐矩阵的相关操作【动态规划 + 组合数学】(C++ 实现)Unique Paths 系列
文章目录 62. Unique Paths动态规划思路实现代码复杂度分析 组合数学思路实现代码复杂度分析 63. Unique Paths II动态规划定义状态状态转移方程初始化复杂度分析 优化空间复杂度状态转移方程 62. Unique Paths There is a robot on an m x n grid. The robot is initially lo…...
基于 Elasticsearch 和 Milvus 的 RAG 运维知识库的架构设计和部署落地实现指南
最近在整理一些业务场景的架构设计和部署落地实现指南 先放一个 【基于RAG的运维知识库 (ElasticSearch + Milvus) 的详细实现指南】,其中包含了详尽的技术实现细节、可运行的示例代码、原理分析、优缺点分析和应用场景分析。 架构描述: 基于RAG的运维知识库 (ElasticSearch…...
山西青年杂志山西青年杂志社山西青年编辑部2025年第3期目录
青年争鸣 教师发展中心行动转向的价值意蕴分析框架研究与启示 于宝证;李军红;郑钰莹;何易雯; 产教融合视角下职业本科工商管理专业人才培养模式探析 杜芯铭; 青年教育研究 教育数字化背景下高职院校的课堂教学研究 张晨; 统筹职业教育、高等教育、继续教育协同…...
使用Truffle、Ganache、MetaMask、Vue+Web3完成的一个简单区块链项目
文章目录 概要初始化Truffle项目创建编写合约编译合约配置Ganache修改truffle-config.js文件编写迁移文件部署合约使用Truffle 控制台使用MetaMask和VueWeb3与链交互 概要 使用Truffle、Ganache、MetaMask、VueWeb3完成的一个简单区块链项目。 初始化Truffle项目 安装好truf…...
【GenBI优化】提升text2sql准确率:建议使用推理大模型,增加重试
引言 Text-to-SQL(文本转 SQL)是自然语言处理(NLP)领域的一项重要任务,旨在将自然语言问题自动转换为可在数据库上执行的 SQL 查询语句。这项技术在智能助手、数据分析工具、商业智能(BI)平台等领域具有广泛的应用前景,能够极大地降低数据查询和分析的门槛,让非技术用…...
LLVM - 编译器前端 - 学习将源文件转换为抽象语法树(二)
一:处理消息 在一个庞大的软件(比如编译器)中,我们不希望将消息字符串分散在各个地方。如果需要修改消息内容或将其翻译成另一种语言,最好将它们集中存放在一个地方!目前缺少的是对消息的集中定义。下面我们看看来如何实现它。 一种简单的方法是,每条消息都有一个 ID(一…...
T-SQL 语言基础: SQL 数据库对象元数据及配置信息获取
目录 介绍目录视图 获取表和架构名称获取列信息 信息架构视图 获取表信息获取列信息 系统存储过程和函数 获取对象列表获取对象详细信息获取约束信息获取数据库属性信息 总结引用 介绍 在 SQL 数据库管理中,获取数据库对象的元数据信息是至关重要的。元数据提供了…...
基于vue框架的游戏博客网站设计iw282(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
系统程序文件列表 项目功能:用户,博客信息,资源共享,游戏视频,游戏照片 开题报告内容 基于FlaskVue框架的游戏博客网站设计开题报告 一、项目背景与意义 随着互联网技术的飞速发展和游戏产业的不断壮大,游戏玩家对游戏资讯、攻略、评测等内容的需求日…...
批量提取 Word 文档中的页面
如何将 Word 文档中的页面提取出来形成一个新的文档呢?比如将 Word 文档中的第一页提取出来、将 Word 文档中的最后一页提取出来、再或者将 Word 文档中的中间几页提取出来等等。人工的处理肯定非常的麻烦,需要新建 Word 文档,然后将内容复制…...
本地大模型编程实战(26)用langgraph实现基于SQL数据构建的问答系统(5)
本文将将扩展上一篇文章完成的 langgraph 链,继续使用基于 langgraph 链 ,对结构化数据库 SQlite 进行查询的方法。该系统建立以后,我们不需要掌握专业的 SQL 技能,可以用自然语言询问有关数据库中数据的问题并返回答案。主要完善…...
csrf与ssrf学习笔记
一、CSRF(Cross-Site Request Forgery) 1. 定义 攻击目标:利用用户已登录的合法身份,在用户不知情的情况下发起恶意请求。 核心条件:受害者需已登录目标系统,且浏览器会自动携带身份凭证(如 C…...
安装Maven配置阿里云地址 详细教程
下面以安装Maven公认最稳定版本(使用最多)3.6.1为例 1、访问maven官网 Maven官网 直接跳转Maven3.6.1 Maven3.6.1 2、点击下载 跳转页面后继续单击 Maven 3 archives 下载后解压放到自己的软件目录下 ~ 2.配置本地仓库 在目录下创建repo文件夹 &…...
我的世界1.20.1forge模组开发进阶物品(7)——具有动画、3D立体效果的物品
基础的物品大家都会做了对吧?包括武器的释放技能,这次来点难度,让物品的贴图呈现动画效果和扔出后显示3D立体效果,这个3D立体效果需要先学习blockbench,学习如何制作贴图。 Blockbench Blockbench是一个用于创建和编辑三维模型的免费软件,特别适用于Minecraft模型的设计…...
火语言RPA--PDF提取表格
【组件功能】:提取PDF文档指定位置表格 配置预览 配置说明 文件路径 支持T或# 默认FLOW输入项 待提取表格的PDF文件的完整路径。 提取位置 全部、指定页、指定范围3种位置供选择。 PDF文件密码 支持T或# 打开PDF文件的密码。 页码 支持T或# 提取指定页的页…...
【开源-线程池(Thread Pool)项目对比】
一些实现**线程池(Thread Pool)**功能的开源项目的对比分析。 线程池功能的开源项目 项目名称语言优点缺点适用场景开源代码链接ThreadPoolC简单易用,代码简洁;适合快速原型开发。功能较为基础,不支持动态调整线程数…...
JavaScript系列05-现代JavaScript新特性
JavaScript作为网络的核心语言之一,近年来发展迅速。从ES6(ECMAScript 2015)开始,JavaScript几乎每年都有新的语言特性加入,极大地改善了开发体验和代码质量。本文主要内容包括: ES6关键特性:解构赋值与扩展运算符&am…...
【二.提示词工程与实战应用篇】【3.Prompt调优:让AI更懂你的需求】
最近老张在朋友圈秀出用AI生成的国风水墨画,隔壁王姐用AI写了份惊艳全场的年终总结,就连楼下小卖部老板都在用AI生成营销文案。你看着自己跟AI对话时满屏的"我不太明白您的意思",是不是怀疑自己买了台假电脑?别慌,这可能是你的打开方式不对。今天咱们就聊聊这个…...
C++学习之C++初识、C++对C语言增强、对C语言扩展
一.C初识 1.C简介 2.第一个C程序 //#include <iostream> //iostream 相当于 C语言下的 stdio.h i - input 输入 o -output 输出 //using namespace std; //using 使用 namespace 命名空间 std 标准 ,理解为打开一个房间,房间里有我们所需…...
基于eRDMA实测DeepSeek开源的3FS
DeepSeek昨天开源了3FS分布式文件系统, 通过180个存储节点提供了 6.6TiB/s的存储性能, 全面支持大模型的训练和推理的KVCache转存以及向量数据库等能力, 每个客户端节点支持40GB/s峰值吞吐用于KVCache查找. 发布后, 我们在阿里云ECS上进行了快速的复现, 并进行了性能测试, ECS…...
写Oracle表耗时25分钟缩短到23秒——SeaTunnel性能优化
本文主要给大家介绍JDBC Source批处理任务动态切分优化,希望大家批评指正 JDBC Source 如果配置了table_path 和 partition_column,引擎会对数据进行动态切分,可以通过分析样本数据优化切分区间,规避数据倾斜问题。 目前发现任务…...
Golang的图形用户界面设计
一、Golang图形用户界面设计的基本概念 了解Golang 也称为Go语言,是一种由Google开发的开源编程语言。它具有良好的并发性,能够更好地利用多核处理器,同时也拥有丰富的标准库和强大的工具链。 什么是图形用户界面 图形用户界面(GU…...
蓝桥杯备赛Day12 动态规划1基础
动态规划 动态规划基础 动态规划将复杂问题分解成很多重叠的子问题,再通过子问题的解得到整个问题的解 分析步骤: 确定状态:dp[i][j]val,“到第i个为止,xx为j的方案数/最小代价/最大价值” 状态转移方程: 确定最终状态 要求: (1)最优子结构 (2)无后效性…...
我的AI工具箱Tauri版-通用音频转文本
本模块支持FunAsr和FasterWhisper两种模式,可批量处理音频与视频文件,自动生成txt文本与srt字幕,满足多种应用场景需求。 工具内置FunAsr,无需额外参数调整,特别适用于中文语音的高质量转录,确保识别准确率…...
C#—Settings配置详解
C#—Settings配置详解 在C#项目中,全局配置通常指的是应用程序的设置(settings),这些设置可以跨多个类或组件使用,并且通常用于存储应用程序的配置信息,如数据库连接字符串、用户偏好设置等。 Settings配置…...
机器学习算法——分类任务
算法: 1、决策树 2、随机森林 3、梯度提升树 4、逻辑回归 5、支持向量机SVM 6、K近邻 KNN 7、朴素贝叶斯 8、多层感知机 9、统一分类 10、比较总结 11、完整代码 1、决策树 1.1 Decision Tree Analysis (C4.5,CART,CHAID)决策树 算法树结构特征选择连续值处理缺失…...
聆听PostgreSQL数据库的使用
参考:(1)零基础入门PostgreSQL教程 (2)菜鸟教程 文章目录 一、PostgreSQL是什么?二、基本使用1.下载2.操作(1)数据库(2)表 一、PostgreSQL是什么?…...
C# 装箱(Boxing)与拆箱(Unboxing)
C# 装箱(Boxing)与拆箱(Unboxing) 在 C# 中,装箱和拆箱是与值类型(如结构体)和引用类型(如类)之间的转换相关的操作。它们是类型系统的一部分,但如果不正确使…...
vue实例
// vue应用通过createApp函数创建一个新的应用实例,相当于根组件 import { createApp } from vue import App from ./App.vue // 在一个vue项目当中,有且只有一个vue的实例对象 const appcreateApp(App) // App:根组件 // 实例必须调用了.mount&am…...
Spring Boot的启动流程
Spring Boot 的启动流程是一个复杂且有序的过程: 创建SpringApplication实例 — 调用run方法 — 启动完成(发布应用启动事件,配置环境,创建ApplicationContext,准备ApplicationContext,刷新ApplicationContext[【创建B…...