標(biāo)題:
單片機(jī)實(shí)現(xiàn)PWM調(diào)節(jié)LED燈亮度程序及仿真?
[打印本頁]
作者:
XYH_123
時(shí)間:
2017-4-22 23:46
標(biāo)題:
單片機(jī)實(shí)現(xiàn)PWM調(diào)節(jié)LED燈亮度程序及仿真?
有沒有大神分享個(gè)實(shí)例,最近在學(xué)習(xí)這個(gè)
作者:
cjjcjj1
時(shí)間:
2017-4-23 13:25
提示:
作者被禁止或刪除 內(nèi)容自動(dòng)屏蔽
作者:
zha
時(shí)間:
2017-4-24 21:42
我最近在做三路pwm控制rgb小燈的顏色,因?yàn)榘遄由蠜]有pwm,所以是用純軟件實(shí)現(xiàn)的
作者:
zha
時(shí)間:
2017-4-24 21:44
#include <reg52.h>
sbit PWMOUT = P0^0;
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
unsigned char HighRH = 0; //高電平重載值的高字節(jié)
unsigned char HighRL = 0; //高電平重載值的低字節(jié)
unsigned char LowRH = 0; //低電平重載值的高字節(jié)
unsigned char LowRL = 0; //低電平重載值的低字節(jié)
void ConfigPWM(unsigned int fr, unsigned char dc);
void ClosePWM();
void main()
{
unsigned int i;
EA = 1; //開總中斷
ENLED = 0; //使能獨(dú)立 LED
ADDR3 = 1;
ADDR2 = 1;
ADDR1 = 1;
ADDR0 = 0;
while (1)
{
ConfigPWM(100, 10); //頻率 100Hz,占空比 10%
for (i=0; i<40000; i++);
ClosePWM();
ConfigPWM(100, 40); //頻率 100Hz,占空比 40%
for (i=0; i<40000; i++);
ClosePWM();
ConfigPWM(100, 90); //頻率 100Hz,占空比 90%
for (i=0; i<40000; i++);
ClosePWM(); //關(guān)閉 PWM,相當(dāng)于占空比 100%
for (i=0; i<40000; i++);
}
}
/* 配置并啟動(dòng) PWM,fr-頻率,dc-占空比 */
void ConfigPWM(unsigned int fr, unsigned char dc)
{
unsigned int high, low;
unsigned long tmp;
tmp = (11059200/12) / fr; //計(jì)算一個(gè)周期所需的計(jì)數(shù)值
high = (tmp*dc) / 100; //計(jì)算高電平所需的計(jì)數(shù)值
low = tmp - high; //計(jì)算低電平所需的計(jì)數(shù)值
high = 65536 - high + 12; //計(jì)算高電平的重載值并補(bǔ)償中斷延時(shí)
low = 65536 - low + 12; //計(jì)算低電平的重載值并補(bǔ)償中斷延時(shí)
HighRH = (unsigned char)(high>>8); //高電平重載值拆分為高低字節(jié)
HighRL = (unsigned char)high;
LowRH = (unsigned char)(low>>8); //低電平重載值拆分為高低字節(jié)
LowRL = (unsigned char)low;
TMOD &= 0xF0; //清零 T0 的控制位
TMOD |= 0x01; //配置 T0 為模式 1
TH0 = HighRH; //加載 T0 重載值
TL0 = HighRL;
ET0 = 1; //使能 T0 中斷
TR0 = 1; //啟動(dòng) T0
PWMOUT = 1; //輸出高電平
}
/* 關(guān)閉 PWM */
void ClosePWM()
{
TR0 = 0; //停止定時(shí)器
ET0 = 0; //禁止中斷
PWMOUT = 1; //輸出高電平
}
/* T0 中斷服務(wù)函數(shù),產(chǎn)生 PWM 輸出 */
void InterruptTimer0() interrupt 1
{
if (PWMOUT == 1) //當(dāng)前輸出為高電平時(shí),裝載低電平值并輸出低電平
{
TH0 = LowRH;
TL0 = LowRL;
PWMOUT = 0;
}
else //當(dāng)前輸出為低電平時(shí),裝載高電平值并輸出高電平
{
TH0 = HighRH;
TL0 = HighRL;
PWMOUT = 1;
}
}
復(fù)制代碼
這是我板子上的代碼,你要用需要改改
作者:
38178138
時(shí)間:
2017-4-24 22:07
通過占空比調(diào)節(jié)
作者:
stc0079
時(shí)間:
2017-8-10 09:57
zha 發(fā)表于 2017-4-24 21:44
這是我板子上的代碼,你要用需要改改
這個(gè)是純軟件控制的嗎?
作者:
ll250520
時(shí)間:
2017-8-10 10:45
可以仿真,看PWM波形
作者:
yangchaozhong
時(shí)間:
2017-8-10 17:38
#include "led.h"
//LED IO初始化
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE); //使能PA,PD端口時(shí)鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //LED0-->PA.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根據(jù)設(shè)定參數(shù)初始化GPIOA.8
GPIO_SetBits(GPIOA,GPIO_Pin_8); //PA.8 輸出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1-->PD.2 端口配置, 推挽輸出
GPIO_Init(GPIOD, &GPIO_InitStructure); //推挽輸出 ,IO口速度為50MHz
GPIO_SetBits(GPIOD,GPIO_Pin_2); //PD.2 輸出高
}
#include "pwm.h"
#include "led.h"
void TIM1_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能GPIO外設(shè)時(shí)鐘使能
//設(shè)置該引腳為復(fù)用輸出功能,輸出TIM1 CH1的PWM脈沖波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //TIM_CH1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復(fù)用推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個(gè)更新事件裝入活動(dòng)的自動(dòng)重裝載寄存器周期的值 80K
TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來作為TIMx時(shí)鐘頻率除數(shù)的預(yù)分頻值 不分頻
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設(shè)置時(shí)鐘分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計(jì)數(shù)模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時(shí)器模式:TIM脈沖寬度調(diào)制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
TIM_OCInitStructure.TIM_Pulse = 0; //設(shè)置待裝入捕獲比較寄存器的脈沖值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //根據(jù)TIM_OCInitStruct中指定的參數(shù)初始化外設(shè)TIMx
TIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE 主輸出使能
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH1預(yù)裝載使能
TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的預(yù)裝載寄存器
TIM_Cmd(TIM1, ENABLE); //使能TIM1
}
#include "delay.h"
#include "sys.h"
#include "pwm.h”
int main(void)
{
u16 led0pwmval=0;
u8 dir=1;
delay_init(); //延時(shí)函數(shù)初始化
LED_Init(); //初始化與LED連接的硬件接口
TIM1_PWM_Init(899,0);//不分頻。PWM頻率=72000/(899+1)=80Khz
while(1)
{
delay_ms(10);
if(dir)led0pwmval++;
else led0pwmval--;
if(led0pwmval>300)dir=0;
if(led0pwmval==0)dir=1;
TIM_SetCompare1(TIM1,led0pwmval);
}
}
這是三個(gè)keil下創(chuàng)建的C文件
作者:
au597
時(shí)間:
2017-8-11 17:05
控制PWM波的占空比就可以實(shí)現(xiàn)亮度變化,呼吸燈就是這樣的
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1