[CH32V003]GPIO EXTERNAL Interrupt
GPIOによるインターラプト。
GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource3);
サンプルはネットで見つける事ができるのですが、
GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource3);
この1行がよくわからないので調査。インターラプトに設定するピンを素直にPC3とかPD1とか指定させてくれれば良いのに、GPIO_PinSource3???
EXTI0~EXTI7の8個の外部インタラプトが用意されている
GPIO(Px0~Px7(x=A/B/C/D))に設定ができる
ただし、EXTI0ならPx0と数字の部分が一致していないといけない。
EXTI0にPA0を割り当てると他のPB0,PC0,PD0に設定する事ができない。
という事か。
さっそくテストをしてみる。
//CH32V003 * 5V tolerant pins
// -----------------------
//1 - PD4 PD3 - 20
//2 - PD5(UTX) PD2 - 19
//3 - PD6(URX) (SWIO)PD1 - 18
//4 - PD7 (MISO)PC7 - 17
//5 - PA1 (MOSI)*PC6 - 16
//6 - PA2 (SCK)*PC5 - 15
//7 - VSS (GNG) PC4 - 14
//8 - PD0 PC3 - 13
//9 - VDD *PC2 - 12
//10- PC0 *PC1 - 11
// -----------------------
#include "debug.h"
/* Global define */
/* Global Variable */
vu8 val;
/*********************************************************************
* @fn USARTx_CFG
*
* @brief Initializes the USART2 & USART3 peripheral.
*
* @return none
*/
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_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);
}
void GPIO_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure={0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
void EXTI0_INT_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
EXTI_InitTypeDef EXTI_InitStructure = {0};
NVIC_InitTypeDef NVIC_InitStructure = {0};
/* GPIO PD3 setting */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/*EXTernal Interrupt(EXTI)
/* GPIOD ----> EXTI_Line3 */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource3);
EXTI_InitStructure.EXTI_Line = EXTI_Line3;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* ベクタ割込みコントローラ(NVIC)を設定する*/
NVIC_InitStructure.NVIC_IRQChannel = EXTI7_0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI7_0_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void EXTI7_0_IRQHandler(void)
{
EXTI_ClearFlag(EXTI_Line3); // 割り込みフラグをリセット
GPIO_SetBits(GPIOD, GPIO_Pin_2); // CS HIGH
Delay_Us(10);
GPIO_ResetBits(GPIOD, GPIO_Pin_2); // CS LOW
}
/*********************************************************************
* @fn main
*
* @brief Main program.
*
* @return none
*/
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
SystemCoreClockUpdate();
Delay_Init();
#if (SDI_PRINT == SDI_PR_OPEN)
SDI_Printf_Enable();
#else
USART_Printf_Init(115200);
#endif
printf("SystemClk:%d\r\n",SystemCoreClock);
printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
USARTx_CFG();
GPIO_INIT();
EXTI0_INT_INIT();
GPIO_ResetBits(GPIOD, GPIO_Pin_2); // CS LOW
GPIO_ResetBits(GPIOD, GPIO_Pin_4); // CS LOW
while(1)
{
GPIO_SetBits(GPIOD, GPIO_Pin_4); // CS HIGH
Delay_Us(5);
GPIO_ResetBits(GPIOD, GPIO_Pin_4); // CS LOW
Delay_Ms(150);
// while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
// {
// /* waiting for receiving finish */
// }
// val = (USART_ReceiveData(USART1));
// USART_SendData(USART1, ~val);
// while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
// {
// /* waiting for sending finish */
// }
}
}
【動作】
・PD4を出力設定して、150msec毎に5usecのパルスを出力
・PD3を入力設定し、PD4のパルスを受ける。
・PD3が立下りを検出したら、PD2に10usecのパルスを出力する。
・クロックは、48MHzに設定
【検証の結果】
PD4黄色のパルスの立下りを検出、0.92usec程度遅れて、PD2緑のパルスが立ち上がる。
5usecのパルスは7.65~7.75usecとロジアナでは見えて、10uパルスは、12.83~12.92
コメント
コメントを投稿