找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 1391|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

STM8S單片機(jī)PWM總是調(diào)試不成功

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
最近在弄STM8S,依照網(wǎng)上的實(shí)驗(yàn)教程調(diào)試PWM程序,總是沒有輸出,有沒有人用過這個(gè)全程,好像是風(fēng)馳的教程
STM8C語(yǔ)言編程(14)-- PWM

在單片機(jī)應(yīng)用系統(tǒng)中,也常常會(huì)用到PWM信號(hào)輸出,例如電機(jī)轉(zhuǎn)速的控制,F(xiàn)在很多高檔的單片機(jī)也都集成了PWM功能模塊,方便用戶的應(yīng)用。
對(duì)于PWM信號(hào),主要涉及到兩個(gè)概念,一個(gè)就是PWM信號(hào)的周期或頻率,另一個(gè)就是PWM信號(hào)的占空比。例如一個(gè)頻率為1KHZ,占空比為30%,有效信號(hào)為1的PWM信號(hào),在用示波器測(cè)量時(shí),就是高電平的時(shí)間為300uS,低電平的時(shí)間為700uS的周期波形。
在單片機(jī)中實(shí)現(xiàn)PWM信號(hào)的功能模塊,實(shí)際上就是帶比較器的計(jì)數(shù)器模塊。首先該計(jì)數(shù)器循環(huán)計(jì)數(shù),例如從0到N,那么這個(gè)N就決定了PWM的周期,PWM周期=(N+1)*計(jì)數(shù)器時(shí)鐘的周期。在計(jì)數(shù)器模塊中一定還有一個(gè)比較器,比較器有2個(gè)輸入,一個(gè)就是計(jì)數(shù)器的當(dāng)前值,另一個(gè)是可以設(shè)置的數(shù),這個(gè)數(shù)來(lái)自一個(gè)比較寄存器。當(dāng)計(jì)數(shù)器的值小于比較寄存器的值時(shí),輸出為1(可以設(shè)置為0),當(dāng)計(jì)數(shù)器的值大于或等于比較寄存器的值時(shí),輸出為0(也可設(shè)置為1,與前面對(duì)應(yīng))。
了解了這個(gè)基本原理后,我們就可以使用STM8單片機(jī)中的PWM模塊了。下面的實(shí)驗(yàn)程序首先將定時(shí)器2的通道2設(shè)置成PWM輸出方式,然后通過設(shè)置自動(dòng)裝載寄存器TIM2_CCR2,決定PWM信號(hào)的周期。在程序的主循環(huán)中,循環(huán)修改占空比,先是從0逐漸遞增到128,然后再?gòu)?28遞減到0。
當(dāng)把下面的程序在ST的三合一板上運(yùn)行時(shí),可以看到發(fā)光二極管LD1逐漸變亮,然后又逐漸變暗,就這樣循環(huán)往復(fù)。如果用示波器看,可以看到驅(qū)動(dòng)LD1的信號(hào)波形的占空比從0變到50%,然后又從50%變到0。
同樣還是利用ST的開發(fā)工具,生成一個(gè)C語(yǔ)言程序的框架,然后修改其中的main.c,修改后的代碼如下。

//  程序描述:用PWM輸出驅(qū)動(dòng)LED

#include"STM8S207C_S.h"

voidCLK_Init(void);
voidTIM_Init(void);

// 函數(shù)功能:延時(shí)函數(shù)
// 輸入?yún)?shù):ms -- 要延時(shí)的毫秒數(shù),這里假設(shè)CPU的主頻為2MHZ
// 輸出參數(shù):無(wú)
// 返 回 值:無(wú)
// 備    注:無(wú)
voidDelayMS(unsigned int ms)
{
unsigned char i;
while(ms != 0)
  {
   for(i=0;i<250;i++)
   {
   }
   for(i=0;i<75;i++)
   {
   }
   ms--;  
}     
}

// 函數(shù)功能:初始化時(shí)鐘
// 輸入?yún)?shù):無(wú)
// 輸出參數(shù):無(wú)
// 返 回 值:無(wú)
// 備    注:無(wú)
voidCLK_Init()
{
CLK_CKDIVR = 0x11;          // 10:fHSI = fHSI RC output/ 4
                             //          = 16MHZ / 4 =4MHZ
                             // 001: fCPU=fMASTER/2. = 2MHZ
}

// 函數(shù)功能:初始化定時(shí)器2的通道2,用于控制LED的亮度
// 輸入?yún)?shù):無(wú)
// 輸出參數(shù):無(wú)
// 返 回 值:無(wú)
// 備    注:無(wú)
voidTIM_Init()
{
TIM2_CCMR2 = TIM2_CCMR2 | 0x70;// Output modePWM2.         
                                //通道2被設(shè)置成比較輸出方式
                                // OC2M = 111,為PWM模式2,
                                // 向上計(jì)數(shù)時(shí),若計(jì)數(shù)器小于比較值,為無(wú)效電平
                                // 即當(dāng)計(jì)數(shù)器在0到比較值時(shí),輸出為1,否則為0
TIM2_CCER1 = TIM2_CCER1 | 0x30;// CC polarity low,enable PWMoutput      */
                                // CC2P = 1,低電平為有效電平
                                // CC2E = 1,開啟輸出引腳               

//初始化自動(dòng)裝載寄存器,決定PWM方波的頻率,F(xiàn)pwm=4000000/256=15625HZ      
TIM2_ARRH = 0;
TIM2_ARRL = 0xFF;

//初始化比較寄存器,決定PWM方波的占空比            
TIM2_CCR2H = 0;
TIM2_CCR2L = 0;

// 初始化時(shí)鐘分頻器為1,即計(jì)數(shù)器的時(shí)鐘頻率為Fmaster=4MHZ
TIM2_PSCR = 0;
// 啟動(dòng)計(jì)數(shù)
TIM2_CR1 = TIM2_CR1 | 0x01;
}

main()
{
unsigned char i;

CLK_Init();                // 初始化時(shí)鐘
TIM_Init();                // 初始化定時(shí)器      

while(1)                   // 進(jìn)入無(wú)限循環(huán)
  {
   // 下面的循環(huán)將占空比逐漸從0遞增到50%
   for(i=0;i<128;i++)
   {
     TIM2_CCR2H = 0;
     TIM2_CCR2L = i;
     DelayMS(5);
   }

   // 下面的循環(huán)將占空比逐漸從50%遞減到0
   for(i=128;i>0;i--)
   {
     TIM2_CCR2H = 0;
     TIM2_CCR2L = i;
     DelayMS(5);
   }
}
}
//========================================
//上面這個(gè)實(shí)例老是調(diào)不通,不知道為什么??
//========================================
由于上面的例子總是調(diào)試不好,就換了個(gè)例子,但也是調(diào)不通,不知道是不是我哪里弄錯(cuò)了
在輸出模式下,該寄存器的值與 CNT 的值比較,根據(jù)比較結(jié)果產(chǎn)生相應(yīng)動(dòng)作。利用這點(diǎn),我們通過修改這個(gè)寄存器的值,就可以控制 PWM 的輸出脈寬了。
#include "iostm8s207rb.h"
void CLK_Init(void);
void TIM2_PWM2_Init(void);
void delay_ms(int value);
main()
{
unsigned char i;
CLK_Init(); // 初始化時(shí)鐘
TIM2_PWM2_Init(); // 初始化定時(shí)器的PWM功能
while(1) // 進(jìn)入無(wú)限循環(huán)
{
// 下面的循環(huán)將占空比逐漸從0遞增到50%
for(i=0;i<100;i++)
{
TIM2_CCR2H = 0;
TIM2_CCR2L = i;
delay_ms(10);
}
// 下面的循環(huán)將占空比逐漸從50%遞減到0
for(i=100;i>0;i--)
{
TIM2_CCR2H = 0;
TIM2_CCR2L = i;
delay_ms(10);
}
}
}
// 函數(shù)功能:初始化定時(shí)器2的通道2,用于控制LED的亮度
void TIM2_PWM2_Init()
{
TIM2_CCMR2 = TIM2_CCMR2 | 0x70;// Output mode PWM2.
// 通道2被設(shè)置成比較輸出方式
// OC2M = 111,為PWM模式2,
// 向上計(jì)數(shù)時(shí),若計(jì)數(shù)器小于比較值,為無(wú)效電平
// 即當(dāng)計(jì)數(shù)器在0到比較值時(shí),輸出為1,否則為0
TIM2_CCER1 = TIM2_CCER1 | 0x10;// CC polarity low,enable PWM output
// CC2P = 0,高電平為有效電平
// CC2E = 1,開啟輸出引腳
//初始化自動(dòng)裝載寄存器,決定PWM方波的頻率,F(xiàn)pwm=4000000/200=20KHZ
TIM2_ARRH = 0;
TIM2_ARRL = 0xC8; //200
//初始化比較寄存器,決定PWM方波的占空比
TIM2_CCR2H = 0;
TIM2_CCR2L = 0;
// 初始化時(shí)鐘分頻器為4,即計(jì)數(shù)器的時(shí)鐘頻率為Fmaster=16MHZ,CK_CNT = 4M
TIM2_PSCR = 2;
// 啟動(dòng)計(jì)數(shù)
TIM2_CR1 = TIM2_CR1 | 0x01;
}
void CLK_Init()
{
CLK_CKDIVR =0x00; //16M主頻
}
/*
********************************************
簡(jiǎn)單延時(shí)程序
********************************************
*/
void delay_ms(int value)
{
int i,j;
if(value < 1)
value = 1;
for(i=0;i!=value;++i)
for(j=0;j!=5000;++j);
}
//===================================
//上面這個(gè)例子也是沒有調(diào)好
//====================================
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:807361 發(fā)表于 2022-9-28 21:41 | 只看該作者
這兩個(gè)全程好像都是風(fēng)馳的,但是我手頭沒有風(fēng)馳的開發(fā)板可以下載來(lái)看效果,就用了另外一塊小開發(fā)板代替著用
回復(fù)

使用道具 舉報(bào)

板凳
ID:276663 發(fā)表于 2022-9-29 05:05 | 只看該作者
stm8的單片機(jī)需要修改“OPTION BYTES”
回復(fù)

使用道具 舉報(bào)

地板
ID:807361 發(fā)表于 2022-9-30 23:32 | 只看該作者
你好,修改什么地方,麻煩你說一下好嗎?
回復(fù)

使用道具 舉報(bào)

5#
ID:276663 發(fā)表于 2022-10-3 06:18 | 只看該作者
xieqinfu 發(fā)表于 2022-9-30 23:32
你好,修改什么地方,麻煩你說一下好嗎?

類似于其端口復(fù)用功能,需要修改option byte,你倒不如直接百度。

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表