/********************************** (C) COPYRIGHT *******************************
* File Name : main.c
* Author : WCH
* Version : V1.0.0
* Date : 2024/08/23
* Description : CH32V003 Device Peripheral Access Layer System Header File.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
/*
*DDS
*Timer 1 als Timer-Interrupt und PWM an D2
*Timer2 für PWM-Ausgabe an D3
Vorteil: Getrennte Frequenzen m?glich
Rechteck an D4
*/
#include "debug.h"
#include "math.h"
u32 freq, akk, phase;
//u16 n;
const uint8_t sin_table[256] =
{128, 131, 134, 137, 140, 143, 146, 149, 152, 156, 159, 162, 165, 168, 171, 173,
176, 179, 182, 185, 188, 190, 193, 196, 199, 201, 204, 206, 209, 211, 213, 216,
218, 220, 222, 224, 226, 228, 230, 232, 234, 235, 237, 239, 240, 242, 243, 244,
246, 247, 248, 249, 250, 251, 251, 252, 253, 253, 254, 254, 255, 255, 255, 255,
255, 255, 255, 255, 255, 254, 254, 253, 253, 252, 251, 251, 250, 249, 248, 247,
246, 244, 243, 242, 240, 239, 237, 235, 234, 232, 230, 228, 226, 224, 222, 220,
218, 216, 213, 211, 209, 206, 204, 201, 199, 196, 193, 191, 188, 185, 182, 179,
176, 174, 171, 168, 165, 162, 159, 156, 152, 149, 146, 143, 140, 137, 134, 131,
128, 124, 121, 118, 115, 112, 109, 106, 103, 100, 96, 93, 90, 87, 84, 82, 79,
76, 73, 70, 67, 65, 62, 59, 57, 54, 51, 49, 46, 44, 42, 39, 37, 35, 33, 31,
29, 27, 25, 23, 21, 20, 18, 16, 15, 13, 12, 11, 9, 8, 7, 6, 5, 4, 4, 3, 2,
2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9,
11, 12, 13, 15, 16, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 42, 44,
46, 49, 51, 54, 56, 59, 62, 64, 67, 70, 73, 76, 79, 81, 84, 87, 90, 93, 96,
99, 103, 106, 109, 112, 115, 118, 121, 124, };
/*********************************************************************
* @fn TIM1_UP_IRQHandler
*
* @brief This function handles TIM1 UP exception.
*
*
* @return none
*/
void TIM1_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void TIM1_UP_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1, TIM_IT_Update)==SET)
{
akk += phase;
TIM1->CH1CVR = sin_table[akk >> 24];
TIM2->CH2CVR = 128; // sin_table[akk >> 24];
GPIO_WriteBit(GPIOD, GPIO_Pin_4, akk >> 31);
}
TIM_ClearITPendingBit( TIM1, TIM_IT_Update );
}
/*********************************************************************
* @fn TIM1_INT_Init
*
* @brief Initializes TIM1 output compare.
*
* @param arr - the period value.
* psc - the prescaler value.
*
* @return none
*/
void TIM1_INT_Init( u16 arr, u16 psc)
{
NVIC_InitTypeDef NVIC_InitStructure={0};
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure={0};
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE );
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOD | RCC_APB2Periph_TIM1 , ENABLE );
TIM_TimeBaseInitStructure.TIM_Period = arr;
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 80;
TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure);
TIM_ClearITPendingBit( TIM1, TIM_IT_Update );
NVIC_InitStructure.NVIC_IRQChannel =TIM1_UP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;
NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
}
void TIM2_PWMOut_Init(u16 arr, u16 psc, u16 ccp)
{
GPIO_InitTypeDef GPIO_InitStructure={0};
TIM_OCInitTypeDef TIM_OCInitStructure={0};
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure={0};
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOD | RCC_APB2Periph_TIM1 , ENABLE );
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //D4 out PWM/Sinus
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_30MHz;
GPIO_Init( GPIOD, &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //D2 Rechteck
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_30MHz;
GPIO_Init( GPIOD, &GPIO_InitStructure );
TIM_TimeBaseInitStructure.TIM_Period = arr;
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit( TIM2, &TIM_TimeBaseInitStructure);
TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = ccp;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC2Init( TIM2, &TIM_OCInitStructure );
TIM_OC1Init( TIM1, &TIM_OCInitStructure );
//GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE );
TIM_CtrlPWMOutputs(TIM2, ENABLE );
TIM_OC1PreloadConfig( TIM1, TIM_OCPreload_Disable );
TIM_OC1PreloadConfig( TIM2, TIM_OCPreload_Disable );
TIM_ARRPreloadConfig( TIM1, ENABLE );
TIM_ARRPreloadConfig( TIM2, ENABLE );
TIM_Cmd( TIM1, ENABLE );
TIM_Cmd( TIM2, ENABLE );
}
void USARTx_CFG(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
USART_InitTypeDef USART_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_USART1, ENABLE);
// USART1 TX-->D.5 RX-->D.6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_30MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOD, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
int getchar(void) {
while((USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)){}
return (USART_ReceiveData(USART1));
}
uint16_t getint(void){
char c;
uint16_t n=0;
while((USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)){}
c=(USART_ReceiveData(USART1));
while (c > 13){
if (c>47 && c<58){
n=n*10;
n+=c-48;
}
while((USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)){}
c=(USART_ReceiveData(USART1));
}
return n;
}
/*********************************************************************
* @fn main
*
* @brief Main program.
*
* @return none
*/
int main(void)
{
SystemCoreClockUpdate();
Delay_Init();
USART_Printf_Init(115200);
printf("SystemClk:%d\r\n",SystemCoreClock);
printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
TIM1_INT_Init(20-1, 0);
TIM_Cmd( TIM1, ENABLE );//5S
TIM2_PWMOut_Init( 255, 0, 128 );
USARTx_CFG();
freq = 1000;
phase = freq*14496;
TIM2->PSC= 65000; //PWM-Freq ca. 3 Hz an D3
while(1){
freq = getint();
phase = freq*14496;
};
}