(一)串口发送
一、实验现象:
开发板实现功能发送
二、实验过程
1、PL2303 USB转串口电路图
2、串口发送
(1)查看用户手册有:
UART0 对应的外部设备 IO 引脚关系为: P0_2 ------ RX
P0_3 ------ TX
UART1 对应的外部设备 IO 引脚关系为: P0_5 ------ RX
P0_4 ------ TX
(2)USART功能特点:
在 CC2540中, UART0和UART1是串行通信接口,它们能够分别运于异步UART模式或者同步SPI模式两个模式。两个UART的功能是一样,可以通过设置在单独的 IO引脚上。
UART 模式的操作具有下列特点:
①8位或者 9位负载数据
②奇校验、偶校验或者无奇偶校验
③配置起始位和停止电平
④配置 LSB 或者 MSB 首先传送
⑤独立收发中断
⑥独立收发 DMA 触发
(3)CC2540配置串口的一般步骤
① 配置 IO,使用外部设备功能。 此处配置 P0_2 和 P0_3用作串口 UART0
② 配置相应串口的控制和状态寄存器。 此处配置 UART0 的工作寄存器
③ 配置串口工作的波特率。 此处配置波特率为115200
(4)寄存器的相关内容:
U0CSR (UART0控制和状态寄存器) |
BIT7:MODE | 0:SPI模式 1:UART模式 |
BIT6:RE | 0:接收器进制 1:接收器使能 | |
BIT5:SLAVE | 0:SPI主模式 1:SPI从模式 | |
BIT4:FE | 0:没有检测到出帧错误 1:收到字节停止位电平出错 |
|
BIT3:ERR | 0:没有检测出奇偶检验出错 1:收到字节奇偶检验出错 |
|
BIT2:RX_BYTE | 0:没有收到字节 1:收到字节就绪 |
|
BIT1:TX_BYTE | 0:没有发送字节 1:写到数据缓冲区寄存器的最后字节已发送 |
|
BIT0:ACTIVE | 0:UART空闲 1:UART忙碌 |
|
U0GCR (UART0通用控制寄存器) |
BIT7:CPOL | 0:SPI负时钟极性 1:SPI正时钟极性 |
BIT6:CPHA | 0:当来自CPOL的SCK反相之后又返回CPOL时,数据输出到 MOSI;当来自CPOL的SCK返回CPOL反相时,输入数据采样到MISO。 1:当来自CPOL的SCK反相之后又返回CPOL时,输入数据采样MOSI;当来自CPOL的SCK返回CPOL反相时,数据输出到 MOSI。 |
|
BIT5:ORDER | 0:LSB先传送 1:MSB先传送 |
|
BIT[4,0]:BAUD_E | 波特率指数值 BAUD_E连同BAUD_M一起决定了UART的波特率 | |
U0BAUD UART0 波特率控制寄存器 |
BIT[7,0]:BAUD_M | 波特率尾数值 BAUD_E连同BAUD_M一起决定了UART的波特率 |
U0DBUF | 串口发送/接受数据缓冲区 | |
UTX0IF 发送中断标志 |
中断标志5IRCON2的BIT1 | 0:中断未挂起 1:中断挂起 |
(5)串口波特率设置
公式如下:
常用波特率设置:
(6)代码实现:
#include#include <string.h> #define uint unsigned int #define uchar unsigned char //定义LED的端口 #define LED1 P1_0 #define LED2 P1_1 //函数声明 void Delay_ms(uint); void initUART(void); void UartSend_String(char *Data,int len); char Txdata[19]; //存放"Hello BlueTooth4.0\n"共19个字符串 /**************************************************************** 延时函数 ****************************************************************/ void Delay_ms(uint n) { uint i,j; for(i=0;i ) for(j=0;j<1774;j++); } void IO_Init() { P1DIR = 0x01; //P1_0,P1_1 IO方向输出 LED1 = 0; } /**************************************************************** 串口初始化函数 ****************************************************************/ void InitUART(void) { PERCFG = 0x00; //位置1 P0口 P0SEL = 0x0c; //P0_2,P0_3用作串口(外部设备功能) P2DIR &= ~0XC0; //P0优先作为UART0 U0CSR |= 0x80; //设置为UART方式 U0GCR |= 11; U0BAUD |= 216; //波特率设为115200 UTX0IF = 0; //UART0 TX中断标志初始置位0 } /**************************************************************** 串口发送字符串函数 ****************************************************************/ void UartSend_String(char *Data,int len) { int j; for(j=0;j ) { U0DBUF = *Data++; while(UTX0IF == 0); UTX0IF = 0; } } /**************************************************************** 主函数 ****************************************************************/ void main(void) { CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振稳定为32M CLKCONCMD &= ~0x47; //设置系统主时钟频率为32MHZ IO_Init(); InitUART(); strcpy(Txdata,"Hello BlueTooth4.0\n"); //将发送内容copy到Txdata; while(1) { UartSend_String(Txdata,sizeof("Hello BlueTooth4.0\n")); //串口发送数据 Delay_ms(500); //延时 LED1=!LED1; //标志发送状态 } }
三、实验成果:
PS:串口驱动,不行去百度下一个,然后更新驱动程序,在列表中选择,直到选到一个能用的。。真是无底坑。
(二)串口接受和发送
一、实验现象:
开发板实现收发
二、实验过程
原理部分同上,直接上源码
#include#include<string.h> //宏定义 #define LED1 P1_0 #define LED2 P1_1 //函数声明 void Delay_ms(unsigned int delay); //延时函数 void IO_init(); //IO配置 void UART_init(); //初始化UART void Send_String(char *Data,int len); //发送字符串函数 //变量声明 char temp=0; //接收到的字符 char Strdata[60]; //存放字符串 //延时函数 void Delay_ms(unsigned int delay) { unsigned int i,j; for(i=delay;i>0;i--) { for(j=0;j<1774;j++); } } //IO配置 void IO_init() { P1SEL=0x00; P1DIR=0X03; P1INP=0X00; LED1=0; LED2=0; } //初始化UART void UART_init() { PERCFG=0X00; //位置一:P0口 P0SEL=0X3c; //P0_2,P0_3,P0_4,P0_5用作第三用途 P2DIR &= ~0XC0; //方向为输入 U0CSR|=0X80; //设置UART方式 U0GCR|=11; U0BAUD|=216; //设置波特率 UTX0IF=0; //清除中断标志位 //用来接收字符 U0CSR |= 0x40; //允许接收 IEN0 |= 0x84; //开总中断,接收中断 } //发送字符串函数 void Send_String(char *Data,int len) { unsigned int i; for(i=0;i ) { //U0DBUF = *Data++; //两种方法都可以 U0DBUF = Data[i]; while(UTX0IF==0); //发送完一个字符后,会产生一个中断。我们通过等待中断产生,来控制传输时间间隔。 UTX0IF = 0; } } void main() { int datanumber = 0; //统计字符长度 int RXTXflag = 1; //接收状态标志变量 CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振稳定 CLKCONCMD &= ~0x47; //设置系统主时钟频率为32MHZ。 IO_init(); //初始化 UART_init(); strcpy(Strdata,"Hello World~\n"); while(1) { if(RXTXflag == 1) //接收状态 { LED1 = 1; //接收状态表示 if(temp!=0) { if((temp!='#')&&(datanumber<50)) //最多接收50个字符,和以#号结束 { Strdata[datanumber++] = temp; } else { RXTXflag=3; //进入发送状态 LED1=0; //关指示灯 } temp=0; } } if(RXTXflag == 3) { LED2=1; //发送状态表示 U0CSR &= ~0X40; //禁止接收 Send_String(Strdata,datanumber); U0CSR |= 0x40; //允许接受 RXTXflag = 1; //恢复到接收状态 datanumber = 0; //指针归0 LED2 = 0; //关发送提示 } } } //一个个拿出发送的字符,使用中断的手段
#pragma vector = URX0_VECTOR __interrupt void fu(void) { URX0IF=0; //清除中断标志 temp=U0DBUF; }
三、实验结果
(三)UART0控制LED
一、实验现象:
开发板实现UARTO控制LED
二、实验过程
原理部分同上,直接上源码
#include#include<string.h> //宏定义 #define LED1 P1_0 #define LED2 P1_1 //函数声明 void Delay_ms(unsigned int delay); //延时函数 void IO_init(); //IO配置 void UART_init(); //初始化UART void Send_String(char *Data,int len); //发送字符串函数 //变量声明 char temp=0; //接收到的字符 char Strdata[60]; //存放字符串 //延时函数 void Delay_ms(unsigned int delay) { unsigned int i,j; for(i=delay;i>0;i--) { for(j=0;j<1774;j++); } } //IO配置 void IO_init() { P1SEL=0x00; P1DIR=0X03; P1INP=0X00; LED1=0; LED2=0; } //初始化UART void UART_init() { PERCFG=0X00; //位置一:P0口 P0SEL=0X3c; //P0_2,P0_3,P0_4,P0_5用作第三用途 P2DIR &= ~0XC0; //方向为输入 U0CSR|=0X80; //设置UART方式 U0GCR|=11; U0BAUD|=216; //设置波特率 UTX0IF=0; //清除中断标志位 //用来接收字符 U0CSR |= 0x40; //允许接收 IEN0 |= 0x84; //开总中断,接收中断 } //发送字符串函数 void Send_String(char *Data,int len) { unsigned int i; for(i=0;i ) { //U0DBUF = *Data++; //两种方法都可以 U0DBUF = Data[i]; while(UTX0IF==0); //发送完一个字符后,会产生一个中断。我们通过等待中断产生,来控制传输时间间隔。 UTX0IF = 0; } } void main() { int datanumber = 0; //统计字符长度 int RXTXflag = 1; //接收状态标志变量 CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振稳定 CLKCONCMD &= ~0x47; //设置系统主时钟频率为32MHZ。 IO_init(); //初始化 UART_init(); while(1) { if(RXTXflag == 1) //接收状态 { if(temp!=0) { if((temp!='#')&&(datanumber<50)) //最多接收50个字符,和以#号结束 { Strdata[datanumber++] = temp; } else { RXTXflag=3; //进入发送状态 } temp=0; } } if(RXTXflag == 3) { if( Strdata[0]=='L') { switch( Strdata[1]-'0') { case 1: LED1=~LED1;break; //低电平点亮 case 2: LED2=~LED2;break; } } RXTXflag = 1; //恢复到接收状态 datanumber = 0; //指针归0 } } } #pragma vector = URX0_VECTOR __interrupt void fu(void) { URX0IF=0; //清除中断标志 temp=U0DBUF; }
三、实验结果