Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

Introduction to serial port protocols

Serial port transmission protocol is a common transmission protocol in embedded development. The most common way used in the development stage is to print the debugging information of MCU to the PC serial terminal for display, which is convenient for debugging errors.

There are two common transmission protocols: parallel port and serial port.

Parallel port transmission protocol: Data bits are sent or received simultaneously, using a separate wire for each data bit. Transmission speed, high efficiency, but need more data lines, high cost.

Serial port transfer protocol: The sequential sending or receiving of data bit by bit. Less data line is required, low cost, but the transmission speed is slow, low efficiency.

CC2530 has two serial communication interfaces, USART0 and USART1, which can be configured into asynchronous UART mode or synchronous SPI mode.

The two USART interfaces have the same function. The mapping between the external I/O pins of the two USART interfaces can be set using the PERCFG register:

location1: RX0 -- P0_2 TX0 -- P0_3 RX1 -- P0_5 TX1 -- P0_4 position2: RX0 - P1_4 TX0 - P1_5 RX1 - P1_7 TX1 - P1_6Copy the code

Programming for each USART serial communication, essentially setting the relevant 5 registers:

<1> UxCSR: control and status registers for USARTx. <2> UxUCR: the UART control register of USARTx. <3> UxGCR: general purpose control register of USARTx. <4> UxDBUF: the receive/send data buffer register of USARTx. <4> UxBAUD: the baud rate control register of USARTx.Copy the code

When communicating with PC through serial port, USB to TTL chip is usually needed for voltage conversion. Therefore, before learning serial programming, first understand two levels: TTL level and RS232 level

TTL level: logic0- less than0.8V logic1- more than2.4V. RS232 level: logic0---- 5~15V logic1---- - 5~- 15V.Copy the code

During serial communication, the speed is expressed by baud rate.

The common baud rate Settings are as follows:

The baud rate of CC2530 is determined by BAUD_E and BAUD_M together:

2. Schematic diagram data manual analysis

Serial port configuration code examples

3.1 Write the serial port initialization function to realize serial port string sending (CPU frequency is 16MHZ, baud rate is 9600)


#include <ioCC2530.h>
#include <string.h>

// Define the LED light port
#define LED1 P1_2
#define LED2 P1_3

// Define the port for the KEY
#define KEY1 P1_0       // Define the key as P1_0 port control
#define KEY2 P1_1       // Define the button as port P1_1 control

/* Initialize hardware connection: LED1-->P1_2, LED2-->P1_3 */
void LED_Init(void)
{
    P1DIR |=0x3<<2;  // Set P1_2 and P1_3 as output modes
    LED1 = 1;
    LED2 = 1;
}

/* Key IO port initialization hardware connection: KEY1-->P1_0 KEY2-->P1_1 */
void KEY_Init(void)
{
    P1SEL&=~(0x3<<0); // Configure P1_0 so that P1_1 is in general GPIO port mode
    P1DIR&=~(0x3<<0); // Set P1_0 with P1_1 as the input mode
    P1INP|= 0x3<<0;   / /
}


void delay10ms(void)   / / error 0 us
{
    unsigned char a,b,c;
    for(c=193; c>0; c--)for(b=118; b>0; b--)for(a=2; a>0; a--); }/* Function function: key scan return value: pressed key value */
unsigned char Key_Scan(void)
{
    static unsigned char stat=1;
    if((KEY1==0||KEY2==0)&&stat)
    {
       stat=0;
       delay10ms(a);if(KEY1==0)return 1;
       if(KEY2==0)return 2;
    }
    else
    {
        if(KEY1&&KEY2)stat=1;
    }
    return 0;
}

/* Initialize serial port 0 */
void Init_Uart0(void)
{
  PERCFG&=~(1<<0);  // The pins of serial port 0 are mapped to positions 1, P0_2 and P0_3
  P0SEL|=0x3<<2;   // Set ports P0_2 and P0_3 to peripheral function
  U0BAUD = 59;     // a 16MHz system clock generates 9600BPS baud rate
  U0GCR&=~(0x1F<<0);// Clear the baud rate index
  U0GCR|=9<<0;      // Set the baud rate index value
  U0UCR |= 0x80;    // Disable flow control, 8-bit data, clear buffer
  U0CSR |= 0x3<<6;  // Select UART mode to enable the receiver
}

/* Function function: UART0 sends a string function */
void UR0SendString(char *str,unsigned int len)
{
  int j;
  for(j=0; j<len; j++) { U0DBUF = *str++;// 1 byte of data to be sent is written to U0DBUF
    while(UTX0IF == 0);// Wait for data to be sent
    UTX0IF = 0;       // Clear the send complete flag, ready for the next send}}/* Main function */
void main(void)
{
    char buff[]="-----CC2530 embedded development -----\r\n";
    unsigned char key;
    LED_Init(a);// Initializes the LED control IO port
    KEY_Init(a);// Key initialization
    Init_Uart0(a);// Initialize serial port 0
    while(1)          
    {  
       key=Key_Scan(a);if(key)
       {
          // Send a string to test whether serial port 0 data transfer is correct
          UR0SendString(buff,strlen(buff));
          LED1 = !LED1;     
          LED2 = !LED2;
       }       
    }
}


Copy the code

3.2 Write the serial port initialization function to send serial string (CPU frequency is 16MHZ, baud rate is 115200)


#include <ioCC2530.h>
#include <string.h>

// Define the LED light port
#define LED1 P1_2
#define LED2 P1_3

// Define the port for the KEY
#define KEY1 P1_0       // Define the key as P1_0 port control
#define KEY2 P1_1       // Define the button as port P1_1 control

/* Initialize hardware connection: LED1-->P1_2, LED2-->P1_3 */
void LED_Init(void)
{
    P1DIR |=0x3<<2;  // Set P1_2 and P1_3 as output modes
    LED1 = 1;
    LED2 = 1;
}

/* Key IO port initialization hardware connection: KEY1-->P1_0 KEY2-->P1_1 */
void KEY_Init(void)
{
    P1SEL&=~(0x3<<0); // Configure P1_0 so that P1_1 is in general GPIO port mode
    P1DIR&=~(0x3<<0); // Set P1_0 with P1_1 as the input mode
    P1INP|= 0x3<<0;   / /
}


void delay10ms(void)   / / error 0 us
{
    unsigned char a,b,c;
    for(c=193; c>0; c--)for(b=118; b>0; b--)for(a=2; a>0; a--); }/* Function function: key scan return value: pressed key value */
unsigned char Key_Scan(void)
{
    static unsigned char stat=1;
    if((KEY1==0||KEY2==0)&&stat)
    {
       stat=0;
       delay10ms(a);if(KEY1==0)return 1;
       if(KEY2==0)return 2;
    }
    else
    {
        if(KEY1&&KEY2)stat=1;
    }
    return 0;
}

/* Initialize serial port 0 */
void Init_Uart0(void)
{
  PERCFG&=~(1<<0);  // The pins of serial port 0 are mapped to positions 1, P0_2 and P0_3
  P0SEL|=0x3<<2;   // Set ports P0_2 and P0_3 to peripheral function
  U0BAUD = 216;     // a 16MHz system clock generates 115,200 BPS baud rate
  U0GCR&=~(0x1F<<0);// Clear the baud rate index
  U0GCR|=12<<0;      // a 16MHz system clock generates 115,200 BPS baud rate
  U0UCR |= 0x80;    // Disable flow control, 8-bit data, clear buffer
  U0CSR |= 0x3<<6;  // Select UART mode to enable the receiver
}

/* Function function: UART0 sends a string function */
void UR0SendString(char *str,unsigned int len)
{
  int j;
  for(j=0; j<len; j++) { U0DBUF = *str++;// 1 byte of data to be sent is written to U0DBUF
    while(UTX0IF == 0);// Wait for data to be sent
    UTX0IF = 0;       // Clear the send complete flag, ready for the next send}}/* Main function */
void main(void)
{
    char buff[]="----- Wanbang Easy embedded development -----\r\n";
    unsigned char key;
    LED_Init(a);// Initializes the LED control IO port
    KEY_Init(a);// Key initialization
    Init_Uart0(a);// Initialize serial port 0
    while(1)          
    {  
       key=Key_Scan(a);if(key)
       {
          // Send a string to test whether serial port 0 data transfer is correct
          UR0SendString(buff,strlen(buff));
          LED1 = !LED1;     
          LED2 = !LED2;
       }       
    }
}

Copy the code

3.3 Configuring the Serial Port To Interrupt Receiving Data

#include <ioCC2530.h>
#include <string.h>

// Define the LED light port
#define LED1 P1_2
#define LED2 P1_3

// Define the port for the KEY
#define KEY1 P1_0       // Define the key as P1_0 port control
#define KEY2 P1_1       // Define the button as port P1_1 control

unsigned char dataRecv;
unsigned char Flag = 0;

/* Initialize hardware connection: LED1-->P1_2, LED2-->P1_3 */
void LED_Init(void)
{
    P1DIR |=0x3<<2;  // Set P1_2 and P1_3 as output modes
    LED1 = 1;
    LED2 = 1;
}

/* Key IO port initialization hardware connection: KEY1-->P1_0 KEY2-->P1_1 */
void KEY_Init(void)
{
    P1SEL&=~(0x3<<0); // Configure P1_0 so that P1_1 is in general GPIO port mode
    P1DIR&=~(0x3<<0); // Set P1_0 with P1_1 as the input mode
    P1INP|= 0x3<<0;   / /
}


void delay10ms(void)   / / error 0 us
{
    unsigned char a,b,c;
    for(c=193; c>0; c--)for(b=118; b>0; b--)for(a=2; a>0; a--); }/* Function function: key scan return value: pressed key value */
unsigned char Key_Scan(void)
{
    static unsigned char stat=1;
    if((KEY1==0||KEY2==0)&&stat)
    {
       stat=0;
       delay10ms(a);if(KEY1==0)return 1;
       if(KEY2==0)return 2;
    }
    else
    {
        if(KEY1&&KEY2)stat=1;
    }
    return 0;
}

/* Initialize serial port 0 */
void Init_Uart0(void)
{
  PERCFG&=~(1<<0);  // The pins of serial port 0 are mapped to positions 1, P0_2 and P0_3
  P0SEL|=0x3<<2;   // Set ports P0_2 and P0_3 to peripheral function
  U0BAUD = 216;     // a 16MHz system clock generates 115,200 BPS baud rate
  U0GCR&=~(0x1F<<0);// Clear the baud rate index
  U0GCR|=12<<0;      // a 16MHz system clock generates 115,200 BPS baud rate
  U0UCR |= 0x80;    // Disable flow control, 8-bit data, clear buffer
  U0CSR |= 0x3<<6;  // Select UART mode to enable the receiver
  UTX0IF = 0;       // Clear the TX send interrupt flag
  URX0IF = 0;       // Clear the RX receive interrupt flag
  URX0IE = 1;       // Enable URAT0 receive interrupt
  EA = 1;           // Enable total interrupt
}



/* Function function: UART0 sends a string function */
void UR0SendString(char *str,unsigned int len)
{
  int j;
  for(j=0; j<len; j++) { U0DBUF = *str++;// 1 byte of data to be sent is written to U0DBUF
    while(UTX0IF == 0);// Wait for data to be sent
    UTX0IF = 0;       // Clear the send complete flag, ready for the next send}}/*================UR0 receive interrupt service function ================*/
#pragma vector = URX0_VECTOR
__interrupt void UART0_RecvInterrupt(a)
{
  URX0IF = 0;           // Clear the RX receive interrupt flag
  dataRecv =  U0DBUF;   // Read data from the receive buffer
  Flag = 1;             // Set the receive command flag
}


/*================ Execute the host's command =================*/
void ExecuteTheOrder(a)
{
  Flag = 0 ;            // Clear the receive instruction flag
  switch(dataRecv)
  {
    case 'A':
      UR0SendString("Option 1! \r\n".9);
      break;
    case 'B':
      UR0SendString("Select 2! \r\n".9);
      break;
    case 'C':
      UR0SendString("Choose 3! \r\n".9);
      break;
    case 'D':
      UR0SendString("Select 4! \r\n".9);
      break; }}/* Main function */
void main(void)
{
    char buff[]="----- Embedded development -----\r\n";
    unsigned char key;
    LED_Init(a);// Initializes the LED control IO port
    KEY_Init(a);// Key initialization
    Init_Uart0(a);// Initialize serial port 0
    while(1)          
    {
       key=Key_Scan(a);if(key)
       {
          // Send a string to test whether serial port 0 data transfer is correct
          UR0SendString(buff,strlen(buff)); LED2 = ! LED2; }if(Flag == 1)      // Check whether the host command is received
      {
        ExecuteTheOrder(a); }}}Copy the code