1.GPIO工作模式
输入:
浮空输入
上拉输入
输出:
推挽输出
(1).浮空输入:浮空输入,可以做KEY识别,RX1
(2).带上拉输入:IO内部上拉电阻输入
(3).开漏输出:IO输出0接GND,IO输出1,悬空,需要外接上拉电阻,才能实现输出高电平。当输出为1时,IO口的状态由上拉电阻拉高电平,但由于是开漏输出模式,这样IO口也就可以由外部电路改变为低电平或不变。
(4).推挽输出:IO输出0-接GND,IO输出1 -接VCC,读输入值是未知的
2.软件配置
参考:STM8S中文书据手册、原理图、google
初始化流程:
cpu时钟初始化
IO输入输出选择
IO模式选择
IO输出/输入电平
(1).CPU时钟初始化(所有STM8工程,都需要先设置时钟)
内部时钟寄存器(CLK_ICKR):
高速内部RC振荡器使能
高速内部振荡器准备就绪
CLK_ICKR = 0x03;
时钟分频寄存器(CLK_CKDIVR):
CLK_CKDIVR = 0x01; //cpu work on 16/2=8MHz
(2).IO寄存器配置
a.IO输入输出选择:
端口x数据方向 (Px_DDR): x可以是A/B/C/D, 分别代表端口A/B/C/D
输入模式:
Px_DDR = 0x00; //端口x全部设置为输入模式
输出模式:
Px_DDR = 0x00; //端口x全部设置为输出模式
b.IO模式选择:
端口x控制寄存器1 (Px_CR1):
输入模式:
浮空输入:Px_CR1 = 0x00; //端口x全部设置为浮空输入
带上拉电阻输入:Px_CR1 = 0xFF; //端口x全部设置为带上拉电阻
输出模式:
模拟开漏输出:Px_CR1 = 0x00; //端口x全部设置为模拟开漏输出
推挽输出:Px_CR1 = 0xFF; //端口x全部设置为推挽输出
c.IO输入/输出电平:
端口x输入寄存器 (Px_IDR):
Input = Px_IDR & 1; //当Input 为0时,端口Px的第0位输入低电平
//当Input 为1时,端口Px的第0位输入高电平
端口x输出数据寄存器(Px_ODR):
Px_ODR |= 0xFF; //端口x全部输出高电平
Px_ODR &= 0xFF; //端口x全部输出低电平
3.附上源码
1.main.c
/* MAIN.C file
*
* Copyright (c) 2002-2005 STMicroelectronics
*/
#include #include "stm8s_type.h" #include "stm8s103f.h" #include "stm8s.h" #include "gpio.h" //test gpio void test_gpio(void) { TGpioProperty Portx; //PD3 上拉输出 低电平设置 Portx.port = PORTD; //选中端口 Portx.dir = 1; //输入、输出选择 Portx.mode = 1; //模式选择 Portx.index = 3; //端口那个 Portx.outlevel = 0; //输出时电平选择,输入模式无效 init_Pxx_as_gpio(Portx); Portx.outlevel = 1; set_Pxx_level(Portx); } int main(void) { bool PD3_level = 0; TGpioProperty Portx; CLK_ICKR = 0x03; /// open interval RTC and wakeup /// set cpu freq. CLK_CKDIVR = 0x00; //cpu work on 16MHz delay_us(5000); //test gpio test_gpio(); Portx.port = PORTD; Portx.dir = 0; Portx.mode = 1; Portx.index = 3; Portx.outlevel = 0; init_Pxx_as_gpio(Portx); while (1) { PD3_level = get_Pxx_level(Portx); if(PD3_level) { } else { } delay_us(1000000); } } 2.gpio.c /* * gpio.c * * Created on: Oct 25, 2019 * Author: * Email : */ #include "stm8s.h" #include "stm8s103f.h" #include "gpio.h" //GPIO输入输出 #define PADIR(dir, index) {dir == 0? (PA_DDR &= ~(1< //GPIO模式选择 #define PAMODE(mode, index) {mode == 0? (PA_CR1 &= ~(1< //输出电平设置 #define PA_OLEVEL(dir, index, level) {dir == 1? (level == 0? (PA_ODR &= ~(1< //输入电平设置 #define PA_ILEVEL(index) (PA_IDR & (1< void init_Pxx_as_gpio(TGpioProperty Portx) { switch(Portx.port) { case PORTA: PADIR(Portx.dir, Portx.index); PAMODE(Portx.mode, Portx.index); PA_OLEVEL(Portx.dir, Portx.index, Portx.outlevel); break; case PORTB: PBDIR(Portx.dir, Portx.index); PBMODE(Portx.mode, Portx.index); PB_OLEVEL(Portx.dir, Portx.index, Portx.outlevel); break; case PORTC: PCDIR(Portx.dir, Portx.index); PCMODE(Portx.mode, Portx.index); PC_OLEVEL(Portx.dir, Portx.index, Portx.outlevel); break; case PORTD: PDDIR(Portx.dir, Portx.index); PDMODE(Portx.mode, Portx.index); PD_OLEVEL(Portx.dir, Portx.index, Portx.outlevel); break; default: break; } } void set_Pxx_level(TGpioProperty Portx) { switch(Portx.port) { case PORTA: PA_OLEVEL(Portx.dir, Portx.index, Portx.outlevel); break; case PORTB: PB_OLEVEL(Portx.dir, Portx.index, Portx.outlevel); break; case PORTC: PC_OLEVEL(Portx.dir, Portx.index, Portx.outlevel); break; case PORTD: PD_OLEVEL(Portx.dir, Portx.index, Portx.outlevel); break; default: break; } } bool get_Pxx_level(TGpioProperty Portx) { bool level = 0;; switch(Portx.port) { case PORTA: level = PA_ILEVEL(Portx.index); break; case PORTB: level = PB_ILEVEL(Portx.index); break; case PORTC: level = PC_ILEVEL(Portx.index); break; case PORTD: level = PD_ILEVEL(Portx.index); break; default: break; } return level; } 3.gpio.h /* * gpio.h * * Created on: Oct 25, 2019 * Author: * Email : */ #ifndef DEVICE_GPIO_GPIO_H_ #define DEVICE_GPIO_GPIO_H_ #include #define INPUT 0 #define OUTPUT 1 #define LOW_LEVEL 0 #define HIGHT_LEVEL 1 #define PushPullOutput 1 #define OpenDrainOutput 0 #define PullUpInput 1 #define FloatingiInput 0 typedef enum { PORTA = 0, PORTB = 1, PORTC = 2, PORTD = 3 }PORTx; typedef struct _gpio_property { PORTx port; //A~D bool dir; //INPUT 0, OUTPUT 1 unsigned char mode; //输入:上拉输入1 浮空输入 0; 输入:开漏输出0 推挽输出1 unsigned char index; //端口下标 unsigned char outlevel; //输出时电平选择,输入模式无效 }TGpioProperty, *PGpioProperty; void init_Pxx_as_gpio(TGpioProperty Portx); void set_Pxx_level(TGpioProperty Portx); bool get_Pxx_level(TGpioProperty Portx); #endif /* DEVICE_GPIO_GPIO_H_ */
设计资源 培训 开发板 精华推荐
- 一种基于洞洞板的面包板
- AD5341 并行接口、单电压输出、12 位 DAC 的典型应用
- LT6207 的典型应用 - 四路单电源 3V、100MHz 视频运算放大器
- 0.9 至 3.3V DC 至 DC 便携式单路输出电源
- MIC4100YM EV,汽车用 MOSFET 功率驱动器评估板
- LT3692AEUH 电源双输入单路 3.3V/4A 输出降压转换器的典型应用电路
- MIC5381-G4YFT EV,MIC5381 高性能双路 150mA LDO 评估板
- LT6657BHMS8-5 扩展电源范围基准的典型应用电路
- TWR-S12GN32:MC9S12GN32超可靠的16位Tower®系统模块
- 1.2V, 1.2V, 1.8V, 2.8V DC to DC多路输出手机电源