一.串口通讯
有问题发送邮件至468078841@qq.com
(一)串口概念
串行接口是一种可以将接收来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接收的串行数据流转换为并行的数据字符供给CPU的器件。一般完成这种功能的电路,我们称为串行接口电路。串口是计算机上一种非常通用的设备通信协议。大多数计算机(不包括笔记本电脑)包含两个基于RS-232的串口。串口同时也是仪器仪表设备通用的通信协议;很多GPIB兼容的设备也带有RS-232口。同时,串口通信协议也可以用于获取远程采集设备的数据
(二)通信方式
1.单工:
数据传输只支持数据在一个方向上传输;在同一时间只有一方能接受或发送信息,不能实现双向通信,举例:电视,广播。
2.半双工:
半双工数据传输允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;在同一时间只可以有一方接受或发送信息,可以实现双向通信。举例:对讲机。
3.全双工:
全双工数据通信允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力;在同一时间可以同时接受和发送信息,实现双向通信,举例:电话通信。
二.串口通讯参数
(一)波特率
这是一个衡量符号传输速率的参数。指的是信号被调制以后在单位时间内的变化,即单位时间内载波参数变化的次数,如每秒钟传送240个字符,而每个字符格式包含10位(1个起始位,1个停止位,8个数据位),这时的波特率为240Bd,比特率为10位*240个/秒=2400bps。一般调制速率大于波特率,比如曼彻斯特编码)。通常电话线的波特率为14400,28800和36600。波特率可以远远大于这些值,但是波特率和距离成反比。高波特率常常用于放置的很近的仪器间的通信,典型的例子就是GPIB设备的通信。
(二)数据位
这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据往往不会是8位的,标准的值是6、7和8位。如何设置取决于你想传送的信息。比如,标准的ASCII码是0~127(7位)。扩展的ASCII码是0~255(8位)。如果数据使用简单的文本(标准 ASCII码),那么每个数据包使用7位数据。每个包是指一个字节,包括开始/停止位,数据位和奇偶校验位。由于实际数据位取决于通信协议的选取,术语“包”指任何通信的情况。
(三)停止位
用于表示单个包的最后一位。典型的值为1,1.5和2位。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。
(四)奇偶校验位
在串口通信中一种简单的检错方式。有四种检错方式:偶、奇、高和低。当然没有校验位也是可以的。对于偶和奇校验的情况,串口会设置校验位(数据位后面的一位),用一个值确保传输的数据有偶个或者奇个逻辑高位。例如,如果数据是011,那么对于偶校验,校验位为0,保证逻辑高的位数是偶数个。如果是奇校验,校验位为1,这样就有3个逻辑高位。高位和低位不真正的检查数据,简单置位逻辑高或者逻辑低校验。这样使得接收设备能够知道一个位的状态,有机会判断是否有噪声干扰了通信或者是否传输和接收数据是否不同步。
三cc2530串口及其引脚
(一)引脚的确定
CC2530有两个串行通信接口USART0和USART1,它们能够分别运行于异步UART模式或者同步SPI模式。
两个USART接口具有相同的功能,通过PERCFG寄存器可以设置两个USART接口对应外部I/O引脚的映射关系:
位置1:RX0 — P0_2 TX0 — P0_3 RX1 — P0_5 TX1 — P0_4
位置2:RX0 — P1_4 TX0 — P1_5 RX1 — P1_7 TX1 — P1_6
(二)波特率的选择
指数寄存器 U0GCR 可以直接赋值
小数部分U0BAUD
例如波特率19200;
U0BAUD = 0x3B; //波特率
U0GCR = 0x09;
、
(三)U0SCR:USART 0 控制与状态
这里我们选择UART模式,
U0CSR |= 0x80;
U0CSR |= 0X40; //打开接受使能
(四)UOUCR UAR控制与状态
这里为了方便演示全部禁止
U0UCR |= 0x80;
(五)中断开关汇总
串口中断相关的配置
UTX0IF; //TX发送中断标志
URX0IF; //RX接收中断标志
URX0IE ; //URAT0的接收中断
EA ; //总中断
1使能 0禁止
注意
当USART 的发送/接收数据缓冲寄存器UxDBUF被写入数据时,该字节就会发送到TXD引脚,
接受的为U0DBUF到TXD引脚
四.代码实战区
要求串口1 UART模式 波特率115200,不需要其他参数,当接收到open灯全亮 接收到stop灯全灭 blink灯闪烁,发死其他的消息 cc2530像PC发送wrong conmond
#include "ioCC2530.h"
#include <string.h>
#include <stdio.h>
#define LED1 P1_0
#define LED2 P1_1
#define LED3 P1_3
#define LED4 P1_4
static int data = 0;
static int DATE = 0;
const char *o = "open\r\n";
const char *s = "stop\r\n";
const char *b = "blink\r\n";
char *buff1 = "wrong conmond";
char *temp = "\0";
char buff[256]; //数据缓冲区
void IO_INIT()
{
P1SEL &= ~0x1B;
P1DIR |= 0x1B ;
P1 &= ~0x1B;
CLKCONCMD &= 0x80;
}
void delay(int x)
{
for(int i = 0;i<=x;i++)
{
for(int j = 0;j<=255;j++)
{
}
}
}
void initUART0(void)
{
PERCFG = 0x00;
P0SEL = 0x3c; //P0 用作串口, P0.2、P0.3、P0.4、P0.5作为片内外设I/O
U0BAUD = 0x3B; //波特率
U0GCR = 0x09;
U0CSR |= 0x80;
U0UCR |= 0x80;
URX0IF = 0;
U0CSR |= 0X40;
UTX0IF = 0; //清除RX接收中断标志开启第一次接受
URX0IE = 1; //使能URAT0的接收中断
EA = 1; //开总中断监测
}
void LED_BLINK() //闪烁函数
{
P1 |= 0x0B;
delay(1000);
P1 &= ~0x0B;
delay(1000);
}
void UART0SendByte(char c) //发送给字节函数
{
U0DBUF = c; //传入C 把c传给寄存器U0DBUF
while (!UTX0IF);
UTX0IF = 0;
}
void UART0SendString(char *str) //发送字符串函数
{
while(1)
{
if(*str == '\0') break; //在字符串解为为'\0'
UART0SendByte(*str++);
}
}
void receive_handler(void) //写的接受中断函数
{
buff[data] =U0DBUF;
if(buff[data] == '\n')
{
U0CSR &=~0x40;
DATE = 0;
if(strcmp(buff,s) == 0) //在这里比较成功返回0
{
LED1 = 0;
}
else if(strcmp(buff,o) == 0) //在这里比较成功返回0
{
LED1 = 1;
}
else if(strcmp(buff,b) == 0) //在这里比较成功返回0
{
DATE = 1;
}
else{
UART0SendString(buff1);
}
U0CSR |=0x40;
memset(buff,'\0',data);
data = 0;
}
else data++;
}
#pragma vector=URX0_VECTOR
__interrupt void URX0_ISR(void)
{
URX0IF = 0;//清除RX接收中断标志准备下一次接受
receive_handler(); //接受处理函数
}
void main(void)
{
IO_INIT();
initUART0();
while(1)
{
if(DATE == 1)
{
LED_BLINK();
}
}
}