基于STC8G試驗箱 PWM程序修改的 舵機控制程序,現在情況是 舵機沒有反應,想請老師們看看程序有沒有問題。
/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC 1T Series MCU Demo Programme -------------------------------*/
/* 如果要在程序中使用此代碼,請在程序中注明使用了STC的資料及程序 */
/*---------------------------------------------------------------------*/
#include "config.h"
#include "timer.h"
#include "GPIO.h"
#include "PWM.h"
/************* 功能說明 **************
本例程基于STC8H8K64U為主控芯片的實驗箱8進行編寫測試,STC8H系列芯片可通用參考.
高級PWM定時器 PWM1P/PWM1N,PWM2P/PWM2N,PWM3P/PWM3N,PWM4P/PWM4N 每個通道都可獨立實現PWM輸出,或者兩兩互補對稱輸出.
8個通道PWM設置對應P6的8個端口.
通過P6口上連接的8個LED燈,利用PWM實現呼吸燈效果.
PWM周期和占空比可以根據需要自行設置,最高可達65535.
下載時, 選擇時鐘 24MHZ (用戶可在"config.h"修改頻率).
******************************************/
/************* 本地常量聲明 **************/
/************* 本地變量聲明 **************/
PWMx_Duty PWMA_Duty;
/************* 本地函數聲明 **************/
int dutyCycle;
/************* 外部函數和變量聲明 *****************/
// 簡單的延時函數
void delayMs(int ms) {
int i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 120; j++); // 調整內部循環計數以獲得所需的延時
}
/************************ IO口配置 ****************************/
void GPIO_config(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //結構定義
GPIO_InitStructure.Pin = GPIO_Pin_0; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7, 或操作
GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的輸入或輸出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P4,&GPIO_InitStructure); //初始化
GPIO_InitStructure.Pin = GPIO_Pin_All; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7, 或操作
GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的輸入或輸出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P1,&GPIO_InitStructure); //初始化
}
/************************ 定時器配置 ****************************/
void Timer_config(void)
{
TIM_InitTypeDef TIM_InitStructure; //結構定義
TIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; //指定工作模式, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask
TIM_InitStructure.TIM_Priority = Priority_0; //指定中斷優先級(低到高) Priority_0,Priority_1,Priority_2,Priority_3
TIM_InitStructure.TIM_Interrupt = ENABLE; //中斷是否允許, ENABLE或DISABLE
TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T; //指定時鐘源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
TIM_InitStructure.TIM_ClkOut = DISABLE; //是否輸出高速脈沖, ENABLE或DISABLE
TIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / 1000); //中斷頻率, 1000次/秒
TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后啟動定時器, ENABLE或DISABLE
Timer_Inilize(Timer0,&TIM_InitStructure); //初始化Timer0 Timer0,Timer1,Timer2,Timer3,Timer4
}
/*************** 串口初始化函數 *****************/
void PWM_config(void)
{
PWMx_InitDefine PWMx_InitStructure;
PWMx_InitStructure.PWM1_Mode = CCMRn_PWM_MODE1; //模式, CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
// PWMx_InitStructure.PWM2_Mode = CCMRn_PWM_MODE1; //模式, CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
// PWMx_InitStructure.PWM3_Mode = CCMRn_PWM_MODE1; //模式, CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
// PWMx_InitStructure.PWM4_Mode = CCMRn_PWM_MODE1; //模式, CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
PWMx_InitStructure.PWM1_SetPriority = Priority_0; //指定中斷優先級(低到高) Priority_0,Priority_1,Priority_2,Priority_3
// PWMx_InitStructure.PWM2_SetPriority = Priority_0; //指定中斷優先級(低到高) Priority_0,Priority_1,Priority_2,Priority_3
// PWMx_InitStructure.PWM3_SetPriority = Priority_0; //指定中斷優先級(低到高) Priority_0,Priority_1,Priority_2,Priority_3
// PWMx_InitStructure.PWM4_SetPriority = Priority_0; //指定中斷優先級(低到高) Priority_0,Priority_1,Priority_2,Priority_3
PWMx_InitStructure.PWM_Period = 20000 - 1; // 20ms周期對應50hz頻率
PWMx_InitStructure.PWM1_Duty = 1500; //1.5ms為中位位置
// PWMx_InitStructure.PWM2_Duty = PWMA_Duty.PWM2_Duty; //PWM2占空比時間, 0~Period
// PWMx_InitStructure.PWM3_Duty = PWMA_Duty.PWM3_Duty; //PWM3占空比時間, 0~Period
// PWMx_InitStructure.PWM4_Duty = PWMA_Duty.PWM4_Duty; //PWM4占空比時間, 0~Period
// PWMx_InitStructure.PWM_DeadTime = 0; //死區發生器設置, 0~255
PWMx_InitStructure.PWM_EnoSelect = ENO1P ; //輸出通道選擇, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
PWMx_InitStructure.PWM_PS_SW = PWM1_SW_P10_P11; //切換端口, PWM1_SW_P10_P11,PWM1_SW_P20_P21,PWM1_SW_P60_P61
// PWM2_SW_P12_P13,PWM2_SW_P22_P23,PWM2_SW_P62_P63
// PWM3_SW_P14_P15,PWM3_SW_P24_P25,PWM3_SW_P64_P65
// PWM4_SW_P16_P17,PWM4_SW_P26_P27,PWM4_SW_P66_P67,PWM4_SW_P34_P33
PWMx_InitStructure.PWM_CC1Enable = ENABLE; //開啟PWM1P輸入捕獲/比較輸出, ENABLE,DISABLE
// PWMx_InitStructure.PWM_CC1NEnable = ENABLE; //開啟PWM1N輸入捕獲/比較輸出, ENABLE,DISABLE
// PWMx_InitStructure.PWM_CC2Enable = ENABLE; //開啟PWM2P輸入捕獲/比較輸出, ENABLE,DISABLE
// PWMx_InitStructure.PWM_CC2NEnable = ENABLE; //開啟PWM2N輸入捕獲/比較輸出, ENABLE,DISABLE
// PWMx_InitStructure.PWM_CC3Enable = ENABLE; //開啟PWM3P輸入捕獲/比較輸出, ENABLE,DISABLE
// PWMx_InitStructure.PWM_CC3NEnable = ENABLE; //開啟PWM3N輸入捕獲/比較輸出, ENABLE,DISABLE
// PWMx_InitStructure.PWM_CC4Enable = ENABLE; //開啟PWM4P輸入捕獲/比較輸出, ENABLE,DISABLE
// PWMx_InitStructure.PWM_CC4NEnable = ENABLE; //開啟PWM4N輸入捕獲/比較輸出, ENABLE,DISABLE
PWMx_InitStructure.PWM_MainOutEnable= ENABLE; //主輸出使能, ENABLE,DISABLE
PWMx_InitStructure.PWM_CEN_Enable = ENABLE; //使能計數器, ENABLE,DISABLE
PWM_Configuration(PWMA, &PWMx_InitStructure); //初始化PWM, PWMA,PWMB
}
void setServoAngle(int angle) {
// 檢查角度是否在有效范圍內,防止錯誤輸入導致不正確操作
if (angle < 0) angle = 0;
if (angle > 180) angle = 180;
// 將角度(0-180度)轉換為對應的PWM占空比值
// 假設0度對應500μs(占空比2.5%),180度對應2500μs(占空比12.5%)
dutyCycle = 500 + ((angle * 2000) / 180);
PWMA_Duty.PWM1_Duty = dutyCycle;
UpdatePwm(PWMA, &PWMA_Duty);
}
/******************** 主函數**************************/
void main(void)
{
GPIO_config();
Timer_config();
PWM_config();
EA = 1;
P10 = 0; //打開LED電源
setServoAngle(0);
while (1)
{
setServoAngle(0); // Move servo to 0 degrees
delayMs(5000); // Delay to observe position
setServoAngle(90); // Move servo to 90 degrees (center)
delayMs(5000); // Delay to observe position
// setServoAngle(180); // Move servo to 180 degrees
// delayMs(5000); // Delay to observe position
}
}
|