日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Linux實現(xiàn)方波輸出和PWM技術(shù)(linux方波輸出pmw)

隨著人們對數(shù)字化和自動化需求的增加,嵌入式系統(tǒng)在市場上的應(yīng)用越來越廣泛,而Linux系統(tǒng)作為軟件開發(fā)非常成熟的一個操作系統(tǒng),被廣泛應(yīng)用于嵌入式系統(tǒng)中。在嵌入式系統(tǒng)開發(fā)中,有許多應(yīng)用需要使用到PWM技術(shù)或者方波輸出,本文將會詳細講解如何在Linux系統(tǒng)中實現(xiàn)方波輸出和PWM技術(shù)。

一、方波輸出

方波信號是一種具有特定周期和占空比的信號,一般用于嵌入式系統(tǒng)中的定時器、DAC轉(zhuǎn)換、蜂鳴器等場合,現(xiàn)在我們將借助Linux系統(tǒng)實現(xiàn)方波輸出。

1.1 硬件搭建

方波輸出的硬件搭建如圖1所示,需要一個單片機作為信號發(fā)生器和一個示波器進行觀察。

![圖1](https://img-blog.csdn.net/20230331210056508?watermark/2/text/aHR0cDovL2J2cuY3Nkbi5uZXQvbG9naW5fZ3VpZGUx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/q/75)

1.2 打開XT2時鐘

在CCS(Code Composer Studio)中,多數(shù)情況需要用到內(nèi)部低頻晶振(LFXT1),然而現(xiàn)在我們沒用到它,而使用外部高頻晶振(XT2)。需要進行如下配置:

(1)flash主程序分配區(qū)域

在 startup_ccs/hw_memmap.h 文件中添加如下宏定義:

#define HW_NMI (0xFFFEu)

將NMI vector定義設(shè)置在微控制器的外部RAM中。

(2)時鐘配置

在CPU主頻為16MHz(CLK)和數(shù)量級于4~20MHz的外部時鐘的設(shè)定下,格式為:

#include

UCSCTL3 |= SELREF_2; // Set DCO FLL reference = XT2 = 16MHz

UCSCTL4 |= SELA_2; // Set ACLK = XT2 = 16MHz

UCSCTL0 |= UCSON; // Enable UCS subsystem

UCSCTL4 |= SELS_4 | SELM_4; // CLK=MCLK=XT2

此處,UCSCTL3是內(nèi)部系統(tǒng)時鐘,表示將此時鐘配置為使用XT2作為DCO FLL參考時鐘,UCSCTL4是時鐘門控寄存器,SELREF_2表示使用XT2作為DCO FLL參考時鐘,SELA_2表示設(shè)置ACLK時鐘源為XT2,SELS_4和SELM_4表示將時鐘源分別設(shè)置為CLK和MCLK。

1.3 實現(xiàn)方波讀寫操作

(1)打開輸出口

P8SEL |= BIT0;

這里P8SEL和SEL和dir是三個位于io.h頭文件中的宏定義。P8SEL代表P8口,SEL口和DIR口分別用于配置端口是輸入還是輸出,這里我們將P8口的P8.0位于SEL高阻態(tài)。

(2)關(guān)閉濾波器

/*

* Regarding Digital IOs’ filtering, if a I/O line,

* primary or secondary function, is expected to experience

* a sharp rising or falling edge, and that we want to

* capture that signal, one would have to disable the

* digital filter associated to the I/O line using the

* digital IO disable register DIO#_FSEL.

*

* DIO#_FSEL &= ~bitfield;

*

* DIO# is the name of the Digital IO and bitfield is the

* bitfield associated to that Digital IO.

* __even_in_range is a macro that dynamically compares the

* user defined number with the base of the register.

*

* We’ll disable all digital filters for this example.

*/

P8DIR |= BIT0;

P8DS |= BIT0;

P8OUT &= ~BIT0;

P8SEL &= ~BIT0;

P8REN &= ~BIT0;

P8SEL |= BIT0;

這里需要將濾波器概念介紹一下。數(shù)字IO端口在信號輸入時,當(dāng)解析器的輸出跳變時,端口會使用一個低頻率振蕩電路(低通濾波器)將輸入信號進行濾波。濾波器按照設(shè)備的預(yù)定閾值設(shè)定為一個可濾波的更大上升沿時延(通常在幾微秒到幾百微秒之間),過濾掉了較慢的信號干擾。當(dāng)端口輸出時,需要將端口濾波器關(guān)掉,否則會影響輸出。通過配置P8口的P8.0相應(yīng)的FSEL控制寄存器,可以實現(xiàn)關(guān)閉數(shù)字濾波器。

(3)實現(xiàn)方波輸出

while (1) { // Loop forever

period = 20; // 20ms period

pulsewidth = period / 2; // Time the signal stays high

TA0CCR0 = TA1CCR0 = period * 1000 / 25; // Counter for up/down mode

TA0CCR1 = TA1CCR1 = pulsewidth * 1000 / 25; // Time when output is high

TA0CCTL1 = TA1CCTL1 = OUTMOD_7; // Set output mode to toggle

TA0CTL = TA1CTL = TASSEL__XT2 | MC__UPDOWN | TACLR; // Set upcounter & clear timer

while (1){}; // Let period edge interrupt handle next pulse

}

在這段代碼中,我們通過配置TA0和TA1兩個定時器,實現(xiàn)了單片機生成一段特定占空比的方波信號。這里的定時器是通用定時器(Timer_A),是單片機中常用的高級定時器。

TA0CCR0是計數(shù)器閾值,TA0CCR1是比較器閾值,TA0CCTL1是比較器控制器,OUTMOD_7表示設(shè)置輸出模式為“比較輸出模式7”(即:除計數(shù)器為0時置位外,其他情況下,比較器寄存器與計數(shù)器寄存器相等則翻轉(zhuǎn)信號,否則不翻轉(zhuǎn))。TASSEL_2是選擇TA的時鐘源為XT2,MC_UPDOWN是計數(shù)模式設(shè)為向上向下計數(shù)模式,TACLR是允許清除TA計時器計數(shù)器。

1.4 完整代碼

下面是生成方波信號的完整代碼:

#include

int mn (void) {

WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

P8SEL |= BIT0; // Set P8.0 for secondary peripheral module function (GPIO output)

P8DIR |= BIT0; // Configure P8.0 as output

P8DS |= BIT0; // Connect P8.0 to I/O pad

P8OUT &= ~BIT0; // Set initial output to 0

P8SEL &= ~BIT0; // Disconnect P8.0 from NMI/nRST

P8REN &= ~BIT0; // Disable internal pullup resistor

P8SEL |= BIT0; // Select peripheral module function (in this case, TACLK)

while (1) { // Loop forever

period = 20; // 20ms period

pulsewidth = period / 2; // Time the signal stays high

TA0CCR0 = TA1CCR0 = period * 1000 / 25; // Counter for up/down mode

TA0CCR1 = TA1CCR1 = pulsewidth * 1000 / 25; // Time when output is high

TA0CCTL1 = TA1CCTL1 = OUTMOD_7; // Set output mode to toggle

TA0CTL = TA1CTL = TASSEL__XT2 | MC__UPDOWN | TACLR; // Set upcounter & clear timer

while (1){}; // Let period edge interrupt handle next pulse

}

二、PWM技術(shù)

PWM技術(shù)(Pulse-width modulation)又稱脈寬調(diào)制技術(shù),是一種通過調(diào)節(jié)周期相等的脈沖寬度來控制輸出電壓或電流的技術(shù),一般應(yīng)用于馬達控制、LED的亮度控制等場合。下面我們將介紹在Linux系統(tǒng)中如何實現(xiàn)PWM技術(shù)。

2.1 硬件搭建

PWM技術(shù)的硬件搭建如圖2所示,需要一個單片機作為信號發(fā)生器和一個示波器進行觀察。

![圖2](https://img-blog.csdn.net/20230331211053518?watermark/2/text/aHR0cDovL2J2cuY3Nkbi5uZXQvbG9naW5fZ3VpZGUx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/q/75)

2.2 驅(qū)動器

PWM技術(shù)的es0風(fēng)驅(qū)動器通過將電源轉(zhuǎn)換為PWM信號來控制電機的轉(zhuǎn)速。驅(qū)動器是由一個控制器、一個驅(qū)動芯片和一個三相橋組成的??刂破髫撠?zé)控制電機的電流,驅(qū)動芯片ON/OFF是在這個信號的控制下進行的。使用PWM技術(shù),我們可以調(diào)整PWM信號的峰值來控制電機的輸出功率。

2.3 PWM方式實現(xiàn)

在Linux系統(tǒng)中,實現(xiàn)PWM方式有兩種:軟件PWM和硬件PWM。軟件PWM的優(yōu)點是實現(xiàn)簡單,但精度有限,很難實現(xiàn)更高分辨率的PWM波形。硬件PWM技術(shù)通過直接控制MCU的輸出端口來生成高分辨率的PWM波形,但由于接口的限制,硬件PWM技術(shù)的靈活性比軟件PWM要低。

下面我們將介紹如何在Linux系統(tǒng)中通過硬件PWM技術(shù)來實現(xiàn)控制一個3相電機的轉(zhuǎn)速。

(1)配置PWM輸出輸出引腳

我們需要向設(shè)備樹引擎添加定時器、PWM驅(qū)動程序和節(jié)點,以實現(xiàn)PWM控制。

給xilinx,dma節(jié)點添加定時器屬性,將PWM信號輸出到zynq (ps)端口。定時器只需要設(shè)定時鐘源和計數(shù)器周期即可。

pwm-leds {

compatible = “pwm-leds”;

led0 {

pwms = ;

pwn-period = ;

line-names = “pwm0”;

default-brightness-level = ;

};

};

&pwm0 {

status = “okay”;

pwn-period = ; /* 100Hz with internal clock */

ti,shoot-yes;

};

配置完畢后,我們可以讀取PWM周期和占空比并將其寫入設(shè)備文件,以控制電機的速度。

(2)控制電機的速度

控制電機的轉(zhuǎn)速是通過調(diào)整PWM信號的頻率和占空比來實現(xiàn)的。具體來說,我們可以通過增加PWM信號的頻率來加快電機的轉(zhuǎn)速,同時通過增加PWM信號的占空比來提高其輸出功率。

下面是代碼,用于通過PWM技術(shù)驅(qū)動一個3相電機:

/* pwm_leds.c */

#include

#include

#include

#include

#include

#include

#include

#include

#define DEVICE_NAME “pwm-leds”

static struct pwm_device *pwm_dev;

static struct device *dev;

static void pwm_leds_set_brightness_level(unsigned int level)

{

printk(KERN_INFO “pwm_leds: Set brightness level to %u\n”, level);

/* Level should be in the range of [0, pwn-period] */

level = min_t(unsigned int, pwm_get_period(pwm_dev), level);

/* Set PWM duty cycle */

pwm_config(pwm_dev, level, pwm_get_period(pwm_dev));

/* Enable the PWM signal */

pwm_enable(pwm_dev);

/* Wt a short while for the new settings to take effect */

msleep(50);

}

/* Device attribute callbacks */

static ssize_t brightness_level_show(struct device *dev,

struct device_attribute *attr, char *buf)

{

return scnprintf(buf, PAGE_SIZE, “%u\n”,

pwm_get_duty_cycle(pwm_dev));

}

static ssize_t brightness_level_store(struct device *dev,

struct device_attribute *attr, const char *buf,

size_t count)

{

int value;

int ret;

ret = kstrtoint(buf, 10, &value);

if (ret

return ret;

if ((value pwm_get_period(pwm_dev)))

return -EINVAL;

pwm_leds_set_brightness_level(value);

return count;

}

/* Device attributes */

static DEVICE_ATTR(brightness_level, S_IWUSR|S_IRUGO,

brightness_level_show, brightness_level_store);

/* Platform device driver */

static int pwm_leds_probe(struct platform_device *pdev)

{

struct device_node *np = pdev->dev.of_node;

int err;

if (!np)

return -ENODEV;

pwm_dev = devm_pwm_get(&pdev->dev, NULL);

if (IS_ERR(pwm_dev))

return PTR_ERR(pwm_dev);

/* Initialize device attributes */

err = device_create_file(&pdev->dev, &dev_attr_brightness_level);

if (err)

goto fl;

/* Create a new device node */

dev = device_create(pc_class, NULL, 0, NULL, DEVICE_NAME);

if (IS_ERR(dev)) {

err = PTR_ERR(dev);

goto fl;

}

dev_set_drvdata(dev, pwm_dev);

return 0;

fl:

if (&dev_attr_brightness_level.attr)

device_remove_file(&pdev->dev, &dev_attr_brightness_level);

return err;

}

static int pwm_leds_remove(struct platform_device *pdev)

{

device_remove_file(&pdev->dev, &dev_attr_brightness_level);

device_unregister(dev);

return 0;

}

static struct platform_driver pwm_leds_driver = {

.probe = pwm_leds_probe,

.remove = pwm_leds_remove,

.driver = {

.name = DEVICE_NAME,

.owner = THIS_MODULE,

},

};

static int __init pwm_leds_init(void)

{

return platform_driver_register(&pwm_leds_driver);

}

static void __exit pwm_leds_exit(void)

{

platform_driver_unregister(&pwm_leds_driver);

}

MODULE_LICENSE(“GPL”);

module_init(pwm_leds_init);

module_exit(pwm_leds_exit);

成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián),建站經(jīng)驗豐富以策略為先導(dǎo)10多年以來專注數(shù)字化網(wǎng)站建設(shè),提供企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計,響應(yīng)式網(wǎng)站制作,設(shè)計師量身打造品牌風(fēng)格,熱線:028-86922220

小車的電機驅(qū)動要不要L298N?我是想用PMW方式調(diào)速,是單片機直接輸出高低電平到L298N嗎?

我驅(qū)動電機的時候用了光耦,不用的話電機停不下來,電路圖百度文庫有,找不到的話我給你發(fā)一個。

不需要用L298N,將上圖的DC MTR1接到你單片機的PWM1口,DC MTR2接到單族鏈片機的PWM2口,你需要程序做的是:清DC MTR2為低電平,并輸出PWM信號到PWM1口;反之亦然。

注意:該電路不帶過流檢測,單片機塵穗賣復(fù)位的時候一定要清PWM1、PWM2兩個端口,否則程序如一直不啟動,兩個口均為高電平狀態(tài),此時Q1、Q2、Q4、Q6四個三極派逗管為導(dǎo)通狀態(tài)!

達林頓管有壓降,不可避免的對電機速度有限制,可以試著用場春棚做效應(yīng)管,場效應(yīng)管沒有壓降,但是驅(qū)動電壓高,可以先升壓再和告用單片機控制三極扒衡管,進而控制場效應(yīng)管,這樣就把速度提上去了!

L298N的內(nèi)部結(jié)構(gòu)就是你圖里的橋接??梢圆挥娩h薯L298N。

可以不用光耦。

PWM(不是PMW)可以直接接298上的兩個使能擾和端。

我用298做了個,也是PWM調(diào)銀李者速,控制兩個電機。沒有用光耦。

基于單片機信號發(fā)生器設(shè)計重點研究問題是什么

利用單片機做信號發(fā)生器,其重點就是單片機的主頻啦

  因為主頻代表著程序運行的時間,這個時間是完成一次程序的從頭到尾單片機內(nèi)部所需的時間,而運行一次只能輸出一種端口狀態(tài),那么需要方波輸出,則需要單片機運行兩次才能真正輸出一個方波信號,所以主頻才是升毀重中之重。

另外還有程序的整體步數(shù),就是程序的長度或多少,程序語句越多,運行速度也越慢,輸出的信號頻率也越低

  例神宴如想做一個1MHz的方波發(fā)生器,那么51單片機的更高主頻是12MHz,然而真正輸出的更高只能達到12分之一,那就是1MHz,勉勉強強算是可以

  如果超過1MHz的波形,51類單片機是達不到效果了,只能選擇其它單片機

下面是本人曾經(jīng)利用單吵瞎備片機做的PMW信號發(fā)生器程序,僅供參考

/***************************************************************************/

#include//頻率約為 2.37 KHz

//根據(jù)按鍵來控制輸出波形

it D=P2^0 ; //端口定義

int h,m,s,f;

/***************************************************************************/

void main(void)

{

TMOD=0x22; EA=1; ET0=1; ET1=1; TR0=1;//定時器初始化

while(1)

{

switch(P0)

{

case 0xfe : h=1; break;

case 0xfd : h=2; break;

case 0xfb : h=3; break;

case 0xf7 : h=4; break;

case 0xef : h=5; break;

case 0xdf : h=6; break;

case 0xbf : h=7; break;

case 0x7f : h=8; break;

default : h=9; break;

}

m=10-h;

}

}

/***************************************************************************/

void int0() interrupt 1 //定時器 0 中斷

{

TH0=0xff; s++;

if(s>=h){ TR0=0; TR1=1; D=0; s=0; }//開始時間

}

/***************************************************************************

/void int1() interrupt 3 //定時器 1 中斷

{

TH1=0xff; s++;

if(s>=m){ TR1=0; TR0=1; D=1; s=0; }//休止時間

}

/***************************************************************************/

基于單片機信號發(fā)生器設(shè)計

讓我來幫你 .

關(guān)于linux 方波輸出pmw的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。

成都網(wǎng)站建設(shè)選創(chuàng)新互聯(lián)(?:028-86922220),專業(yè)從事成都網(wǎng)站制作設(shè)計,高端小程序APP定制開發(fā),成都網(wǎng)絡(luò)營銷推廣等一站式服務(wù)。


新聞標(biāo)題:Linux實現(xiàn)方波輸出和PWM技術(shù)(linux方波輸出pmw)
當(dāng)前地址:http://www.dlmjj.cn/article/djdcpeg.html