• 串口


    串口相关实验

    1、串口

    串口即串行通信接口,CC2530有两个串行通信接口:USART0

    和USART1。两个USART具有相同的功能,可以通过设置相应

    的寄存器来决定选用哪一个串口。它们能够分别运行于异步 USART 模式或者同步 SPI 模式。

    USART0 对应的外部设备 IO 引脚关系为: P0_2 —— RX

    P0_3 —— TX

    USART1 对应的外部设备 IO 引脚关系为: P0_5 —— RX

    P0_4 —— TX

    TX:发送数据

    RX:接收数据

    2、串口发送:CC2530向PC发送内容

    (1)CC2530 配置串口的一般步骤

    在本次实验中,我们用到的是UART0 。

    1 、 配置 IO, 使用外部设备功能。 此处配置 P0_2 和 P0_3 用作串口 USART0,参考下图

    img

    2 、 配置相应串口的控制和状态寄存器。此处配置 USART0 的工作寄存器

    3 、 配置串口工作的波特率。此处配置为波特率为 115200。寄存器设置参考下表

    img

    (2)与串口配置相关的寄存器

    1)PERCFG

    它是外设I/O寄存器之一,称作:外设控制寄存器。它用来控制外设功能的备用位置。(备用位置:串口在I/O端口中有对应的位置。比如USART0当使用UART模式时,备用位置1根据映射表就知道,使用的是P0_2 P0_3端口来实现接收和发送数据的,其中P0_2对应TX,其中P0_3对应RX。)并且它是一个八位的寄存器,它的第0位是负责USART0 I/O控制。0:表示备用位置1 1:表示备用位置2。

    例:串口0备用位置设置。

    /设置串口0位备用位置1/

    PERCFG &=~ 0x01;

    2)P0SEL

    它是一个八位功能寄存器。用来设置P0端口的每个引脚为通用I/O或者外设I/O。当某个引脚作为串口时就是外设功能。

    3)P2DIR

    它是一个八位方向寄存器,设置端口2。它除了设置端口P2_0~P2_4输出/输入方向之外,第6位和第7位还可以用来决定串口的优先级别。当串口0、串口1和定时器1共同使用CC2530的某些引脚时就需要设置其优先级别。

    例:串口0优先级别设置

    /设置串口0为第一优先级别/

    P2DIR &=~0XC0;//0000 0000

    4)U0CSR

    八位寄存器。串口0的控制和状态寄存器。可以用来选择串口模式。它的第7位主要负责串口模式选择。

    7:

    0:选择SPI模式

    1:选择UART模式

    例:U0CSR寄存器配置

    /UART方式/

    U0CSR|=0x80;

    5)U0GCR、U0BAUD

    都是八位寄存器。U0GCR是串口0的通用控制寄存器。U0BAUD是串口0的波特率控制寄存器。它们通常是搭配使用来设置串口的波特率。波特率的计算公式:

    通过寄存器U0GCR的4~0位的设置来决定BAUD_E 值,通过寄存器U0BAUD的7~0位的设置来决定 BAUD_M的值。

    6)UTX0IF

    USART0发送完成中断标志。

    2. 相关代码

    串口通讯(HELLO WEBEE)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117


    #include <string.h>

    #define uint unsigned int

    #define uchar unsigned char



    #define LED1 P1_0

    #define LED2 P1_1

    char Txdata[14]; //存放"HELLO WEBEE "共14个字符串

    void ()

    {

    CLKCONCMD = 0x88; // 系统时钟源采用外部32M晶振,主时钟为32M

    while(CLKCONSTA & 0x40); // 等待主时钟稳定

    }

    void Config_GPIO()

    {

    P1DIR |= 0x03; //P1_0定义为输出

    P1INP |= 0X01; //打开下拉三态输出

    LED1=0;

    LED2=0;

    }

    void Delay(unsigned int k)

    {

    for(unsigned int i = k; i > 0; i --)

    for(unsigned int j = 587; j >0; j --);

    }

    void Config_UART0_TX()

    {

    // CC2530发送数据给PC

    PERCFG = 0x00; //位置1 P0口

    P0SEL = 0x0c; //P0_2,P0_3用作串口(外部设备功能)

    P2DIR &= ~0XC0; //P0优先作为UART0

    U0CSR = 0x80; // 串口0工作方式

    U0UCR = 0x02; // UART控制寄存器

    U0GCR = 11; // 通用寄存器

    U0BAUD = 216; // 波特率,该波特率是用在32M晶振输出

    }

    void UART0_TX_String(char * txData,char num) // 发送字符串

    {

    int j;

    for(j=0;j<len;j++)

    {

    U0DBUF = *txData++;

    while(UTX0IF == 0);

    UTX0IF = 0;

    }

    }

    void main(void)

    {

    Config_32M_Clock();

    Config_GPIO();

    Config_UART0_TX();

    strcpy(Txdata,"HELLO WEBEE "); //将发送内容copy到Txdata;

    while(1)

    {

    UART0_TX_String(Txdata,sizeof("HELLO WEBEE "));

    Delay(500); //延时

    LED1=!LED1; //标志发送状态

    }

    }

    然后将代码烧写进入实验板,串口设置如下。然后在 IAR中点击GO,就会出现下面的界面

    img

    串口通讯(send & receive)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76大专栏  串口span>
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137


    #include <string.h>

    #define uint unsigned int

    #define uchar unsigned char



    //定义控制LED灯的端口

    #define LED1 P1_0 //定义LED1为P10口控制

    #define LED2 P1_1



    char Rxdata[50];

    char temp;

    uchar RXTXflag = 1;

    uchar datanumber = 0;

    #define len 10

    char bufferedData[len] = {0};

    void ()

    {
    CLKCONCMD = 0x88; // 系统时钟源采用外部32M晶振,主时钟为32M
    while(CLKCONSTA & 0x40); // 等待主时钟稳定
    }

    void Config_GPIO()

    {

    P1DIR |= 0x03; //P1_0定义为输出

    P1INP |= 0X01; //打开下拉三态输出



    LED1=0;

    LED2=0;

    }

    void Config_UART0_TX()

    {

    // CC2530发送数据给PC

    PERCFG = 0x00; //位置1 P0口

    P0SEL = 0x0c; //P0_2,P0_3用作串口(外部设备功能)

    P2DIR &= ~0XC0; //P0优先作为UART0



    U0CSR = 0x80; // 串口0工作方式

    U0UCR = 0x02; // UART控制寄存器

    U0GCR = 11; // 通用寄存器

    U0BAUD = 216; // 波特率,该波特率是用在32M晶振输出

    }

    void Config_UART0_RX()

    {

    // CC2530接收来自PC的数据

    EA = 1; // 总中断

    URX0IE = 1; // 串口0接收中断

    IT1 = 1; // 总是置1

    U0CSR |= 0x40; // 允许接收

    }

    void main(void)

    {

    Config_32M_Clock();

    Config_GPIO(); //调用初始化函数

    Config_UART0_TX();

    Config_UART0_RX();

    while(1)

    {
    if(RXTXflag == 1) //接收状态
    {
    LED1=1; //接收状态指示
    if( temp != 0)
    {
    if((temp!='#')&&(datanumber<50)) //'#'被定义为结束字符,最多能接收50个字符
    Rxdata[datanumber++] = temp;
    else
    {
    RXTXflag = 3; //进入发送状态
    LED1=0; //关指示灯
    }
    temp = 0;
    }
    }
    if(RXTXflag == 3) //发送状态
    {
    LED2= 1;
    U0CSR &= ~0x40; //禁止接收
    Uart_Send_String(Rxdata,datanumber); //发送已记录的字符串。

    U0CSR |= 0x40; //允许接收
    RXTXflag = 1; // 恢复到接收状态
    datanumber = 0; //指针归0
    LED2 = 0; //关发送指示
    }
    }

    }

    其中RXTXflag只是作为一个表示是发送还是接收状态的标志

    本实验需要使用中断

    我们参考手册

    img

    利用第三节外部中断的知识我们可以知道串口接收的配置为

    img

    中断处理函数为

    PS:一定要记得清除中断标志位

    对本次试验的一些理解

    一开始程序从main函数开始执行,一直执行到程序的最后接受区都没有任何内容显示。直到我们在串口调试助手中点击“手动发送”(这个行为其实就表明有数据从串口传至CC2530),这实际上是一个触发中断事件,则接下来会进入中断,执行中断函数。这一个中断函数的最终结果就是将temp有了不为零的值。此时程序从while(1)开始执行,就会出现现象。

    UART0-控制LED

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    void main(void)

    {

    InitLed();//调用初始化函数

    InitUart();

    while(1)

    {

    if(RXTXflag == 1) //接收状态

    {

    if( temp != 0)

    {

    /*

    '#'被定义为结束字符,

    最多能接收50个字符

    */

    if((temp!='#')&&(datanumber<3))

    Rxdata[datanumber++] = temp;

    else

    {

    RXTXflag = 3; //进入发送状态

    }
    temp = 0;
    }
    }
    if(RXTXflag == 3) //检测接收到的数据
    {
    if(Rxdata[0]=='L')
    /*
    很重要,ASICC码转成数字,
    判断L后面第一个数
    */
    switch(Rxdata[1]-48)
    {
    case 1:
    {
    LED1=~LED1; //低高平点亮
    break;
    }
    case 2:
    {
    LED2=~LED2;
    break;
    }
    }
    RXTXflag = 1;
    datanumber = 0; //指针归 0
    }
    }

    }

    只写出了main函数部分 ,因为其余部分没有区别只是把CC2530向PC发数据改成了根据接收的数据来使LED亮起来

    小测试

    通过输入LED使两个LED都亮起来

    提示:引入一个字符串比较函数,比较输入的字符串是不是LED。

  • 相关阅读:
    ASP.NET 2.0个性化配置(profile)
    03 创建虚拟机
    一些新的Blender的视频教程
    [转载]虚拟家庭存档文件修改方法
    [转载]游戏开发中常用的设计模式
    批处理for命令详解(转)
    [转载]高效软件开发团队的特征
    软件构架师的特点
    一点SICP(Structure and Interpretation of Computer Programs) 资料 (转载加整理)
    [译]游戏编程入门(by David Astle)
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12376398.html
Copyright © 2020-2023  润新知