在51單片機中,是沒有PWM這種外設(shè)的,其實PWM的原理很簡單,就是將單片機的引腳按設(shè)定好的時間拉高拉低引腳。時間用定時器(T0,T1)就可以產(chǎn)生,高低電平只需要在定時器中斷中拉高拉低就行。
創(chuàng)新互聯(lián)總部坐落于成都市區(qū),致力網(wǎng)站建設(shè)服務有網(wǎng)站制作、成都網(wǎng)站制作、網(wǎng)絡(luò)營銷策劃、網(wǎng)頁設(shè)計、網(wǎng)站維護、公眾號搭建、微信小程序開發(fā)、軟件開發(fā)等為企業(yè)提供一整套的信息化建設(shè)解決方案。創(chuàng)造真正意義上的網(wǎng)站建設(shè),為互聯(lián)網(wǎng)品牌在互動行銷領(lǐng)域創(chuàng)造價值而不懈努力!往往我們在寫程序是都要開啟定時器來作為程序定時功能,比如時間片;而為了讓輸出的波形更加標準,模擬PWM應該獨享一個定時器,這樣輸出的波形才會更加的完美。
可以通過設(shè)置定時器重裝載值來設(shè)置PWM的頻率,那占空比如何設(shè)置?通過載中斷中放置一個靜態(tài)變量累加。例如:我要設(shè)置一個PWM周期為100ms的,占空比為30%的PWM波形,我需要設(shè)置定時器每次發(fā)生中斷的時間為10ms,當靜態(tài)變量i?< 3, 相應的引腳輸出0,當3<= i?< 10,相應的引腳輸出1.
#ifndef MID_PWM_H
#define MID_PWM_H
#include "reg52.h"
#include "c51_gpio.h"
typedef u16 PWM_Period;
typedef struct
{
//綁定IO口,用于快速開關(guān)PWM
unsigned char PWM_State;
GPIO_TypeDef GPIOx;
GPIO_PinNum_t GPIO_Pin;
//設(shè)置占空比和一個周期的時間
u16 Dievdend;//分子
u16 Divsor;//分母
u8 record_time_flag;
PWM_Period time;//毫秒級
u16 old_time;
}PWM_TypeDef;
void PWM_set_and_start(PWM_TypeDef* PWM_InitStructure);
void PWM_OnOff(PWM_TypeDef* PWM_InitStructure, u8 state);
void PWM_Modify_PWM_Period(PWM_TypeDef* PWM_InitStructure, PWM_Period time);
void PWM_Modify_DutyCycle(PWM_TypeDef* PWM_InitStructure, unsigned char Dievdend, unsigned char Divsor);
void PWM_set(void);
#endif
#include "mid_pwm.h"
#include "bsp_uart.h"
#include "bsp_time0.h"
extern u16 time_count;
void PWM_set_and_start(PWM_TypeDef* PWM_InitStructure)
{
u16 temp = 0;
u16 DutyCycle_time = PWM_InitStructure->time / PWM_InitStructure->Divsor * PWM_InitStructure->Dievdend;
if(PWM_InitStructure->PWM_State == 0)
{
if(PWM_InitStructure->record_time_flag == 0)
{
PWM_InitStructure->record_time_flag = 1;
PWM_InitStructure->old_time = time_count;
}
else
{
if(PWM_InitStructure->old_time< time_count)
{
temp = time_count - PWM_InitStructure->old_time;
}
else
{
temp = 0xFFFF - PWM_InitStructure->old_time + time_count;
}
if(temp >= 0 && temp< DutyCycle_time)
{
GPIO_Write(PWM_InitStructure->GPIOx, PWM_InitStructure->GPIO_Pin, Bit_RESET);
// bsp_uart_send_data(0xA1);
// delay_us(40000);
}
else if(temp< PWM_InitStructure->time && temp >= DutyCycle_time)
{
GPIO_Write(PWM_InitStructure->GPIOx, PWM_InitStructure->GPIO_Pin, Bit_SET);
// bsp_uart_send_data(0xB1);
// delay_us(40000);
}
else if(temp >= PWM_InitStructure->time)
{
PWM_InitStructure->record_time_flag = 0;
// bsp_uart_send_data(0xC1);
// delay_us(40000);
}
}
}
}
void PWM_OnOff(PWM_TypeDef* PWM_InitStructure, u8 state)
{
PWM_InitStructure->PWM_State = state;
}
void PWM_Modify_PWM_Period(PWM_TypeDef* PWM_InitStructure, PWM_Period time)
{
PWM_InitStructure->time = time;
}
void PWM_Modify_DutyCycle(PWM_TypeDef* PWM_InitStructure, unsigned char Dievdend, unsigned char Divsor)
{
PWM_InitStructure->Dievdend = Dievdend;
PWM_InitStructure->Divsor = Divsor;
}
通過模擬的PWM控制直流無刷電機?本來想著說將PWM1這個變量聲明成code類型,然而悲催的是,其不能用指針來訪問,然后想了一下,這個變量是在flash中,而指針的概念是存在內(nèi)存中的,因此訪問會有問題?
#include "app_motor.h"
PWM_TypeDef PWM1 =
{
0,
P_0,
GPIO_Pin_1,
15,
80,
0,
800,
0
};
void app_set_motor_speed(void)
{
GPIO_Write(P_0, GPIO_Pin_0, 1);//控制H橋一直導通
PWM_set_and_start(&PWM1);//PWM控制另外一個通路,這樣就能控制速度了
}
在寫的過程中,我發(fā)現(xiàn)51單片機是真的慢,寫個中斷回調(diào)和直接用變量time_count++計數(shù)時間差別巨大.
你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧