日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【STC15库函数上手笔记】7、PCA与PWM

發(fā)布時間:2023/12/9 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【STC15库函数上手笔记】7、PCA与PWM 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

  • 硬知識
    • 硬件知識
      • CCP/PWM/PCA模塊的結(jié)構(gòu)
    • 軟件知識
      • PCA初始化函數(shù)
      • PWM更新占空比函數(shù)
  • 測試程序
    • PWM模式產(chǎn)生PWM信號
      • main.c
      • 實驗現(xiàn)象
    • 16位軟件定時器模式模式產(chǎn)生PWM信號
      • main.c
      • 實驗現(xiàn)象
    • 捕獲模式測量周期長度
      • main.c
      • 實驗現(xiàn)象

STC實驗箱4
IAP15W4K58S4
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0


硬知識

硬件知識

???????摘自《STC15系列單片機(jī)器件手冊
???????STC15系列部分單片機(jī)集成了3路可編程計數(shù)器陣列(CCP/PCA)模塊(STC15W4K32S4系列單片機(jī)只有兩路CCP/PCA),可用于軟件定時器、外部脈沖的捕捉、高速脈沖輸出以及脈寬調(diào)制(PWM)輸出。
???????下表總結(jié)了STC15系列單片機(jī)內(nèi)部集成了CCP/PCA/PM功能的單片機(jī)型號:

???????上表中√表示對應(yīng)的系列有相應(yīng)的功能。

CCP/PWM/PCA模塊的結(jié)構(gòu)

???????STC15系列部分單片機(jī)有3路可編程計數(shù)器陣列CCP/PCA/PWM(通過AUXR1/P_SW1寄存器可以設(shè)置CCP/PCA/PWM從P1口切換到P2口切換到P3口)。
???????PCA含有一個特殊的16位定時器,有3個16位的捕獲/比較模塊與之相連,如下圖所示。

???????每個模塊可編程工作在4種模式下:上升/下降沿捕獲、軟件定時器、高速脈沖輸出或可調(diào)制脈沖輸出。
???????16位PCA定時器/計數(shù)器是3個模塊的公共時間基準(zhǔn),其結(jié)構(gòu)如下圖所示。

軟件知識

???????摘自《STC庫函數(shù)使用參考

PCA初始化函數(shù)

PCA_Init

PCA_id:選擇要初始化的PCA通道:
PCA_InitTypeDef的定義見于文件"PCA.H".

typedef struct {u8 PCA_IoUse;u8 PCA_Clock; u8 PCA_Mode; u8 PCA_PWM_Wide;u8 PCA_Interrupt_Mode; u8 PCA_Polity;u16 PCA_Value; } PCA_InitTypeDef;

PCA_IoUse:選擇PCA使用的IO:初始化PCA_Counter時的取值,初始化PCA0~PCA2時忽略

PCA_Clock:選擇PCA使用的時鐘:初始化PCA_Counter時的取值,初始化PCA0~PCA2時忽略
PCA_Mode:設(shè)置PCA通道的工作模式:初始化PCA0~PCA2時的取值,初始化PCA_Counter時忽略

PCA_PWM_Wide:設(shè)置PCA通道工作于PWM模式時的PWM寬度:初始化PCA0~PCA2工作于PWM模式時的取值,初始化PCA_Counter時或PCA通道其它模式時忽略

PCA_Interrupt_Mode:中斷允許或禁止:初始化PCA0~PCA2時的取值,初始化PCA_Counter時忽略
注意:上面的參數(shù)可以做如下組合:

PCA_InitStructure.PCA_Interrupt_Mode = PCA_Fall_Active | ENABLE; //下降沿中斷,允許中斷。 PCA_InitStructure.PCA_Interrupt_Mode = PCA_Rise_Active | ENABLE; //上升沿中斷,允許中斷。 PCA_InitStructure.PCA_Interrupt_Mode = PCA_Rise_Active | PCA_Fall_Active | ENABLE; //上升沿、下降沿中斷,允許中斷。

如果后面使用了| DISABLE,則中斷被禁止。

PCA_Polity:中斷的優(yōu)先級:初始化PCA_Counter時的取值,初始化PCA0~PCA2時忽略
PCA_Value:設(shè)置PCA通道的初值。初始化PCA0~PCA2時的取值,初始化PCA_Counter時忽略

PWM更新占空比函數(shù)

UpdatePwm

測試程序

PWM模式產(chǎn)生PWM信號

PCA.c里的UpdatePwm函數(shù)默認(rèn)是被注釋掉的,需要解除注釋:

main.c

#include "./Drivers/config.h" #include "./Drivers/delay.h"#include "./Drivers/GPIO.h" #include "./Drivers/PCA.h"void GPIO_config(void) {GPIO_InitTypeDef GPIO_InitStructure; //結(jié)構(gòu)定義GPIO_InitStructure.Mode = GPIO_OUT_PP; //指定IO的輸入或輸出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_InitStructure.Pin = GPIO_Pin_5 | GPIO_Pin_6; //指定要初始化的IO, 或操作GPIO_Inilize(GPIO_P2, &GPIO_InitStructure); //P2.5、P2.6初始化為推挽輸出 }void PCA_config(void) {PCA_InitTypeDef PCA_InitStructure;PCA_InitStructure.PCA_Mode = PCA_Mode_PWM; //PCA_Mode_PWM, PCA_Mode_Capture, PCA_Mode_SoftTimer, PCA_Mode_HighPulseOutputPCA_InitStructure.PCA_PWM_Wide = PCA_PWM_8bit; //PCA_PWM_8bit, PCA_PWM_7bit, PCA_PWM_6bitPCA_InitStructure.PCA_Interrupt_Mode = DISABLE; //PCA_Rise_Active, PCA_Fall_Active, ENABLE, DISABLEPCA_InitStructure.PCA_Value = (u16)((1 << 8) * (1 - 0.5));//對于軟件定時, 為匹配比較值PCA_Init(PCA0,&PCA_InitStructure);PCA_InitStructure.PCA_Mode = PCA_Mode_PWM; //PCA_Mode_PWM, PCA_Mode_Capture, PCA_Mode_SoftTimer, PCA_Mode_HighPulseOutputPCA_InitStructure.PCA_PWM_Wide = PCA_PWM_7bit; //PCA_PWM_8bit, PCA_PWM_7bit, PCA_PWM_6bitPCA_InitStructure.PCA_Interrupt_Mode = DISABLE; //PCA_Rise_Active, PCA_Fall_Active, ENABLE, DISABLEPCA_InitStructure.PCA_Value = (u16)((1 << 7) * (1 - 0.5));//對于軟件定時, 為匹配比較值PCA_Init(PCA1,&PCA_InitStructure);PCA_InitStructure.PCA_Clock = PCA_Clock_1T; //PCA_Clock_1T, PCA_Clock_2T, PCA_Clock_4T, PCA_Clock_6T, PCA_Clock_8T, PCA_Clock_12T, PCA_Clock_Timer0_OF, PCA_Clock_ECIPCA_InitStructure.PCA_IoUse = PCA_P24_P25_P26_P27;//PCA_P12_P11_P10_P37, PCA_P34_P35_P36_P37, PCA_P24_P25_P26_P27PCA_InitStructure.PCA_Interrupt_Mode = DISABLE; //ENABLE, DISABLEPCA_InitStructure.PCA_Polity = PolityHigh; //優(yōu)先級設(shè)置 PolityHigh,PolityLowPCA_Init(PCA_Counter,&PCA_InitStructure); }void main(void) {GPIO_config();PCA_config();UpdatePwm(PCA0, (1 << 8) * (1 - 0.75));UpdatePwm(PCA1, (1 << 7) * (1 - 0.25));while(1){} }

實驗現(xiàn)象

PWM頻率 = PCA時鐘頻率 / 2PWM位數(shù)2^{PWM位數(shù)}2PWM數(shù)

30MHz/1/28=117187.5Hz30MHz / 1 / 2^8 = 117187.5 Hz30MHz/1/28=117187.5Hz

30MHz/1/27=234375Hz30MHz / 1 / 2^7 = 234375 Hz30MHz/1/27=234375Hz

16位軟件定時器模式模式產(chǎn)生PWM信號

PWM頻率 = PCA時鐘頻率 / PWMx_DUTY

修改PCA.h中的PWMx_DUTY

修改PCA_Handler內(nèi)的對應(yīng)引腳

//======================================================================== // 函數(shù): void PCA_Handler (void) interrupt PCA_VECTOR // 描述: PCA中斷處理程序. // 參數(shù): None // 返回: none. // 版本: V1.0, 2012-11-22 //======================================================================== void PCA_Handler (void) interrupt PCA_VECTOR {if(CCF0) //PCA模塊0中斷{CCF0 = 0; //清PCA模塊0中斷標(biāo)志if(P25) CCAP0_tmp += PCA_Timer0; //輸出為高電平,則給影射寄存器裝載高電平時間長度else CCAP0_tmp += PWM0_low; //輸出為低電平,則給影射寄存器裝載低電平時間長度CCAP0L = (u8)CCAP0_tmp; //將影射寄存器寫入捕獲寄存器,先寫CCAP0LCCAP0H = (u8)(CCAP0_tmp >> 8); //后寫CCAP0H}if(CCF1) //PCA模塊1中斷{CCF1 = 0; //清PCA模塊1中斷標(biāo)志if(P26) CCAP1_tmp += PCA_Timer1; //輸出為高電平,則給影射寄存器裝載高電平時間長度else CCAP1_tmp += PWM1_low; //輸出為低電平,則給影射寄存器裝載低電平時間長度CCAP1L = (u8)CCAP1_tmp; //將影射寄存器寫入捕獲寄存器,先寫CCAP0LCCAP1H = (u8)(CCAP1_tmp >> 8); //后寫CCAP0H}if(CCF2) //PCA模塊2中斷{CCF2 = 0; //清PCA模塊1中斷標(biāo)志if(P27) CCAP2_tmp += PCA_Timer2; //輸出為高電平,則給影射寄存器裝載高電平時間長度else CCAP2_tmp += PWM2_low; //輸出為低電平,則給影射寄存器裝載低電平時間長度CCAP2L = (u8)CCAP2_tmp; //將影射寄存器寫入捕獲寄存器,先寫CCAP0LCCAP2H = (u8)(CCAP2_tmp >> 8); //后寫CCAP0H}if(CF) //PCA溢出中斷{CF = 0; //清PCA溢出中斷標(biāo)志}}

main.c

#include "./Drivers/config.h" #include "./Drivers/delay.h"#include "./Drivers/GPIO.h" #include "./Drivers/PCA.h"void GPIO_config(void) {GPIO_InitTypeDef GPIO_InitStructure; //結(jié)構(gòu)定義GPIO_InitStructure.Mode = GPIO_OUT_PP; //指定IO的輸入或輸出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_InitStructure.Pin = GPIO_Pin_5 | GPIO_Pin_6; //指定要初始化的IO, 或操作GPIO_Inilize(GPIO_P2, &GPIO_InitStructure); //P2.5、P2.6初始化為推挽輸出 }void PCA_config(void) {PCA_InitTypeDef PCA_InitStructure;PCA_InitStructure.PCA_Mode = PCA_Mode_HighPulseOutput; //PCA_Mode_PWM, PCA_Mode_Capture, PCA_Mode_SoftTimer, PCA_Mode_HighPulseOutputPCA_InitStructure.PCA_PWM_Wide = 0; //PCA_PWM_8bit, PCA_PWM_7bit, PCA_PWM_6bitPCA_InitStructure.PCA_Interrupt_Mode = ENABLE; //PCA_Rise_Active, PCA_Fall_Active, ENABLE, DISABLEPCA_InitStructure.PCA_Value = 65535; //對于軟件定時, 為匹配比較值PCA_Init(PCA0,&PCA_InitStructure);PCA_InitStructure.PCA_Mode = PCA_Mode_HighPulseOutput; //PCA_Mode_PWM, PCA_Mode_Capture, PCA_Mode_SoftTimer, PCA_Mode_HighPulseOutputPCA_InitStructure.PCA_PWM_Wide = 0; //PCA_PWM_8bit, PCA_PWM_7bit, PCA_PWM_6bitPCA_InitStructure.PCA_Interrupt_Mode = ENABLE; //PCA_Rise_Active, PCA_Fall_Active, ENABLE, DISABLEPCA_InitStructure.PCA_Value = 65535; //對于軟件定時, 為匹配比較值PCA_Init(PCA1,&PCA_InitStructure);PCA_InitStructure.PCA_Clock = PCA_Clock_12T; //PCA_Clock_1T, PCA_Clock_2T, PCA_Clock_4T, PCA_Clock_6T, PCA_Clock_8T, PCA_Clock_12T, PCA_Clock_Timer0_OF, PCA_Clock_ECIPCA_InitStructure.PCA_IoUse = PCA_P24_P25_P26_P27; //PCA_P12_P11_P10_P37, PCA_P34_P35_P36_P37, PCA_P24_P25_P26_P27PCA_InitStructure.PCA_Interrupt_Mode = DISABLE; //ENABLE, DISABLEPCA_InitStructure.PCA_Polity = PolityHigh; //優(yōu)先級設(shè)置 PolityHigh,PolityLowPCA_Init(PCA_Counter, &PCA_InitStructure); }void main(void) {GPIO_config();PCA_config();PWMn_Update(PCA0, (u16)(PWM0_DUTY * 0.75));PWMn_Update(PCA1, (u16)(PWM1_DUTY * 0.25));EA = 1;while(1){} }

實驗現(xiàn)象

30MHz/12/50000=50Hz30MHz / 12 / 50000 = 50 Hz30MHz/12/50000=50Hz

捕獲模式測量周期長度

修改PCA.c內(nèi)的PCA_Handler

//======================================================================== // 函數(shù): void PCA_Handler (void) interrupt PCA_VECTOR // 描述: PCA中斷處理程序. // 參數(shù): None // 返回: none. // 版本: V1.0, 2012-11-22 //======================================================================== void PCA_Handler (void) interrupt PCA_VECTOR {if(CCF0) //PCA模塊0中斷{CCF0 = 0; //清PCA模塊0中斷標(biāo)志if(P25) CCAP0_tmp += PCA_Timer0; //輸出為高電平,則給影射寄存器裝載高電平時間長度else CCAP0_tmp += PWM0_low; //輸出為低電平,則給影射寄存器裝載低電平時間長度CCAP0L = (u8)CCAP0_tmp; //將影射寄存器寫入捕獲寄存器,先寫CCAP0LCCAP0H = (u8)(CCAP0_tmp >> 8); //后寫CCAP0H}if(CCF1) //PCA模塊1中斷{CCF1 = 0; //清PCA模塊1中斷標(biāo)志if(PCA1_mode >= PCA_Mode_SoftTimer) //PCA_Mode_SoftTimer and PCA_Mode_HighPulseOutput{CCAP1_tmp += PCA_Timer1;CCAP1L = (u8)CCAP1_tmp; //將影射寄存器寫入捕獲寄存器,先寫CCAP0LCCAP1H = (u8)(CCAP1_tmp >> 8); //后寫CCAP0H}else if(PCA1_mode == PCA_Mode_Capture){CCAP1_tmp = CCAP1H; //讀CCAP1HCCAP1_tmp = (CCAP1_tmp << 8) + CCAP1L;B_Capture1 = 1;}}if(CCF2) //PCA模塊2中斷{CCF2 = 0; //清PCA模塊1中斷標(biāo)志if(P27) CCAP2_tmp += PCA_Timer2; //輸出為高電平,則給影射寄存器裝載高電平時間長度else CCAP2_tmp += PWM2_low; //輸出為低電平,則給影射寄存器裝載低電平時間長度CCAP2L = (u8)CCAP2_tmp; //將影射寄存器寫入捕獲寄存器,先寫CCAP0LCCAP2H = (u8)(CCAP2_tmp >> 8); //后寫CCAP0H}if(CF) //PCA溢出中斷{CF = 0; //清PCA溢出中斷標(biāo)志}}

main.c

#include "./Drivers/config.h" #include "./Drivers/delay.h"#include "./Drivers/GPIO.h" #include "./Drivers/PCA.h"#include "./Drivers/soft_UART.h" #include <stdio.h>char putchar(char Char) {TxSend(Char);return Char; }void GPIO_config(void) {GPIO_InitTypeDef GPIO_InitStructure; //結(jié)構(gòu)定義GPIO_InitStructure.Mode = GPIO_OUT_PP; //指定IO的輸入或輸出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_InitStructure.Pin = GPIO_Pin_5; //指定要初始化的IO, 或操作GPIO_Inilize(GPIO_P2, &GPIO_InitStructure); //P2.5初始化為推挽輸出 }void PCA_config(void) {PCA_InitTypeDef PCA_InitStructure;PCA_InitStructure.PCA_Mode = PCA_Mode_HighPulseOutput; //PCA_Mode_PWM, PCA_Mode_Capture, PCA_Mode_SoftTimer, PCA_Mode_HighPulseOutputPCA_InitStructure.PCA_PWM_Wide = 0; //PCA_PWM_8bit, PCA_PWM_7bit, PCA_PWM_6bitPCA_InitStructure.PCA_Interrupt_Mode = ENABLE; //PCA_Rise_Active, PCA_Fall_Active, ENABLE, DISABLEPCA_InitStructure.PCA_Value = 65535; //對于軟件定時, 為匹配比較值PCA_Init(PCA0,&PCA_InitStructure);PCA_InitStructure.PCA_Mode = PCA_Mode_Capture; //PCA_Mode_PWM, PCA_Mode_Capture, PCA_Mode_SoftTimer, PCA_Mode_HighPulseOutputPCA_InitStructure.PCA_PWM_Wide = 0; //PCA_PWM_8bit, PCA_PWM_7bit, PCA_PWM_6bitPCA_InitStructure.PCA_Interrupt_Mode = PCA_Fall_Active | ENABLE; //(PCA_Rise_Active, PCA_Fall_Active) or (ENABLE, DISABLE)PCA_InitStructure.PCA_Value = 0; //對于捕捉, 這個值沒意義PCA_Init(PCA1,&PCA_InitStructure);PCA_InitStructure.PCA_Clock = PCA_Clock_12T; //PCA_Clock_1T, PCA_Clock_2T, PCA_Clock_4T, PCA_Clock_6T, PCA_Clock_8T, PCA_Clock_12T, PCA_Clock_Timer0_OF, PCA_Clock_ECIPCA_InitStructure.PCA_IoUse = PCA_P24_P25_P26_P27; //PCA_P12_P11_P10_P37, PCA_P34_P35_P36_P37, PCA_P24_P25_P26_P27PCA_InitStructure.PCA_Interrupt_Mode = DISABLE; //ENABLE, DISABLEPCA_InitStructure.PCA_Polity = PolityHigh; //優(yōu)先級設(shè)置 PolityHigh,PolityLowPCA_Init(PCA_Counter, &PCA_InitStructure); }u16 Cap_time; //上一次捕捉時間void main(void) {u16 j;Cap_time = 0;GPIO_config();PCA_config();PWMn_Update(PCA0, (u16)(PWM0_DUTY * 0.75));EA = 1;while(1){if(B_Capture1){B_Capture1 = 0;j = CCAP1_tmp - Cap_time; //計算時間差Cap_time = CCAP1_tmp;printf("%d us\r\n", (int)(j * 12. / 30));}delay_ms(1);} }

實驗現(xiàn)象

總結(jié)

以上是生活随笔為你收集整理的【STC15库函数上手笔记】7、PCA与PWM的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。