視頻請參考http://v.eepw.com.cn/video/play/id/1917
PWM調光原理:通過對LED的開關控制實現不同的亮度,當開關的頻率超過了100 HZ,人的肉眼就感覺不到閃了。
呼吸燈原理:PWM的占空比由5%變為6%,7%。。。。。。100%然后再變小99%,98%,97%。。。。。。5%。。。。。。不斷循环。
代碼如下:
定義寄存器如下:
unsigned char LedTimerCount; //
unsigned char LedOnCount;
unsigned int LedStepCount;
unsigned char Direction;
用定時器產生一個4K的中斷,中斷代碼如下:
#pragma vector = INTTM00_vect
__interrupt void MD_INTTM00(void)
{
TMIF00 = 0U; //clear int flag
LedStepCount++;
if(LedStepCount>300)
{
LedStepCount=0;
if(Direction==0)
{
LedOnCount++;
if(LedOnCount>98)
{
Direction=1;
}
}
else
{
LedOnCount--;
if(LedOnCount<2)
{
Direction=0;
}
}
}
LedTimerCount++;
if(LedTimerCount>100)
{
LedTimerCount=0;
}
if(LedTimerCount>LedOnCount)
{
P7_bit.no7=1; //led off
}
else
{
P7_bit.no7=0; //led on
}
}
內部溫度傳感器+串口(UART2)+上位機軟件實現溫度監控
視頻:http://v.eepw.com.cn/video/play/id/1920
測溫度用了平均值濾波法,下面介紹幾種常用的軟件濾波方法
1.平均值濾波法:連繼讀到幾個數值,求平均數。
缺點:需要連續多次進行AD轉換,占用CPU資源
技巧:讀8次,和右移3位就得到平均值,可省去除法運算
2.移動平均值濾波法:建立一個數組記錄數據,每進行一次AD 轉換后,把最新數據移入數組,把最舊的數據移出數組。再求平均值
優點:節省CPU資源
3.去頭去尾求平均值:就像奧運比賽一樣,把最大最小的數據去除了,再求平均數。
優點:把最大最小值去掉了,結果將更精確
下面是一些代碼,給大家參考一下,為了省時間,有很多代碼是系統生成的:
下面兩個子程序用于計算溫度:
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function stores the AD conversion results and calculates the temperature.
**
** Parameters:
** None
**
** Returns:
** None
**
**-----------------------------------------------------------------------------
*/
void ADC_Calculation_Temp(void)
{
unsigned char i;
unsigned short TempBuffer;
g_temp_adcvalue=0x0000;
for(i=0;i<8;i++)
{
ADS = _80_AD_INPUT_TEMPERSENSOR_0;
AD_Start();
/* Wait for the A/D conversion to complete */
while(ADIF == 0);
/* Clear ADC interrupt flag */
ADIF = 0;
AD_Read(&TempBuffer); // Store the conversion result in TempBuffer
g_temp_adcvalue = + TempBuffer;
}
g_temp_adcvalue >>=3; // Get average
temp = (float) 1.44 / g_ref_hexvalue;
g_temperature = (float) (25 - ((((g_temp_adcvalue * temp) - 1) * 1000) / 3.6)); // Calculate the temperature value in 癈
TempBuffer=(unsigned short)(g_temperature*10);
TXBuffer[0]=CMD_SETTING; //command
TXBuffer[1]=CMD_SEND_TEMPERATURE; //command
TXBuffer[2]=0x31; //channel
TXBuffer[3]=(unsigned char)(TempBuffer/100)+0x30; //Change the temperature to BCD
TXBuffer[4]=(unsigned char)(TempBuffer%100/10)+0x30;
TXBuffer[5]='.';
TXBuffer[6]=(unsigned char)(TempBuffer%10)+0x30;
TXBuffer[7]='C';
TXBuffer[8]=CMD_END_DATA;
UartTX(&TXBuffer[0]); //Send data to computer via UART2
while(TXStatus!=TX_FINISH);
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function stores the AD conversion results and calculates the reference voltage.
**
** Parameters:
** None
**
** Returns:
** None
**
**-----------------------------------------------------------------------------
*/
void ADC_Calculation_Ref(void)
{
unsigned char i;
unsigned short TempBuffer;
g_ref_hexvalue=0x0000;
for(i=0;i<8;i++)
{
ADS = _81_AD_INPUT_TEMPERSENSOR_1; //select internal temperature sensor
AD_Start();
/* Wait for the A/D conversion to complete */
while(ADIF == 0);
/* Clear ADC interrupt flag */
ADIF = 0;
AD_Read(&TempBuffer); // Store the conversion result in TempBuffer
g_ref_hexvalue = + TempBuffer;
}
g_ref_hexvalue >>=3; //get average
}
下面是串口發送數據及中斷程序:
void UartTX(unsigned char *p)
{
TXStatus=TX_START;
SRMK2 = 1U; /* Disable Reception Interrupt */
SREMK2 = 1U; /* Disable Reception error Interrupt */
TXPointer=p;
STMK2 = 1U; /* disable INTST0 interrupt */
TXD2=*TXPointer++; // Send System on msg to host computer
TXCount=1;
STIF2 = 0U; /* clear INTST2 interrupt flag */
STMK2 = 0U; /* enable INTST0 interrupt */
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function is INTST2 interrupt service routine.
**
** Parameters:
** None
**
** Returns:
** None
**
**-----------------------------------------------------------------------------
*/
#pragma vector = INTST2_vect
__interrupt void MD_INTST2(void)
{
TXD2 = * TXPointer; // TX next character
TXCount++;
if (* TXPointer == CMD_END_DATA || TXCount==MAX_PACKET_LEN) // TX over?
{
TXStatus=TX_FINISH;
SRIF2 = 0U; /* clear INTSR2 interrupt flag */
SRMK2 = 0U; /* enable INTSR2 interrupt */
SREIF2 = 0U; /* clear INTSRE2 interrupt flag */
SREMK2 = 0U; /* enable INTSRE2 interrupt */
STMK2 = 1U; /* disable INTST0 interrupt */
}
TXPointer++;
}
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 | |
【分享评测,赢取加热台】使用8051单片机驱动WS2812被打赏40分 |