藍橋杯單片機組第十二屆省賽第二批次

前言
第十二屆省賽涉及知識點: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測試
在這里插入圖片描述

其余模塊代碼請自行添加到工程中即可運行,本篇文章僅提供一種實現思路,如有模塊代碼無法實現或者與題目要求相違,請移步評論區指出或私信我,看到會及時回復。
每周會更新兩篇模擬賽、省賽或國賽的文章,敬請期待。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896248.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896248.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896248.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

opencv:距離變換 cv2.distanceTransform

函數 cv2.distanceTransform() 用于計算圖像中每一個非零點像素與其最近的零點像素之間的距離&#xff08;Distance Transform&#xff0c; DT算法&#xff09;,輸出的是保存每一個非零點與最近零點的距離信息&#xff1b;圖像上越亮的點&#xff0c;代表了離零點的距離越遠。 …

基于Spring Boot的黨員學習交流平臺設計與實現(LW+源碼+講解)

專注于大學生項目實戰開發,講解,畢業答疑輔導&#xff0c;歡迎高校老師/同行前輩交流合作?。 技術范圍&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容&#xff1a;…

自動駕駛兩個傳感器之間的坐標系轉換

有兩種方式可以實現兩個坐標系的轉換。 車身坐標系下一個點p_car&#xff0c;需要轉換到相機坐標系下&#xff0c;旋轉矩陣R_car2Cam&#xff0c;平移矩陣T_car2Cam。點p_car在相機坐標系下記p_cam. 方法1&#xff1a;先旋轉再平移 p_cam T_car2Cam * p_car T_car2Cam 需要注…

k8s ssl 漏洞修復

針對Kubernetes集群中SSL/TLS協議信息泄露漏洞&#xff08;CVE-2016-2183&#xff09;的修復&#xff0c;需重點修改涉及弱加密算法的組件配置。以下是具體修復步驟及驗證方法&#xff1a; 一、漏洞修復步驟 1. 修復etcd服務 修改配置文件 &#xff1a; 編輯 /etc/kubernetes/…

數字IC后端培訓教程| 芯片后端實戰項目中base layer drc violation解析

今天分享一個咱們社區IC后端訓練營學員遇到的一個經典DRC案例。這個DRC Violation的名字為PP.S.9(這里的PP就是Plus P)。這一層是屬于管子的base layer。更多關于base layer的介紹&#xff0c;可以查看下面這份教程。 https://alidocs.dingtalk.com/api/doc/transit?spaceId5…

從零到一學習c++(基礎篇--筑基期十一-類)

從零到一學習C&#xff08;基礎篇&#xff09; 作者&#xff1a;羨魚肘子 溫馨提示1&#xff1a;本篇是記錄我的學習經歷&#xff0c;會有不少片面的認知&#xff0c;萬分期待您的指正。 溫馨提示2&#xff1a;本篇會盡量用更加通俗的語言介紹c的基礎&#xff0c;用通俗的語言去…

DeepSeek技術全景解析:架構創新與行業差異化競爭力

一、DeepSeek技術體系的核心突破 架構設計&#xff1a;效率與性能的雙重革新 Multi-head Latent Attention (MLA)&#xff1a;通過將注意力頭維度與隱藏層解耦&#xff0c;實現顯存占用降低30%的同時支持4096超長上下文窗口。深度優化的MoE架構&#xff1a;結合256個路由專家…

插入排序:一種簡單而直觀的排序算法

大家好&#xff01;今天我們來聊聊一個簡單卻非常經典的排序算法——插入排序&#xff08;Insertion Sort&#xff09;。在所有的排序算法中&#xff0c;插入排序是最直觀的一個。 一、插入排序的基本思想 插入排序的核心思想是&#xff1a;將一個待排序的元素&#xff0c;插…

2025年校園網絡招聘會匯總

1、衛生健康行業2025屆畢業生春季校園網絡招聘會 企業數量職位數量崗位數量10020002000 訪問地址&#xff1a; https://www.weirenjob.com/zph/zph_wsjkxy2025jbyscjxywlzph/ 2、山東地區面向2025屆高校畢業生網絡招聘活動 企業數量職位數量崗位數量909271052434 訪問地址&a…

Windows 10 GPU STACK 0.5.1 安裝

Windows 10 GPU STACK 0.5.1 安裝 1 GPUStack 安裝1.Python安裝&#xff08;3.10/11/12&#xff09;2.GPUStack 下載3.生成密碼4.訪問5.設置模型下載目錄6.禁用開機自啟并重啟服務7.安裝模型8.查看安裝的進度 2.試驗場聊天測試1.對話模式 3.API Key 測試 1 GPUStack 安裝 1.Py…

【數據結構】快指針和慢指針

一、 給你單鏈表的頭結點 head ,請你找出并返回鏈表的中間結點。如果有兩個中間結點,則返回第二個中間結點。 要求&#xff1a;只遍歷一遍鏈表 可以使用快慢指針&#xff1a;fast 一次走兩步&#xff0c;slow 一次走一步。當 fast NULL&#xff08;偶數個結點&#xff09;或…

1.3 嵌入式系統的固件

嵌入式系統的固件&#xff0c;一般情況下的作用是: 1.硬件抽象層&#xff08;HAL&#xff09;&#xff1a;固件提供了一個硬件抽象層&#xff0c;它將硬件的復雜性隱藏起來&#xff0c;為上層軟件提供了一套標準的接口。這樣&#xff0c;操作系統和應用程序不需要直接與硬件打交…

中國工業互聯網研究院:人工智能大模型年度發展趨勢報告

當前&#xff0c;以大模型為代表的人工智能正快速演進&#xff0c;激發全球科技之變、產業之變、時代之變&#xff0c;人工智能發展迎來新高潮。隨著大模型推理、多模態生成、智能體等創新技術的發展&#xff0c;大模型賦能千行百業將進一步提速。中國工業互聯網研究院全方位剖…

【cv】vs2022配置opencv

release下配置包含目錄和庫目錄 E:\sdk\sdk_cuda12.3\opencv490\include E:\sdk\sdk_cuda12.3\opencv490\include\opencv2 E:\sdk\sdk_cuda12.3\opencv490\lib release下配置包含鏈接器輸入的依附依賴項 opencv_world490.lib release編譯文件夾下需手動復制opencv_world49…

Python Pandas庫使用指南:從入門到精通

1. 引言 Pandas 是 Python 中用于數據處理和分析的核心庫之一。它提供了高效的數據結構(如 DataFrame 和 Series),能夠輕松處理結構化數據,支持數據清洗、過濾、聚合、合并等操作。Pandas 在數據分析、機器學習和科學計算領域中被廣泛使用。 本文將詳細介紹 Pandas 的基本…

Visual Studio中打開多個項目

1) 找到解決方案窗口 2) 右鍵添加→ 選擇現有項目 3) 選擇.vcxproj文件打開即可

react路由總結

目錄 一、腳手架基礎語法(16~17) 1.1、hello react 1.2、組件樣式隔離(樣式模塊化) 1.3、react插件 二、React Router v5 2.1、react-router-dom相關API 2.1.1、內置組件 2.1.1.1、BrowserRouter 2.1.1.2、HashRouter 2.1.1.3、Route 2.1.1.4、Redirect 2.1.1.5、L…

內外網隔離文件傳輸解決方案|系統與釘釘集成+等保合規,安全提升70%

一、背景與痛點 在內外網隔離的企業網絡環境中&#xff0c;員工與外部協作伙伴&#xff08;如釘釘用戶&#xff09;的文件傳輸面臨以下挑戰&#xff1a; 1. **安全性風險**&#xff1a;內外網直連可能導致病毒傳播、數據泄露。 2. **操作繁瑣**&#xff1a;傳統方式需頻繁切…

多線程篇學習面試

多線程 1.樂觀鎖、CAS思想 java樂觀鎖機制&#xff1a; ? 樂觀鎖體現的是悲觀鎖的反面。它是一種積極的思想&#xff0c;它總是認為數據是不會被修改的&#xff0c;所以是不會對數據上鎖的。但是樂觀鎖在更新的時候會去判斷數據是否被更新過。樂觀鎖的實現方案一般有兩種&a…

云服務器和物理服務器該如何選擇

隨著互聯網的快速發展&#xff0c;企業大多都會選擇云服務器和物理服務器進行使用&#xff0c;那么對于云服務器和物理服務器兩者之間該如何進行選擇呢&#xff1f; 云服務器可以為用戶和企業提供網站處理中等到高流量所需要的一切&#xff0c;云服務器中的高可用能性功能&…