文章目录
- 串口的编程技巧
- 发送函数分析
- 串口(UART0)初始化函数
- 主函数体
- 完整代码:
- TIPS1:IAR显示行号
- TIPS2:IAR编译出现 Fatal Error[e72]: Segment BANKED_CODE must be defined
- 解决方法:
- 串口的数据格式
串口的编程技巧
发送函数分析
void UartSendString(char *Data,int len)
{
uint i;
for(i = 0;i<len;i++)
{
U0DBUF = *Data++;
while(UTX0IF == 0)
{
UTX0IF = 0;
}
}
}
检测UTX0IF标志,只要为0,就一直死等;等到标志变成1的时候退出。
这就是所谓串口的查询工作方式:在上一步向发送缓冲区填写数据触发发送之后,在这里死等发送(完成)标志置位。
有些单片机可以查询更细致的标志,例如发送缓冲空标志、线路发送完成标志等等。
串口(UART0)初始化函数
/****************************************************************
串口(UART0)初始化函数:
****************************************************************/
void InitUart(unsigned long int baudrate)
{
CLKCONCMD &= ~0x40; //0: 32 MHz XOSC 与操作,仅设置0位,其他位为1,与后保持不变,设置系统时钟源为32MHZ晶振
while(CLKCONSTA & 0x40); //等待晶振稳定
CLKCONCMD &= ~0x47; // ~0x47=1011 1000,2:0 CLKSPD 001 R/W Clock speed. Cannot be higher than system clock setting given by the OSC bit
//setting. Indicates current system-clock frequency 000: 32 MHz,设置系统主时钟频率为32MHZ
PERCFG = 0x00; //位外设控制寄存器USART 0的IO位置;0为P0口位置;
P0SEL = 0x0c; //P0用作串口,P0.7 to P0.0 function select
//0: General-purpose I/O 1: Peripheral function
//0x0c=0000 1100,P0_2,P0_3用作串口,外设功能
P2DIR &= ~0XC0; //0XC0=1100 0000,~0XC0=0011 1111,与操作,设置0位,P0优先作为UART0
//Port 0 peripheral priority control. These bits determine the order of priority in the case
//when PERCFG assigns several peripherals to the same pins.
//Detailed priority list:
//00:
//1st priority: USART 0
//2nd priority: USART 1
//3rd priority: Timer 1
U0CSR |= 0X40; //允许接收
switch(baudrate)
{
case 115200:
U0GCR = 11;
U0BAUD = 216; //波特率设为115200
break;
case 9600:
U0GCR = 8;
U0BAUD = 59; //波特率设为9600
break;
default:
U0GCR = 8;
U0BAUD = 59; //默认波特率设为9600
break;
}
UTX0IF = 0;
U0CSR |= 0x40; //允许接收
IEN0 |= 0x84; //开总中断,允许接收中断
}
主函数体
/****************************************************************
主函数
****************************************************************/
void main(void)
{
InitUart(115200); //串口初始化
InitLed();
UartState = UART0_RX; //串口0默认处于接收模式
memset(RxData, 0, SIZE);
while(1)
{
CmdPro(cmd);
}
}
完整代码:
#include <ioCC2540.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char
//定义控制灯的端口
#define LED1 P1_0 //P1_0口控制LED1
#define UART0_RX 1
#define UART0_TX 2
#define SIZE 51
char RxBuf;
char UartState;
uchar count;
char RxData[SIZE]; //存储发送字符
char cmd;
uint OnOffState;
void DelayMS(uint msec)
{
uint i,j;
for (i=0;i<msec; i++)
for (j=0;j<1070;j++);
}
void InitLed(void)
{
P1DIR |= 0x01; //0x01=0000 0001 置1,或操作, 定义P1.0为输出
LED1 = 0; //LED1灯灭
}
void CmdPro(char MyCmd)
{
switch(MyCmd)
{
case 'A':
cmd = 0;
LED1 = 1;
OnOffState = 1;
break;
case 'B':
cmd = 0;
LED1 = 0;
OnOffState = 0;
break;
case 'C':
if(OnOffState)
{
LED1 = 0;
DelayMS(1000);
LED1 = 1;
DelayMS(1000);
LED1 = 0;
DelayMS(1000);
LED1 = 1;
DelayMS(1000);
LED1 = 0;
OnOffState = 0;
}
break;
default:
break;
}
}
/****************************************************************
串口(UART0)初始化函数:
****************************************************************/
void InitUart(unsigned long int baudrate)
{
CLKCONCMD &= ~0x40; //0: 32 MHz XOSC 与操作,仅设置0位,其他位为1,与后保持不变,设置系统时钟源为32MHZ晶振
while(CLKCONSTA & 0x40); //等待晶振稳定
CLKCONCMD &= ~0x47; // ~0x47=1011 1000,2:0 CLKSPD 001 R/W Clock speed. Cannot be higher than system clock setting given by the OSC bit
//setting. Indicates current system-clock frequency 000: 32 MHz,设置系统主时钟频率为32MHZ
PERCFG = 0x00; //位外设控制寄存器USART 0的IO位置;0为P0口位置;
P0SEL = 0x0c; //P0用作串口,P0.7 to P0.0 function select
//0: General-purpose I/O 1: Peripheral function
//0x0c=0000 1100,P0_2,P0_3用作串口,外设功能
P2DIR &= ~0XC0; //0XC0=1100 0000,~0XC0=0011 1111,与操作,设置0位,P0优先作为UART0
//Port 0 peripheral priority control. These bits determine the order of priority in the case
//when PERCFG assigns several peripherals to the same pins.
//Detailed priority list:
//00:
//1st priority: USART 0
//2nd priority: USART 1
//3rd priority: Timer 1
U0CSR |= 0X40; //允许接收
switch(baudrate)
{
case 115200:
U0GCR = 11;
U0BAUD = 216; //波特率设为115200
break;
case 9600:
U0GCR = 8;
U0BAUD = 59; //波特率设为9600
break;
default:
U0GCR = 8;
U0BAUD = 59; //默认波特率设为9600
break;
}
UTX0IF = 0;
U0CSR |= 0x40; //允许接收
IEN0 |= 0x84; //开总中断,允许接收中断
}
void UartSendString(char *Data,int len)
{
uint i;
for(i = 0;i<len;i++)
{
U0DBUF = *Data++;
while(UTX0IF == 0)
{
UTX0IF = 0;
}
}
}
#pragma vector = URX0_VECTOR //格式:#pragma vector = 中断向量,紧接着是中断处理程序
__interrupt void UART0_ISR(void)
{
URX0IF = 0; //UART0 TX中断标志初始置位0(清中断标志)
cmd = U0DBUF;
}
/****************************************************************
主函数
****************************************************************/
void main(void)
{
InitUart(115200); //串口初始化
InitLed();
UartState = UART0_RX; //串口0默认处于接收模式
memset(RxData, 0, SIZE);
while(1)
{
CmdPro(cmd);
}
}
TIPS1:IAR显示行号
TIPS2:IAR编译出现 Fatal Error[e72]: Segment BANKED_CODE must be defined
IAR编译出现 Fatal Error[e72]: Segment BANKED_CODE must be defined in a segment definition option (-Z, -b or -P)****
是链接(Link)出错:
原因是IAR新版本使用旧版本文件
解决方法:
打开project->options->linker->config->override default
填入地址:
T
O
O
L
K
I
T
D
I
R
TOOLKIT_DIR
TOOLKITDIR\config\devices\Texas Instruments\lnk51ew_cc2540F256_banked.xcl
选择banked的xcl文件即可,具体的文件可根据所用的芯片型号来选择。
串口的数据格式
头码1 | 头码2 | 长度 | 数据 | 校验
1BYTE | 1BYTE | 1BYTE | NBYTE | 1BYTE
头码1:0xAA
头码2:OxS5
长度为数据和校验总字节数
校验为长度字节和数据字节值求和,即和校验