UART是单片机与计算机通信的重要工具,可以外接蓝牙模块进行通信,也可以通过有线连接usb进行通信。
通过有线usb连接计算机时,单片机上只需连接TX,RX,GND,一般不需要连接VCC。
单片机的底层库一般都自带了UART通信模块,激活对应管脚,设定好波特率即可在程序中调用。
波特率决定数据的传输速率,波特率越高传输越快。一般为了稳定,传简单的数据用9600就够;传图像的话,最好用115200或以上,节省时间。
K60
K60用的是野火的底层库,可以参考它的手册;
输出
输出的话,定义好输出端口和波特率就能用。
uart_init (UART1,19200); //初始化 串口 1 波特率为 19200
uart_putchar (UART1,'F'); //发送一个字符'F'
uart_sendStr (UART1,"uart_str 函数发送数据"); //发送字符串
uart_putchar (UART1,'F'); //发送一个字符'F'
uart_sendStr (UART1,"uart_str 函数发送数据"); //发送字符串
开启Uart输入中断
// isr.h
// 串口输入中断服务
#undef VECTOR_061
#define VECTOR_061 UART0_IRQHandler
extern void UART0_IRQHandler(void);
// 串口输入中断服务
#undef VECTOR_061
#define VECTOR_061 UART0_IRQHandler
extern void UART0_IRQHandler(void);
// main.c
// main() 函数内
//打开串口中断
UART_IRQ_EN(UART0);
// main() 函数内
//打开串口中断
UART_IRQ_EN(UART0);
中断处理
// isr.c
/**************************************
UART0_IRQHandler
串口中断处理函数
**************************************/
void UART0_IRQHandler(void)
{
uint8 ch;
// DisableInterrupts; //关总中断 //注释掉,以允许其他中断进入
//接收一个字节数据并回发
ch=uartRecvChar (UART0); //接收到一个数据
uart0Printf("Input = %c\n",ch);
// 根据不同的输入进行不同的操作
switch(ch){
case 'a':
angle_adjust -= 0.01; gyro_integral = 0;
break;
case 'b':
angle_adjust -= 0.1; gyro_integral = 0;
break;
case 'c':
angle_adjust += 0.01; gyro_integral = 0;
break;
case 'd':
angle_adjust -= 0.01; gyro_integral = 0;
break;
}
}
/**************************************
UART0_IRQHandler
串口中断处理函数
**************************************/
void UART0_IRQHandler(void)
{
uint8 ch;
// DisableInterrupts; //关总中断 //注释掉,以允许其他中断进入
//接收一个字节数据并回发
ch=uartRecvChar (UART0); //接收到一个数据
uart0Printf("Input = %c\n",ch);
// 根据不同的输入进行不同的操作
switch(ch){
case 'a':
angle_adjust -= 0.01; gyro_integral = 0;
break;
case 'b':
angle_adjust -= 0.1; gyro_integral = 0;
break;
case 'c':
angle_adjust += 0.01; gyro_integral = 0;
break;
case 'd':
angle_adjust -= 0.01; gyro_integral = 0;
break;
}
}
XS128
好久没接触这东西,忘得差不多了,也没有硬件给我测试。
详细原理和配置,请参考MC9S12XS256 Reference Manual 中的Chapter 14 Serial Communication Interface (S12SCIV5)
初始化
设定波特率,global.h可以加上宏定义。
定义的值是写入SCI波特率寄存器的值,可以用这个公式计算: SBR = SCI bus clock / (16 x SCI baud rate)
//80M BUSCLK
#define Baud_9600 521 //520.833
#define Baud_11200 446 //446.429
#define Baud_19200 260 //260.417
#define Baud_38400 130 //130.208
#define Baud_56000 89 //89.286
#define Baud_57600 86 //86.80
#define Baud_115200 43 //43.40
#define SCI_Baud Baud_115200//设置baud 115200
#define Baud_9600 521 //520.833
#define Baud_11200 446 //446.429
#define Baud_19200 260 //260.417
#define Baud_38400 130 //130.208
#define Baud_56000 89 //89.286
#define Baud_57600 86 //86.80
#define Baud_115200 43 //43.40
#define SCI_Baud Baud_115200//设置baud 115200
程序启动时初始化
void UART_Init(void)
{
SCI1BD=SCI_Baud;
SCI1CR2=0x2c; //SCI控制寄存器2,启动中断,监听相应管脚。
}
{
SCI1BD=SCI_Baud;
SCI1CR2=0x2c; //SCI控制寄存器2,启动中断,监听相应管脚。
}
输入中断
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 21 SCI1_ISR(void)
{
EnableInterrupts; //开启中断(允许其他优先级更高的中断嵌套)
SCI1CR2_RIE=0; // 关闭串口中断
//此处为串口中断需要处理的事情
tmp =uart_getkey(); // 获取中断的字符
switch(tmp){
case 'e':
SendString("Speed=");
CarSpeedSet+=100;
SendInt((int)CarSpeedSet);
SendString("\n");
break;
case 'f':
SendString("Speed=");
CarSpeedSet-=100;
SendInt((int)CarSpeedSet);
SendString("\n");
break;
}
SCI1CR2_RIE = 1; //开启串口中断
EnableInterrupts; //开启中断
}
void interrupt 21 SCI1_ISR(void)
{
EnableInterrupts; //开启中断(允许其他优先级更高的中断嵌套)
SCI1CR2_RIE=0; // 关闭串口中断
//此处为串口中断需要处理的事情
tmp =uart_getkey(); // 获取中断的字符
switch(tmp){
case 'e':
SendString("Speed=");
CarSpeedSet+=100;
SendInt((int)CarSpeedSet);
SendString("\n");
break;
case 'f':
SendString("Speed=");
CarSpeedSet-=100;
SendInt((int)CarSpeedSet);
SendString("\n");
break;
}
SCI1CR2_RIE = 1; //开启串口中断
EnableInterrupts; //开启中断
}
输出
void uart_putchar(unsigned char ch)
{
while(!(SCI1SR1&0x80)) ; //keep waiting when not empty
SCI1DRL=ch;
}
{
while(!(SCI1SR1&0x80)) ; //keep waiting when not empty
SCI1DRL=ch;
}
Troubleshooting
1. 终端上看到接收到很多数据,但没有字符显示或者显示乱码。
检查收发波特率(Baud rate)是否匹配。
2. 通过UART向单片机发数据没有反应。
确认单片机开启了UART中断;
确认RX和TX没有接反(可以交换收发试试);
大神!!!