今天我们来讲讲串口通讯,在很多的单片机学习中,串口的学习有是必不可少的,串口有两种:
uart:只支持异步通讯;usart:支持同步和异步通讯;
在通讯过程中,主要依靠三根线,一般来说一根tx,一根rx,还有一根是接地,接收线和发送线很容易理解,那么接地线是为什么?
因为这两根现需要有一个参考,不然的话没有办法交流,比如不再同一个海平面的同一座高山是不一样的;
这是我们的io口功能,其中P0.2 P0.3分别对应这接收线和发送线;
那么如何配置串口呢,我们就以cc2530的usart0来说明;
1、配置gpio:
PERCFG &= ~0x01;//设置USAER0的位置为位置1
P0SEL |= 0x3C;//设置P0的io口2、3为外设功能
从寄存器上可以看到,最后一位可以选择usart0的位置,我们用的是P0.2 P0.3所以用的是备用位置1;将最后一位设置为0即可,我们为了不影响其他位,最好利用与取反等于操作来置为0;如果需要置为1的话就是或等于;
我们使用定时器属于外设功能;所以将P0.2 P0.3置为1;
2、配置UART寄存器:
我们有5个串口寄存器需要配置:
- U0SCR:控制和状态寄存器,我们可以设置接收模式,比如spl、UART;
- U0UCR:控制寄存器,设置奇偶校验;
- U0GCR:通用控制寄存器,可设置波特率指数值;
- U0BUF:缓冲寄存器,我们用来存放我们要发送的数据的;
- U0BAUD:波特率寄存器,设置波特率小数部分的值;
这是我们常用的波特率设置表,分别有上面的U0BAUD、U0GCR控制;
像下面就可以设置波特率为9600;
U0GCR = 8;
U0BAUD = 59;
对于U0CSR,我们使能接收器并且使用UART模式即可:
U0CSR |= 0xC0;
而U0UCR 我们可以设计一个可以传入波特率和就校验的初始化函数,来灵活的设置波特率和奇偶校验:
//校验逻辑函数
//其中p是传参,baud也是
if(p != 'n' || p != 'N')
{
//默认设置为偶检验
U0UCR |= 0X38;
if(p == 'o' || p == 'O')
{
//设置为奇校验
U0UCR &= ~0X20;
}
}
//波特率初始化
U0GCR &= ~0x1F;
switch(baud)
{
case 2400:
U0BAUD=59;
U0GCR=6;
break;
case 4800:
U0BAUD=59;
U0GCR=7;
break;
case 9600:
U0BAUD=59;
U0GCR=8;
break;
case 115200:
U0BAUD=216;
U0GCR=11;
break;
default:
//如果用户传入数值超过范围,则默认为9600
U0BAUD=59;
U0GCR=8;
break;
}
3、配置中断:
由于本期不需要用到,我们下期再讲;
总之,我们在做任何的单片机串口初始化的时候,从上面三个步骤思考没有问题;
4、发送的原理:
我们发送也很简单,就利用查询法试一试,下次在看看中断:
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*函数名:UartSend
*参数:*buf 要发送的数据 len 发送数据的长度
*返回:none
*描述:串口发送数据
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void UartSend(unsigned char *buf,unsigned int len)
{
//2.1 查询法发送数据
unsigned int i = 1;
for(;i < len;i++)
{
//将数据存入缓冲区
U0DBUF = buf[i];
//判断字符发送情况
while(!(U0CSR & 0x02));
//发送完成后将发送完成位置为0
U0CSR &= ~0x02;
}
}
我们要注意的是,发送一个字节数据需要判断是否发完,因为发数据很快,我们需要判断才不容易丢失数据,而发送完之后需要我们手动将U0CSR的发送完成状态位置为0;
发送数据一般以数组的形式,然后将数组元素一个一个存到缓冲区即可;
好了,就这么些,由于内容较多,就只能分几次讲;