W5500通過上位機控制實現調節LED燈帶的亮度
該實驗採用W5500開發板通過上位機向開發板傳送命令來控制外接燈帶的亮度;主要的過程如下:
1 實驗目的
上位機通過串列埠傳送格式為:“redbrightness,greenbrightness,bluebrightness”的字串到MCU。MCU將數字轉化成相應的亮度。
2 實驗總體設計
實驗主要分兩個部分:PWM配置以及串列埠通訊配置。整個實驗的難點在於ASCII碼轉換為數字的過程。
3 PWM產生原理
通用定時器可以利用GPIO引腳進行脈衝輸出。要使STM32的通用定時器TIMx產生PWM輸出,需要用到3個暫存器。分別是:捕獲/比較模式暫存器(TIMx_CCMR1/2)、捕獲/比較使能暫存器(TIMx_CCER)、捕獲/比較暫存器(TIMx_CCR1~4)。(注意,還有個TIMx的ARR暫存器是用來控制pwm的輸出頻率)。
對於捕獲/比較模式暫存器(TIMx_CCMR1/2),該暫存器總共有2個,TIMx _CCMR1和TIMx _CCMR2。TIMx_CCMR1控制CH1和2,而TIMx_CCMR2控制CH3和4。其次是捕獲/比較使能暫存器(TIMx_CCER),該暫存器控制著各個輸入輸出通道的開關。
最後是捕獲/比較暫存器(TIMx_CCR1~4),該暫存器總共有4個,對應4個輸通道CH1~4。4個暫存器作用相近,都是用來設定pwm的佔空比的。例如,若配置脈衝計數器TIMx_CNT為向上計數,而過載暫存器TIMx_ARR被配置為N,即TIMx_CNT的當前計數值數值X在TIMxCLK時鐘源的驅動下不斷累加,當TIMx_CNT的數值X大於N時,會重置TIMx_CNT數值為0重新計數。而在TIMxCNT計數的同時,TIMxCNT的計數值X會與比較暫存器TIMx_CCR預先儲存了的數值A進行比較,當脈衝計數器TIMx_CNT的數值X小於比較暫存器TIMx_CCR的值A時,輸出高電平(或低電平),相反地,當脈衝計數器的數值X大於或等於比較暫存器的值A時,輸出低電平(或高電平)。如此迴圈,得到的輸出脈衝週期就為過載暫存器TIMx_ARR儲存的數值(N+1)乘以觸發脈衝的時鐘週期,其脈衝寬度則為比較暫存器TIMx_CCR的值A乘以觸發脈衝的時鐘週期,即輸出PWM的佔空比為A/(N+1) 。
4 PWM配置步驟
4.1 配置GPIO
void LED_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);//開啟複用時鐘
GPIO_InitStructure.GPIO_Pin = LED_RED| LED_BLUE | LED_GREEN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC, LED_RED | LED_BLUE | LED_GREEN);
}
4.2 配置定時器
void TIMER_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);
TIM_BaseInitStructure.TIM_Period = 255;
TIM_BaseInitStructure.TIM_Prescaler = 0;
TIM_BaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_BaseInitStructure);
TIM_ARRPreloadConfig(TIM3, ENABLE);
TIM_Cmd(TIM3, ENABLE);
}
4.3 配置PWM
void PWM_Config(void)
{
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //選擇模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low //極性為高電平有效
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
TIM_OC4Init(TIM3, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable);
TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable);
TIM_CtrlPWMOutputs(TIM3,ENABLE);
}
4.4 小結
PWM模式1:
在向上計數時,一旦TIMx_CNTTIMx_CCR1時通道1為無效電平(OC1REF=0),否則為有效電平(OC1REF=1)。
PWM模式2:
在向上計數時,一旦TIMx_CNTTIMx_CCR1時通道1為有效電平,否則為無效電平。
同時輸出的有效點評還與極性配置有關:
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
此配置是高電平為有效電平,反之亦然。
5 UART配置步驟
5.1 配置UART1以及對應的GPIO
void Usart_Config(uint32_t BaudRate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = BaudRate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART_PC, &USART_InitStructure);
USART_ITConfig(USART_PC, USART_IT_RXNE, ENABLE); //開啟串列埠接收中斷
USART_ITConfig(USART_PC, USART_IT_IDLE, ENABLE); //開啟串列埠接收中斷
USART_Cmd(USART_PC, ENABLE);
}
5.2 配置中斷
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
5.3 中斷函式
void USART1_IRQHandler(void)
{
uint8_t clear = clear;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
RxBuffer[RxCounter++] = USART_ReceiveData(USART1);
}
else if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
{
clear = USART1->SR;
clear = USART1->DR; //先讀SR再讀DR,為了清除IDLE中斷
RxNumber = RxCounter;
RxCounter = 0; //計數清零
IDLE_Flag = 1; //標記接收到一幀的資料
}
}
5.4 小結
STM32微控制器可以實現接收不定長度位元組資料。由於STM32微控制器帶IDLE中斷,利用這個中斷,可以接收不定長位元組的資料。由於STM32屬於ARM微控制器,所以這篇文章的方法也適合其他的ARM微控制器。
IDLE就是串列埠收到一幀資料後,發生的中斷。比如說給微控制器一次發來1個位元組,或者一次發來8個位元組,這些一次發來的資料,就稱為一幀資料,也可以叫做一包資料。 一幀資料結束後,就會產生IDLE中斷。這個中斷十分有用,可以省去了好多判斷的麻煩。
6 ASCII碼轉換為數字
6.1 實現步驟:
while(RxBuffer[i] != ','){ i++; len++;}//如果不為','長度加1
for(j=i-len; j
value = RxBuffer[j]&0x0f; //將ascii碼轉換為數字
pwm_red += value * Power(len-1);
len--;
}
i++;
len = 0;
while(RxBuffer[i] != ','){ i++; len++;}
for(j=i-len; j
value = RxBuffer[j]&0x0f; //將ascii碼轉換為數字
pwm_green += value * Power(len-1);
len--;
}
i++;
len = 0;
while(RxBuffer[i] != '\0'){ i++; len++;}
for(j=i-len; j
value = RxBuffer[j]&0x0f; //將ascii碼轉換為數字
pwm_blue += value * Power(len-1);
len--;
}
RedOutput(pwm_red);
GreenOutput(pwm_green);
BlueOutput(pwm_blue);
pwm_red = 0;
pwm_green = 0;
pwm_blue = 0;
for(i=0; i<11; i++) RxBuffer[i] = NULL;//清除陣列
i = 0;
len = 0;
}
}
}
6.2 10的n次方函式
uint8_t Power(uint8_t pow)
{
uint8_t i;
uint8_t sum = 1;
for(i=0; i
return sum;
}
相關文章
- 【.NET 與樹莓派】PWM 調節LED小燈的亮度樹莓派
- 1、51微控制器實現LED燈的閃爍
- win10為什麼不能調節亮度 win10調節亮度的方法Win10
- 榮耀手機自動調節亮度怎麼關閉?榮耀手機關閉調節自動亮度教程
- win10螢幕亮度怎麼調節 win10螢幕亮度調節的方法Win10
- windows10調節螢幕亮度怎麼操作_windows10亮度調節在哪Windows
- 如何實現臺達PLC與上位機的資料通訊?
- 51微控制器入門:LED燈控制(01)
- 電腦亮度怎麼調亮度按哪個鍵 電腦亮度調節操作方法
- 帶燈LED按鈕開關接線方法
- win10亮度不能調節的如何修復_win10亮度調節失靈的最佳解決方法Win10
- flutter視訊全頻播放,音量亮度的調節Flutter
- win10螢幕亮度低怎麼調節 臺式win10調節亮度低操作方法Win10
- FPGA筆記[2]-撥碼開關控制LED燈FPGA筆記
- 隱喻現實的《律法之地》,是如何通過細節提升劇情帶入感的?
- 透過終端控制螢幕亮度
- win10亮度調節沒了怎麼辦_win10沒有亮度調節選項恢復方法Win10
- win10螢幕亮度不能調節調節無效怎麼辦Win10
- win10螢幕亮度無法調節?一招解決Win10電腦亮度調節失靈Win10
- 微控制器小白學習之路(四)---led燈的閃爍
- 關於Linux核心自帶GPIO LED控制Linux
- S5PV210 | 裸機彙編LED流水燈實驗
- 51微控制器實現流水燈
- 控制皮膚找不到調螢幕亮度win10 怎麼把電腦螢幕亮度調暗Win10
- STM32使用定時器在普通gpio上模擬pwm-紅牛開發板LED1的亮度調節定時器
- C# 簡易的串列埠監視上位機實現C#串列埠
- Android通過Chronometer控制元件實現計時功能Android控制元件
- 以色列諜戰術:竟能靠調節螢幕亮度,行竊取機密之事?
- 鍵盤怎麼調節燈光模式 鍵盤調燈光是哪個鍵模式
- C#如何開發透過USB進行串列埠通訊的Androud上位機C#串列埠
- win10亮度無法調整怎麼辦_win10螢幕亮度調節不了如何解決Win10
- 機械鍵盤怎麼調燈光 機械鍵盤的燈怎麼調模式模式
- 這款免費的多屏亮度調節軟體,真的愛了
- 【android】自定義佈局控制控制元件的位置可以通過繼承FrameLayout實現Android控制元件繼承
- Win10螢幕亮度無法調節解決辦法 Win10螢幕亮度調不了怎麼回事?Win10
- 通過佇列實現棧OR通過棧實現佇列佇列
- 最大化LED亮度以降低系統成本
- 上位機開發之三菱Q系列PLC通訊實踐
- win10亮度怎麼調_win10如何調整亮度Win10