[CC2530 Introduction Tutorial-02] CC2530's general I/O port input and output control

[CC2530 Introduction Tutorial-06] CC2530's ADC working principle and application

[CC2530 Introduction Tutorial-05] The principle and application of the serial interface of CC2530

[CC2530 Introduction Course-04] The principle and application of CC2530 timer/counter

[CC2530 Introduction Course-03] CC2530 Interrupt System and External Interrupt Application

[CC2530 Introduction Tutorial-02] CC2530's general I/O port input and output control

[CC2530 Getting Started Tutorial-01] CC2530 Microcontroller Development Getting Started Basics


One, the pin overview of CC2530

        The CC2530 microcontroller is packaged in QFN40 and has 40 pins. Among them, there are 21 digital I/O ports , among which P0 and P1 are 8-bit ports , and P2 has only 5 bits available. These 21 ports can all be configured through programming . In fact, of the 5 pins of the P2 port, 2 need to be used for simulation and 2 need to be used as a crystal oscillator. You can really use only 17 pins in the development of CC2530 .

        Inside the microcontroller, there are storage units with special functions. These units are used to store commands, data, or some status information during the operation of the internal devices of the microcontroller. These registers are collectively referred to as " special function registers (SFR). " . The essence of operating a microcontroller is to read and write these special function registers, and some special function registers can be bit-addressed .

        Each special function register is essentially a memory unit , and the memory address that identifies each memory unit is not easy to remember. For ease of use, each special function register is given a name. When programming, as long as the header file " ioCC2530.h " is introduced , the memory address can be accessed directly by the name of the register.

There are 4 common registers related to the general-purpose I/O port of CC2530:

        <1>  PxSEL : Port function selection, to set whether the port is general I/O or peripheral function .

        <2>  PxDIR : As a general I/O, it is used to set the direction of data transmission.

        <3>  PxINP : When used as a general-purpose input port, select whether the input mode is pull-up , pull-down or tri-state .

        <4>  Px : Data port, used to control the output of the port or get the input of the port.

 

Second, the method of setting certain bits in the register

 <1> Clear some bits of the register to 0 without affecting other bits.

        For example: The current value of the register is P1TM 0x6C, now requires the first register . 1 bit of . 3  , and position . 5 bit is set to 0 , while not affecting the remaining bits of the value of the register, then, should be written in the C language how What about the code?

        Use " &= " to clear the specified bit of the register to 0 without affecting the value of other bits.

        Correct writing: P1TM &= ~0x2A;

        Because: the characteristic of the logic "and" operation is that the bit has a 0 and the result is 0, if it is 1, the original value is kept unchanged.

        The first byte  0000 0000  in bit to be operated is set to 1 , i.e., 00101010 , this value in the inverted , i.e., 11010101 , i.e. ~ 0x2A . Then "AND" the value with the register P1TM, then the bits with 0, that is, bits 1, 3, and 5 will be cleared to 0, and the remaining bits will maintain their original values.

        So: the current value of P1TM is 0x6c, which is 0110 1100,

        0110 1100  &&  1101 0101  =  0100 0100 , that is, bits 1, 3, and 5 are cleared to 0, and the other bits remain unchanged.

        <Note> : This method can only operate when multiple bits are cleared to 0 at the same time, or one bit is cleared to 0. If the register bit needs to be cleared to 0 and set to 1, this writing method cannot be used. (Think about the reasons for yourself)

        In many source code programs of embedded applications, the clearing operation for the nth bit of the register can also be written as: register &= ~(0x01<<(n)); the reason is the same.

<2> Set some bits of the register without affecting other bits.

        For example: the current value of the register P1TM is 0x6c, now it is necessary to set the 1st , 4th and 5th bits of the register to 1 , and at the same time can not affect the value of the other bits of the register, then, how to write in C language What about the code?

        Use " |= " to assign the register to 1 without affecting the value of other bits.

        Correct writing: P1TM |= 0x32;

        Because: the characteristic of the logical "or" operation is that the bit has a 1 and the result is 1, and if it is 0, the original value is kept unchanged.

        The first byte  0000 0000  in bit to be operated is set to 1 , i.e., 00110010 , is 0x32. Then "OR" the value with the register P1TM, the bit with 1, that is, bits 1, 4, and 5 will be set to 1, and the remaining bits will remain unchanged.

        So: the current value of P1TM is 0x6c, which is 0110 1100,

        0110 1100 ||  0011 0010  =  0111 1110 , that is, the positions 1, 4, and 5 are 1, and the other bits remain unchanged.

        Also note: this method can only operate when multiple bits are set to 1 at the same time, or a certain position is set to 1.

        The clearing operation for the nth bit of the register can also be written as: register |= (0x01<<(n));

 

3. Training case: key input to control light output status

[1] Preparations.

Introduce the necessary header file " ioCC2530.h " for CC2530 , define related variables, etc.

[2] Port function selection.

        Most of the I/O ports of the microcontroller are multiplexed with functions . When in use, the function of the port needs to be configured through the function selection register.

[3] Port transmission direction setting.

[4] Set the input mode for the input port.

        The input mode is used to obtain input electrical signals from external devices. When the pin of CC2530 is an input port, the port can provide three input modes of "pull up", "pull down" and "three-state", which can be set by programming . In this training, there is actually no need to set the input mode for the P0_1 and P1_2 pins, because after the CC2530 is reset, each I/O port uses the pull-up mode by default.

[5] The basic idea of ​​general I/O port register configuration.

[6] Design port initialization function InitPort().

        <1>Set the P1SEL register, and set P1_2, P1_3, and P1_4 as general-purpose I/O ports.

        <2> Set the P1DIR register, set P1_3 and P1_4 as output, and set P1_2 as input.

        <3>Set the P0SEL register, and set P0_1 as a general-purpose I/O port.

        <4> Set the P0DIR register and set P0_1 as an input.

        <5> Set the PxINP register, set P0_1 and P1_2 to pull-up mode, or not set it.

[7] Design the keyboard scanning function ScanKeys().

        <1> When there is no button, the input of the port is high . When it is found that the port has a low level , it may be a button press, which needs to be de-jittered . If the port is still low, It is confirmed as a button press.

        <2> When performing key processing, first wait for the key to be released , and then perform the inverted control of the switch state of the relevant LED.

[8] The realization of the main function.

At this point, the work is done, connect to the emulator, compile and debug.

[Attachment]: This training source code.

#include "ioCC2530.h"

#define LED5 P1_3
#define LED6 P1_4
#define SW1 P1_2
#define SW2 P0_1
/*===================延时函数=========================*/
void Delay(unsigned int t)
{
  while(t--);
}
/*================端口初始化函数======================*/
void InitPort()
{
  P1SEL &= ~0x18;         //将P1_3和P1_4设置为通用I/O端口功能
  P1DIR |= 0x18;          //将P1_3和P1_4的端口传输方式设置为输出
  P1SEL &= ~0x04;         //将P1_2设置为通用I/O端口功能
  P1DIR &= ~0x04;         //将P1_2的端口传输方式设置为输入
  P0SEL &= ~0x02;         //将P0_1设置为通用I/O端口功能
  P0DIR &= ~0x02;         //将P0_1的端口传输方式设置为输入
  P0INP &= ~0x02;         //将P0_1的端口输入方式设置为:上拉/下拉
  P1INP &= ~0x04;         //将P1_2的端口输入方式设置为:上拉/下拉
  P2INP &= ~0x60;         //将P0端口和P1端口引脚设置为:上拉
  LED5 = 0;               //上电的时候,LED5不亮
  LED6 = 0;               //上电的时候,LED6不亮
}
/*=================按键扫描函数=======================*/
void ScanKeys()
{
  if(SW1 == 0)
  {                       //发现SW1有低电平信号
    Delay(100);           //按键去抖动
    if(SW1 == 0)
    {                      //确实是有按键动作
      while(SW1 == 0);    //等待按键1松开
      //将LED5的灯光开关状态取反
      LED5 = ~LED5;
  }
  if(SW2 == 0)
  {                       //发现SW2有低电平信号
    Delay(100);           //按键去抖动
    if(SW2 == 0)
    {                     //确实是有按键动作
      while(SW2 == 0);    //等待按键2松开
      LED6 = ~LED6;
    }
  }
}
/*=====================主函数=========================*/
void main()
{
  InitPort();
  while(1)
  {
    ScanKeys();
  }
}

 

Guess you like

Origin blog.csdn.net/weixin_44643510/article/details/114315442