STM8S IO口基本输入输出

GPIO主要功能
● 端口的各个位可以被单独配置
● 可选择的输入模式:浮动输入和带上拉输入
● 可选择的输出模式:推挽式输出和开漏输出
● 数据输入和输出采用独立的寄存器
● 外部中断可以单独使能和关闭
● 输出摆率控制用以减少EMC噪声
● 片上外设的I/O功能复用
● 当作为模拟输入时可以关闭输入施密特触发器来降低功耗
● 在数据输出锁存时支持读-修改-写
● 输入兼容 5V电压
● I/O口工作电压范围为1.6 V 到VDDIOmax


STM8S的IO口相关的寄存器
端口 x 输出数据寄存器 (Px_ODR)
Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
Px_ODR ODR7 ODR6 ODR5 ODR4 ODR3 ODR2 ODR1 ODR0
读/写 R/w R/w R/w R/w R/w R/w R/w R/w
复位 0 0 0 0 0 0 0 0
Px_ODR中的x代表A、B、C、D、E等端口(下同),这个寄存器所有的位都是一样的,要输出数据的时候把数据往这个寄存器里面放就得了。


一、端口 x 输入寄存器 (Px_IDR)
Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
Px_IDR IDR7 IDR6 IDR5 IDR4 IDR3 IDR2 IDR1 IDR0
读/写 R R R R R R R R
复位 —— —— —— —— —— —— —— ——
无论是输入还是输出模式,都可以通过这个寄存器读取IO电平,
0=低电平;
1=高电平;


二、端口 x 数据方向 (Px_DDR)
Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
Px_DDR DDR7 DDR6 DDR5 DDR4 DDR3 DDR2 DDR1 DDR0
读/写 R/W R/W R/W R/W R/W R/W R/W R/W
复位 0 0 0 0 0 0 0 0
IO口方向操作
0=输入模式;
1=输出模式;


三、端口 x 控制寄存器 1 (Px_CR1)
注意: 初始复位时,所有引脚设置为浮空输入。
Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
Px_CR1 C17 C16 C15 C14 C13 C12 C11 C10
读/写 R/W R/W R/W R/W R/W R/W R/W R/W
复位 0 0 0 0 0 0 0 0
这个寄存器在输入输出不同模式下有不同的功能
在 输入模式时(DDR=0):
0:浮空输入
1::带上拉电阻输入
在 输出模式时(DDR=1):
0:模拟开漏输出(不是真正的开漏输出)
1: 推挽输出, 由CR2相应的位做输出摆率控制


四、端口 x 控制寄存器 2 (Px_CR2)

  • Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
    PxCR2 C27 C26 C25 C24 C23 C22 C21 C20
    读/写 R/W R/W R/W R/W R/W R/W R/W R/W
    复位 —— —— —— —— —— —— —— ——

这个寄存器在输入输出不同模式下有不同的功能
在 输入模式时(DDR=0):
0: 禁止外部中断
1: 使能外部中断
在 输出模式时(DDR=1):
0:输出速度最大为2MHZ.
1:输出速度最大为10MHZ


 ```
例;
IO输出,PE5输出高低电平
/*这个工程模板是别人的,并不是按照官方的标准模板,
这个头文件型号不影响编程*/
#include  

#define LED_On      PE_ODR |=  1<<5      //PE5输出1,低电平有效
#define LED_Off     PE_ODR &= ~(1<<5)    //PE5输出0

void delay(unsigned int ms);
void InitLED(void);

//********************************
int main(void)
{

  CLK_CKDIVR = 0x00;      /*内部时钟为1分频 = 16Mhz,
                          每个工程都要初始化时钟*/
  InitLED();              //调用LED初始化函数
  while(1)
  {
     LED_On;
     delay(100);         //空跑大概延时

     LED_Off;
     delay(100);          //空跑大概延时
  }
}

//***********************************
//这只是概大延时,时间并不精准
void delay(unsigned int ms)
{
  unsigned int x , y;
  for(x = ms; x > 0; x--)    
    for(y = 3000 ; y > 0 ; y--);
}

void InitLED()
{
    PE_DDR |= 1<<5;//PE5方向为输出
    PE_CR1 |= 1<<5;//PE5为推挽输出
    PE_CR2 |= 1<<5;//最大输出速度为10M
    PE_ODR |= 1<<5;//PE5输出1
}


----------


例;PE5的LED状态翻转
/*这个工程模板是别人的,并不是按照官方的标准模板,
这个头文件型号不影响编程*/
#include  

#define LED_Reverse      PE_ODR ^=1 <<5     //PE5输出状态翻转

void delay(unsigned int ms);
void InitLED(void);

//********************************
int main(void)
{
  CLK_CKDIVR = 0x00;      /*内部时钟为1分频 = 16Mhz,
                          每个工程都要初始化时钟*/
  InitLED();              //调用LED初始化函数
  while(1)
  {
     LED_Reverse;
     delay(100);         //空跑大概延时
  }
}

//***********************************
//这只是概大延时,时间并不精准
void delay(unsigned int ms)
{
  unsigned int x , y;
  for(x = ms; x > 0; x--)    
    for(y = 3000 ; y > 0 ; y--);
}

void InitLED()
{
    PE_DDR |= 1<<5;//PE5方向为输出
    PE_CR1 |= 1<<5;//PE5为推挽输出
    PE_CR2 |= 1<<5;//最大输出速度为10M
    PE_ODR |= 1<<5;//PE5输出1
}


----------


例;PC1按键输入,触发PE5的LED状态翻转
/*这个工程模板是别人的,并不是按照官方的标准模板
这个头文件型号不影响编程*/
#include  

#define LED_Reverse   PE_ODR ^=1 <<5  //PE5输出状态翻转

void InitLED(void);
void InitKey(void);

//********************************
int main(void)
{
  CLK_CKDIVR = 0x00; //内部时钟为1分频 = 16Mhz,每个工程都要初始化时钟
  InitLED();             //调用LED初始化函数
  InitKey();             //初始化按键输入
  while(1)
  {
    if((PC_IDR&0x02)==0)//PC1是上拉输入,当把PC1短接到gnd后
                        //LED状态会翻转,这里并没有消抖
       LED_Reverse;
  }
}
//********************************************************
//子函数
void InitLED()
{
    PE_DDR |= 1<<5;//PE5方向为输出
    PE_CR1 |= 1<<5;//PE5为推挽输出
    PE_CR2 |= 1<<5;//最大输出速度为10M
    PE_ODR |= 1<<5;//PE5输出1
}
void InitKey(void)
{
  PC_DDR &= ~(1<<1);//PC1方向为输入
  PC_CR1 |= 1<<1;   //PC1上拉输入
  PC_CR2 &= ~(1<<1);//PC1不使能中断
}

你可能感兴趣的:(STM8S)