feat: pca pwm demos

This commit is contained in:
IOsetting 2022-01-01 17:43:23 +08:00
parent 1d8482ccb9
commit bfdf8f1213
3 changed files with 185 additions and 14 deletions

View File

@ -0,0 +1,71 @@
// Copyright 2021 IOsetting <iosetting(at)outlook.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "fw_hal.h"
__BIT dir = SET;
uint16_t dc = 0;
void main(void)
{
SYS_SetClock();
// UART1, baud 115200, baud source Timer1, 1T mode, no interrupt
UART1_ConfigMode1Dyn8bitUart(UART1_BaudSource_Timer1, HAL_State_ON, 115200);
// Set GPIO pin mode
GPIO_P3_SetMode(GPIO_Pin_2|GPIO_Pin_3, GPIO_Mode_Output_PP);
// Stop PCA/PWM
PCA_SetCounterState(HAL_State_OFF);
// Stop counter in idle mode
PCA_SetStopCounterInIdle(HAL_State_ON);
// Use SYSCLK as clock source
PCA_SetClockSource(PCA_ClockSource_SysClkDiv12);
// Turn off overflow interrupt
PCA_EnableCounterOverflowInterrupt(HAL_State_OFF);
// Set PCA0 and PCA1 to PWM mode
PCA_PCA0_SetWorkMode(PCA_WorkMode_PWM_NonInterrupt);
PCA_PCA1_SetWorkMode(PCA_WorkMode_PWM_NonInterrupt);
// Set both to 8-bit PWM
PCA_PWM0_SetBitWidth(PCA_PWM_BitWidth_10);
PCA_PWM1_SetBitWidth(PCA_PWM_BitWidth_10);
// Set initial duty cycle
PCA_PCA0_SetCompareValue10bit(dc);
PCA_PCA1_SetCompareValue10bit(~dc & 0x3FF);
// Set output port for STC8G1K08A, PWM0:P32, PWM1:P33
PCA_SetPort(PCA_AlterPort_G1K08A_P55_P32_P33_P54);
// Start PWM
PCA_SetCounterState(HAL_State_ON);
while(1)
{
PCA_PCA0_ChangeCompareValue10bit(dc);
PCA_PCA1_ChangeCompareValue10bit(~dc & 0x3FF);
UART1_TxHex(dc >> 8);
UART1_TxHex(dc & 0xFF);
if (dir)
{
dc++;
if (dc == 0x03FF) dir = !dir;
}
else
{
dc--;
if (dc == 0) dir = !dir;
}
UART1_TxString("\r\n");
SYS_Delay(10);
}
}

View File

@ -0,0 +1,72 @@
// Copyright 2021 IOsetting <iosetting(at)outlook.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "fw_hal.h"
__BIT dir = SET;
uint8_t dc = 0;
void main(void)
{
SYS_SetClock();
// UART1, baud 115200, baud source Timer1, 1T mode, no interrupt
UART1_ConfigMode1Dyn8bitUart(UART1_BaudSource_Timer1, HAL_State_ON, 115200);
// Set GPIO pin mode
GPIO_P3_SetMode(GPIO_Pin_2|GPIO_Pin_3, GPIO_Mode_Output_PP);
// Stop PCA/PWM
PCA_SetCounterState(HAL_State_OFF);
// Stop counter in idle mode
PCA_SetStopCounterInIdle(HAL_State_ON);
// Use SYSCLK as clock source
PCA_SetClockSource(PCA_ClockSource_SysClk);
// Turn off overflow interrupt
PCA_EnableCounterOverflowInterrupt(HAL_State_OFF);
// Set PCA0 and PCA1 to PWM mode
PCA_PCA0_SetWorkMode(PCA_WorkMode_PWM_NonInterrupt);
PCA_PCA1_SetWorkMode(PCA_WorkMode_PWM_NonInterrupt);
// Set both to 8-bit PWM
PCA_PWM0_SetBitWidth(PCA_PWM_BitWidth_8);
PCA_PWM1_SetBitWidth(PCA_PWM_BitWidth_8);
// Set initial duty cycle
PCA_PCA0_SetCompareValue(dc);
PCA_PCA1_SetCompareValue(~dc);
// Set output port for STC8G1K08A, PWM0:P32, PWM1:P33
PCA_SetPort(PCA_AlterPort_G1K08A_P55_P32_P33_P54);
// Start PWM
PCA_SetCounterState(HAL_State_ON);
while(1)
{
PCA_PCA0_ChangeCompareValue(dc);
PCA_PCA1_ChangeCompareValue(~dc);
UART1_TxHex(dc);
UART1_TxChar(' ');
UART1_TxHex(~dc);
if (dir)
{
dc++;
if (dc == 0xFF) dir = !dir;
}
else
{
dc--;
if (dc == 0) dir = !dir;
}
UART1_TxString("\r\n");
SYS_Delay(10);
}
}

View File

@ -54,7 +54,7 @@ typedef enum
typedef enum
{
// ECI CCP0 CCP1 CCP2
// ECI CCP0 CCP1 CCP2
PCA_AlterPort_P12_P11_P10_P37 = 0x00,
PCA_AlterPort_P34_P35_P36_P37 = 0x01,
PCA_AlterPort_P24_P25_P26_P27 = 0x10,
@ -62,7 +62,7 @@ typedef enum
typedef enum
{
// ECI CCP0 CCP1 CCP2
// ECI CCP0 CCP1 CCP2
PCA_AlterPort_G1K08A_P55_P32_P33_P54 = 0x00,
PCA_AlterPort_G1K08A_P55_P31_P33_P54 = 0x01,
PCA_AlterPort_G1K08A_P31_P32_P33_P55 = 0x10,
@ -70,7 +70,7 @@ typedef enum
typedef enum
{
// ECI CCP0 CCP1 CCP2
// ECI CCP0 CCP1 CCP2
PCA_AlterPort_G1K08T_P13_P11_P10_P37 = 0x00,
PCA_AlterPort_G1K08T_P34_P35_P36_P37 = 0x01,
PCA_AlterPort_G1K08T_P54_P13_P14_P15 = 0x10,
@ -87,30 +87,58 @@ typedef enum
#define PCA_SetClockSource(__SOURCE___) (CMOD = CMOD & ~(0x07 << 1) | ((__SOURCE___) << 1))
#define PCA_EnableCounterOverflowInterrupt(__STATE__) SFR_ASSIGN(CMOD, 0, __STATE__)
#define PCA_PCA0_SetMode(__MODE__) (CCAPM0 = (__MODE__))
#define PCA_PCA1_SetMode(__MODE__) (CCAPM1 = (__MODE__))
#define PCA_PCA2_SetMode(__MODE__) (CCAPM2 = (__MODE__))
#define PCA_PCA0_SetWorkMode(__MODE__) (CCAPM0 = (__MODE__))
#define PCA_PCA1_SetWorkMode(__MODE__) (CCAPM1 = (__MODE__))
#define PCA_PCA2_SetWorkMode(__MODE__) (CCAPM2 = (__MODE__))
#define PCA_PWM0_SetBitWidth(__BIT_WIDTH__) (PCA_PWM0 = PCA_PWM0 & ~(0x03 << 6) | ((__BIT_WIDTH__) << 6))
#define PCA_PWM1_SetBitWidth(__BIT_WIDTH__) (PCA_PWM1 = PCA_PWM1 & ~(0x03 << 6) | ((__BIT_WIDTH__) << 6))
#define PCA_PWM2_SetBitWidth(__BIT_WIDTH__) (PCA_PWM2 = PCA_PWM2 & ~(0x03 << 6) | ((__BIT_WIDTH__) << 6))
/**
* Set initiale comparison value
*/
#define PCA_PCA0_SetCompareValue(__VALUE__) do{CCAP0H = (__VALUE__); CCAP0L = (__VALUE__);}while(0)
#define PCA_PCA1_SetCompareValue(__VALUE__) do{CCAP1H = (__VALUE__); CCAP1L = (__VALUE__);}while(0)
#define PCA_PCA2_SetCompareValue(__VALUE__) do{CCAP2H = (__VALUE__); CCAP2L = (__VALUE__);}while(0)
/**
* Change comparison value when running
*/
#define PCA_PCA0_ChangeCompareValue(__VALUE__) (CCAP0H = (__VALUE__))
#define PCA_PCA1_ChangeCompareValue(__VALUE__) (CCAP1H = (__VALUE__))
#define PCA_PCA2_ChangeCompareValue(__VALUE__) (CCAP2H = (__VALUE__))
// TODO: set high 8-bit should be enough
#define PCA_PCA0_SetCompareValue(__VALUE__) do{CCAP0H = (__VALUE__); CCAP0L = (__VALUE__);}while(0)
#define PCA_PCA1_SetCompareValue(__VALUE__) do{CCAP1H = (__VALUE__); CCAP1L = (__VALUE__);}while(0)
#define PCA_PCA2_SetCompareValue(__VALUE__) do{CCAP2H = (__VALUE__); CCAP2L = (__VALUE__);}while(0)
// TODO: set high 8-bit should be enough
/**
* Set initiale comparison value
*/
#define PCA_PCA0_SetCompareValue10bit(__VALUE__) do{ \
CCAP0H = ((__VALUE__) & 0xFF); CCAP0L = ((__VALUE__) & 0xFF); \
PCA_PWM0 = PCA_PWM0 & ~(0x0F << 2) | (((__VALUE__) >> 4) & 0x30) | (((__VALUE__) >> 6) & 0x0C); \
CCAP0H = ((__VALUE__) & 0xFF); CCAP0L = ((__VALUE__) & 0xFF); \
}while(0)
#define PCA_PCA1_SetCompareValue10bit(__VALUE__) do{ \
CCAP1H = ((__VALUE__) & 0xFF); CCAP1L = ((__VALUE__) & 0xFF); \
PCA_PWM1 = PCA_PWM1 & ~(0x0F << 2) | (((__VALUE__) >> 4) & 0x30) | (((__VALUE__) >> 6) & 0x0C); \
CCAP1H = ((__VALUE__) & 0xFF); CCAP1L = ((__VALUE__) & 0xFF); \
}while(0)
#define PCA_PCA2_SetCompareValue10bit(__VALUE__) do{ \
CCAP2H = ((__VALUE__) & 0xFF); CCAP2L = ((__VALUE__) & 0xFF); \
PCA_PWM2 = PCA_PWM2 & ~(0x0F << 2) | (((__VALUE__) >> 4) & 0x30) | (((__VALUE__) >> 6) & 0x0C); \
CCAP2H = ((__VALUE__) & 0xFF); CCAP2L = ((__VALUE__) & 0xFF); \
}while(0)
/**
* Change comparison value in running mode
* Note: set high 2bit first, then low 8bit, the hardware will make sure new 10bit be loaded as a whole number.
* If you write low bits first, it will introduce glitchnoise.
*/
#define PCA_PCA0_ChangeCompareValue10bit(__VALUE__) do{ \
PCA_PWM0 = PCA_PWM0 & ~(0x03 << 4) | (((__VALUE__) >> 4) & 0x30); \
CCAP0H = ((__VALUE__) & 0xFF); \
}while(0)
#define PCA_PCA1_ChangeCompareValue10bit(__VALUE__) do{ \
PCA_PWM1 = PCA_PWM1 & ~(0x03 << 4) | (((__VALUE__) >> 4) & 0x30); \
CCAP1H = ((__VALUE__) & 0xFF); \
}while(0)
#define PCA_PCA2_ChangeCompareValue10bit(__VALUE__) do{ \
PCA_PWM2 = PCA_PWM2 & ~(0x03 << 4) | (((__VALUE__) >> 4) & 0x30); \
CCAP2H = ((__VALUE__) & 0xFF); \
}while(0)
/**