2. GPIO configuration and programming of running lights and buttons

1. GPIO basics

Question: What does GPIO refer to? Is the more pins the better?

General Purpose Input Output General purpose input and output interface; in fact, enough pins are good enough, just choose a suitable number of chips.

Modes supported by STM8 microcontroller GPIO:
Insert picture description here

1. Input mode and characteristics

  1. Floating input/floating input mode
    Features:
    high input impedance, suitable for occasions where analog signals are converted to digital signals, often used in ADC types, maintaining complete analog signal characteristics
    Insert picture description here
  2. Pull-up input mode
    Features:
    R1 (30-80K, 55K is a common value), the uncertain level signal on the pin is passed to a high level through a pull-up resistor, and the resistor also acts as a current limiter.
  • Among them, the larger R is, the smaller its effect is, which is called weak pull-up;
  • Among them, the smaller R is, the greater its effect is, which is called strong pull-up;
    Insert picture description here
  1. Protection diode
    characteristics: The function of the protection diode is to place a germanium diode or Schottky with a lower voltage drop if the input voltage from the external control is too high (D1 plays a role in stepping down) or too low (D2 plays a role in adjusting close to 0V). The barrier diode serves as a protection diode.
    Insert picture description here

2. Output mode and characteristics

  1. Push-pull/complementary output
    Features:
    Use two transistors or MOS transistors. Push-pull output is also referred to as PP structure, with low conduction loss, low conduction loss and high efficiency.
    Insert picture description here
  2. Open-drain output
    Features:
    The high-level state to be determined requires an external pull-up resistor. This mode is suitable for current-type driving, and its current absorption capability is relatively strong (generally within 20mA). Most of the drive current is provided by the external power supply to the circuit or device connected to the pin through a pull-up resistor, and there is almost no need to provide a drive current inside the microcontroller. And it can realize line-and logic.
    Insert picture description here
  3. True open-drain output mode
    Features:
    There is no P-channel MOS tube pulled up to the digital power supply in the internal circuit of this pin, and there is no protection diode connected to the digital power supply. The internal circuit is fixed, such pins cannot be configured to output in push-pull mode.
    Insert picture description here

2. Pin identification and configuration

LQFP Thin Quad Flat Package
Insert picture description here

  1. Explanation of the meaning of the description symbols
    Insert picture description here
    O1: Slow output, up to 2MHz
    O2: Fast output, up to 10MHz
    O3: Programmable output, consistent with slow speed after reset
    O4: Programmable output, consistent with fast after reset
    Insert picture description here
  2. The chip pin characteristics are
    Insert picture description here
    distributed as follows:
    Insert picture description here
  3. Five commonly used registers related to GPIO functions.
    Each GPIO port is allocated: an output data register, an input data register, a data direction register and two control registers.
    Insert picture description here
  4. GPIO mode configuration table and mode status (you can check the data manual)
    Insert picture description here
    need to pay attention to:
  • None of the outputs have pull-up resistors
  • The input has no output, so there is no P channel
  • For true open drain, there is no P-channel, and there is no protective pull-up diode Vdd.

Third, the bit operation of the configuration register

(Bitwise or |, bitwise and &, bitwise inverse ~, left shift >>, right shift <<) It
should be noted that || is a logical OR, && is a logical AND, the result is only 01, not a bit operation.

  • Bit-OR operation, that is, set 1 operation to change a certain bit into 1
    eg:
PB_DDR |= 0x44PB_DDR |= (0x1<<3)
  • Bit-and operation, that is, clearing operation to change a certain bit to 0
    eg:
PB_DDR &= 0x44PB_DDR &= ~(0x1<<3)
  • Value operation, read the port status and assign it to the variable "x"
    eg:
x = (PB_IDR >> 2) & 0x01;		//读取PB2端口状态
  • Configure the high 4 bits of the PB group port for 2MHz slope open-drain output mode, and the low four bits for 10MHz slope late output mode, allowing the port to output "01010111" level status
PB_DDR = 0xFF;
PB_CR1 = 0x0F;
PB_CR2 = 0x0F;
PB_ODR = 0x57

Among them, because IAR has written a header file of more than five thousand lines for us, it can support direct manipulation of the relevant bits, which is more convenient, but STVD does not support it, that is, the two software codes need to be changed when transplanting. Traversal brought by IAR header files:

/*---------------------------------------------------------
 *      Port B bit fields
 *-------------------------------------------------------*/
#ifdef __IAR_SYSTEMS_ICC__

#define PB_ODR_ODR0              PB_ODR_bit.ODR0
#define PB_ODR_ODR1              PB_ODR_bit.ODR1
#define PB_ODR_ODR2              PB_ODR_bit.ODR2
#define PB_ODR_ODR3              PB_ODR_bit.ODR3
#define PB_ODR_ODR4              PB_ODR_bit.ODR4
#define PB_ODR_ODR5              PB_ODR_bit.ODR5
#define PB_ODR_ODR6              PB_ODR_bit.ODR6
#define PB_ODR_ODR7              PB_ODR_bit.ODR7

#define PB_IDR_IDR0              PB_IDR_bit.IDR0
#define PB_IDR_IDR1              PB_IDR_bit.IDR1
#define PB_IDR_IDR2              PB_IDR_bit.IDR2
#define PB_IDR_IDR3              PB_IDR_bit.IDR3
#define PB_IDR_IDR4              PB_IDR_bit.IDR4
#define PB_IDR_IDR5              PB_IDR_bit.IDR5
#define PB_IDR_IDR6              PB_IDR_bit.IDR6
#define PB_IDR_IDR7              PB_IDR_bit.IDR7

#define PB_DDR_DDR0              PB_DDR_bit.DDR0
#define PB_DDR_DDR1              PB_DDR_bit.DDR1
#define PB_DDR_DDR2              PB_DDR_bit.DDR2
#define PB_DDR_DDR3              PB_DDR_bit.DDR3
#define PB_DDR_DDR4              PB_DDR_bit.DDR4
#define PB_DDR_DDR5              PB_DDR_bit.DDR5
#define PB_DDR_DDR6              PB_DDR_bit.DDR6
#define PB_DDR_DDR7              PB_DDR_bit.DDR7

#define PB_CR1_C10               PB_CR1_bit.C10
#define PB_CR1_C11               PB_CR1_bit.C11
#define PB_CR1_C12               PB_CR1_bit.C12
#define PB_CR1_C13               PB_CR1_bit.C13
#define PB_CR1_C14               PB_CR1_bit.C14
#define PB_CR1_C15               PB_CR1_bit.C15
#define PB_CR1_C16               PB_CR1_bit.C16
#define PB_CR1_C17               PB_CR1_bit.C17

#define PB_CR2_C20               PB_CR2_bit.C20
#define PB_CR2_C21               PB_CR2_bit.C21
#define PB_CR2_C22               PB_CR2_bit.C22
#define PB_CR2_C23               PB_CR2_bit.C23
#define PB_CR2_C24               PB_CR2_bit.C24
#define PB_CR2_C25               PB_CR2_bit.C25
#define PB_CR2_C26               PB_CR2_bit.C26
#define PB_CR2_C27               PB_CR2_bit.C27

#endif

Specific operation:
Insert picture description here

Four, running water lights and buttons

1. Move the water lamp to the left

void LED_Left_Play2(void)
{
  u8 x = 0xFE;
  u8 i = 0;
  for(i = 0; i <4; i++){
    PI_ODR = x;
    delay_ms(20);
    x = x << 1;
    x |= 0x01;
  }
}

2. Move the water lamp to the right

void LED_Right_Play2(void)
{
  u8 x = 0xF7;
  u8 i = 0;
  for(i = 0; i < 4; i++){
    PI_ODR = x;
    delay_ms(20);
    x = x >> 1;
    x |= 0x80;
  }
}

3. Loop back and forth

void LED_Left_Play(void)   //左移流水灯     
{
  PI_ODR_ODR0 = 0;
  PI_ODR_ODR3 = 1;
  delay_ms(20);
  PI_ODR_ODR1 = 0;
  PI_ODR_ODR0 = 1;
  delay_ms(20);
  PI_ODR_ODR2 = 0;
  PI_ODR_ODR1 = 1;
  delay_ms(20);
  PI_ODR_ODR3 = 0;
  PI_ODR_ODR2 = 1;
}

void LED_Right_Play(void)      //右移流水灯
{
  PI_ODR_ODR3 = 0;
  PI_ODR_ODR0 = 1;
  delay_ms(20);
  PI_ODR_ODR2 = 0;
  PI_ODR_ODR3 = 1;
  delay_ms(20);
  PI_ODR_ODR1 = 0;
  PI_ODR_ODR2 = 1;
  delay_ms(20);
  PI_ODR_ODR0 = 0;
  PI_ODR_ODR1 = 1;
}

4. Design of running water lamp array

void LED_MyDesign(void)
{
  u8 MyLed[8] = {0xFE,0xF7,0xFE,0xF7,0xFD,0xFB,0xFD,0xFB};
  u8 MyLed2[8] = {0xF6,0xF9,0xF6,0xF9,0xFA,0xF5,0xFA,0xF5};
  u8 MyLed3[9]={0xF6,0xF9,0xF6,0xF9,0xFF,0xF0,0xFF,0xF0,0xFF};
  u8 i;
   for(i = 0; i < 9; i++){
    PI_ODR = MyLed3[i];
    delay_ms(20);
  }
  for(i = 0; i < 8; i++){
    PI_ODR = MyLed[i];
    delay_ms(20);
  }
  for(i = 0; i < 8; i++){
    PI_ODR = MyLed2[i];
    delay_ms(20);
  }
}

5. Button control Led light

#define KEY8 PA_IDR_IDR1        //输入量
#define LED0 PI_ODR_ODR0        //输出量
void Key_For_Led(void)  //PA1控制K8
{
    //键盘按键控制LED灯,PA1控制LED0
  PI_DDR_DDR0 = 1;
  PI_CR1_C10 = 1;
  PI_CR2_C20 = 0;
  LED0 = 1;      //熄灭
  
  PA_DDR_DDR1 = 0;
  PA_CR1_C11 = 1; 
  PA_CR2_C21 = 0;
  
while(1){
    if(KEY == 0){  //按键按下
      delay_ms(5);  //消抖
      if(KEY == 0){//再次确认按键按下
        LED = !LED;   //控制LED灯
      }
    while(!KEY);        //如果一直处于按下则等待,很关键,需等待到按键松开再启动新一轮的循环
    }
    // while(!KEY);    //错误的地方,应该为按键按下的时间段中,所以应该包含在if语句中
  }
}

void delay_ms(u32 time)
{
  u32 i,j;
  while(time--){
    for(i = 0; i < 10; i++){
      for(j = 0; j < 100; j++);
    }
  }
}

6. Debug the total code

#include "iostm8s208mb.h"

#define u8  uint8_t
#define u16 uint16_t
#define u32 uint32_t
typedef unsigned char    uint8_t;
typedef unsigned short   uint16_t;
typedef unsigned long    uint32_t;

#define KEY8 PB_IDR_IDR1        //输入量
#define LED0 PI_ODR_ODR0        //输出量

void Key_For_Led(void);     
void GPIO_Init(void);
void LED_light(void);
void LED_Right_Play(void);
void LED_Left_Play(void);
void LED_Right_Play2(void);
void LED_Left_Play2(void);
void LED_MyDesign(void);
void delay_ms(u16 time);

u32 count ;

int main()
{
  //GPIO_Init();
  
  /*    闪烁灯
  PI_ODR_ODR2 = 0;
  PI_ODR_ODR1 = 0;
  while(count--){
    LED_light();
  }
  */
  
 /*   花样流水灯
  while(1)
    LED_MyDesign();
  
  count = 3;
  while(count--)
    LED_Right_Play2();
 
 count = 3;
  while(count--)
    LED_Left_Play2();
  
  count = 3;
  while(count--){     //来回移动
    LED_Left_Play();
    LED_Right_Play();
  }
  */
  
    Key_For_Led();
  
}

void GPIO_Init(void)    //GPIO初始化
{
  /*
  PI_DDR_DDR2 = 1;
  PI_CR1_C12 = 1;
  PI_CR2_C22 = 0;

  PI_DDR_DDR1 = 1;
  PI_CR1_C11 = 1;
  PI_CR2_C21 = 0;
  
  PI_DDR |= 0x09;
  PI_CR1 |= 0x09;
  PI_CR2 &= 0xF6;
  */
  
  PI_DDR |= 0x0F;
  PI_CR1 |= 0x0F;
  PI_CR2 &= 0xF0;
  PI_ODR |= 0x0F;
  
  
  
}

void Key_For_Led(void)  //PA1控制K8
{
    //键盘按键控制LED灯,PA1控制LED0
  PI_DDR_DDR0 = 1;
  PI_CR1_C10 = 1;
  PI_CR2_C20 = 0;
  LED0 = 1;      //熄灭
  
  PB_DDR_DDR1 = 0;
  PB_CR1_C11 = 1;
  PB_CR2_C21 = 0;
  
while(1){
    if(KEY == 0){  //按键按下
      delay_ms(5);  //消抖
      if(KEY == 0){//再次确认按键按下
        LED = !LED;   //控制LED灯
      }
    while(!KEY);        //如果一直处于按下则等待
    }
  }
   
}


void LED_MyDesign(void)
{
  u8 MyLed[8] = {0xFE,0xF7,0xFE,0xF7,0xFD,0xFB,0xFD,0xFB};
  u8 MyLed2[8] = {0xF6,0xF9,0xF6,0xF9,0xFA,0xF5,0xFA,0xF5};
  u8 MyLed3[9]={0xF6,0xF9,0xF6,0xF9,0xFF,0xF0,0xFF,0xF0,0xFF};
  u8 i;
   for(i = 0; i < 9; i++){
    PI_ODR = MyLed3[i];
    delay_ms(20);
  }
  for(i = 0; i < 8; i++){
    PI_ODR = MyLed[i];
    delay_ms(20);
  }
  for(i = 0; i < 8; i++){
    PI_ODR = MyLed2[i];
    delay_ms(20);
  }
}

void LED_light(void)    //闪烁灯
{
  PI_ODR &= 0xF6;
  delay_ms(20);
  PI_ODR |= 0x09;
  delay_ms(20);
}

void LED_Right_Play2(void)
{
  u8 x = 0xF7;
  u8 i = 0;
  for(i = 0; i < 4; i++){
    PI_ODR = x;
    delay_ms(20);
    x = x >> 1;
    x |= 0x80;
  }
}

void LED_Left_Play2(void)
{
  u8 x = 0xFE;
  u8 i = 0;
  for(i = 0; i <4; i++){
    PI_ODR = x;
    delay_ms(20);
    x = x << 1;
    x |= 0x01;
  }
}

void LED_Left_Play(void)   //左移流水灯     
{
  PI_ODR_ODR0 = 0;
  PI_ODR_ODR3 = 1;
  delay_ms(20);
  PI_ODR_ODR1 = 0;
  PI_ODR_ODR0 = 1;
  delay_ms(20);
  PI_ODR_ODR2 = 0;
  PI_ODR_ODR1 = 1;
  delay_ms(20);
  PI_ODR_ODR3 = 0;
  PI_ODR_ODR2 = 1;
}

void LED_Right_Play(void)      //右移流水灯
{
  PI_ODR_ODR3 = 0;
  PI_ODR_ODR0 = 1;
  delay_ms(20);
  PI_ODR_ODR2 = 0;
  PI_ODR_ODR3 = 1;
  delay_ms(20);
  PI_ODR_ODR1 = 0;
  PI_ODR_ODR2 = 1;
  delay_ms(20);
  PI_ODR_ODR0 = 0;
  PI_ODR_ODR1 = 1;
}

void delay_ms(u16 time)
{
  u8 i,j;
  while(time--){
    for(i = 0; i < 50; i++){
      for(j = 0; j < 20; j++);
    }
  }
}






Guess you like

Origin blog.csdn.net/weixin_44751294/article/details/106654800