CH579/CH573/CH57x GPIO使用
其實不是很想寫,無奈有時候還是寫寫,用到時候貼代碼比較快
適用芯片
- CH579/CH578/CH577
- CH573/CH571
- CH581/CH582/CH583
CH57x/CH58x GPIO特點
從手冊上看,WCH的CH57x,CH58x其GPIO寄存器基本是一致的,其提供的SDK的代碼也基本一致
- CH577/578/579只有Px0-15支持中斷
- CH571/573 全部IO都支持中斷
- 所有的中斷都支持中斷喚醒
- 睡眠后IO的狀態可以保持
- 沒有專門的開漏模式支持(實現開漏可參閱此文章)
SDK里提供的函數的使用
//CH57x只有兩個Port,wch的驅動是分別用不同的函數來對待的
//初始化PA9,推拉模式輸出,5mA驅動能力
GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
//拉高PA9
GPIOA_SetBits(GPIO_Pin_9);
//拉高PA8,PA9
GPIOB_SetBits(GPIO_Pin_8|GPIO_Pin_9);
//拉低PB3
GPIOB_ResetBits(GPIO_Pin_3);
//反轉IO
GPIOB_InverseBits(GPIO_Pin_3);
//讀GPIOA port
GPIOA_ReadPort();
//讀GPIOB port
GPIOB_ReadPort();
//讀PAx的值
//GPIOA_ReadPortPin的返回值並不是bool值,而是對應的port&pin的值
GPIOA_ReadPortPin( pin );
外部中斷
在CH577/CH578/CH579上
//初始化位輸入上拉
GPIOB_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
//開啟下降沿中斷
GPIOB_ITModeCfg(GPIO_Pin_8,GPIO_ITMode_FallEdge);
//開啟GPIO的睡眠喚醒,如果需要的話
PWR_PeriphWakeUpCfg( ENABLE, RB_SLP_GPIO_WAKE );
//開啟GPIO中斷
NVIC_EnableIRQ( GPIO_IRQn );
//中斷服務程序
void GPIO_IRQHandler(void) {
PRINT("gpio interrupt\r\n");
GPIOB_ClearITFlagBit(GPIO_Pin_8);
}
在CH571/CH573上
void gpio_wake_init() {
//初始化位輸入上拉
GPIOB_ModeCfg(GPIO_Pin_4, GPIO_ModeIN_PU);
//開啟下降沿中斷
GPIOB_ITModeCfg(GPIO_Pin_4,GPIO_ITMode_FallEdge);
//開啟GPIO睡眠喚醒
PWR_PeriphWakeUpCfg( ENABLE, RB_SLP_GPIO_WAKE,Edge_LongDelay );
//開啟GPIOB中斷
PFIC_EnableIRQ(GPIO_B_IRQn);
}
//中斷服務程序
__attribute__((interrupt("WCH-Interrupt-fast"))) //硬件壓棧
__attribute__((section(".highcode"))) //放到RAM里
void GPIOB_IRQHandler(void) {
PRINT("gpio interrupt\r\n");
GPIOB_ClearITFlagBit(GPIO_Pin_4);
}
外設重映射
CH57Xx系列的芯片,很多數字外設都支持 端口重映射(只是映射到芯片支持的第二個IO上)
如在ch573/ch571上 把UART1 從默認的PA8,PA9映射到PB12:
//remap uart1 to PB13/PB12
//使能對應的外設重映射
GPIOPinRemap( ENABLE, RB_PIN_UART1 );
//初始化對應外設映射后的gpio
GPIOB_SetBits(bTXD1_);
GPIOB_ModeCfg(bTXD1_, GPIO_ModeOut_PP_5mA);
//初始化對應的外設
UART1_DefInit( );
注意事項
- CH578M/CH579M的 PB16 PB17 對應的是ARM-SWD調試口,如果啟用了,會導致該兩個io在程序中不能被控制
- 對於下降沿或者低電平喚醒,在進入休眠時候必須保證 對應的IO是高電平,否則電流會比較大,mA級; 對於上升沿或者高電平喚醒,在進入休眠時候必須保證 對應的IO是低電平,否則電流會比較大,mA級
- GPIO的原子操作問題:
- CH57x,CH58x 系列的BLE芯片,其GPIO都是只提供了reset寄存器,並沒有提供專用的set寄存器.