【STC15库函数上手笔记】7、PCA与PWM
目錄
- 硬知識
- 硬件知識
- 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".
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ù)可以做如下組合:
如果后面使用了| 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)引腳
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
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)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用html制作个人简历(新手)
- 下一篇: 百度语言翻译机