串口在单片机或SOC调试中,作用是非常大的。可以实时打印一些状态信息,也能进行交互,及时反馈。而在NIOS II环境下,操作串口的方法有很多。可以使用寄存器的方式控制,可以使用标准C函数,还可以使用类似Linux的方式读写串口。
这一节,说下标准C函数控制串口的方法,也就是printf和scanf函数的用法。
第七节,在NIOS II软件下创建第二个软核工程,创建的工程名为:uart_printf。修改文件名称:hello_world.c改为main.c之后,双击打开main.c文件。可以看到里面的代码:
#include <stdio.h>
int main()
{
printf("Hello from Nios II!\n");
return 0;
}
只有四行代码,但是是可以运行的。使用USB-BLASTER依次下载FPGA程序和NIOS II程序,在电脑端打开串口助手,可以看到串口打印信息:
是不是很简单!
在传统的STM32或51单片机中,需要对串口寄存器进行配置,还要对printf函数进行重定向,等等操作。但是,在NIOS II软件开发环境中,一切都给你配好了,直接使用就行。
那么,数据发送可以了,数据接收呢?
这里使用和printf函数对应的另一个函数,scanf函数,做为数据接收,看下适配效果如何。修改一下代码,添加scanf函数,把收到的数据存入一个数组,并判断收到的第一个字符是不是“a”,是的话,接收工作结束。代码如下:
#include <stdio.h>
#include "unistd.h"
#include <alt_types.h>
alt_8 test_str[50];
int main()
{
printf("Hello from Nios II!\n");
while(test_str[0] != 'a')
{
printf("waitting for 10 sec.\n");
usleep(1000000);
printf("waitting for 9 sec.\n");
usleep(1000000);
printf("waitting for 8 sec.\n");
usleep(1000000);
printf("waitting for 7 sec.\n");
usleep(1000000);
printf("waitting for 6 sec.\n");
usleep(1000000);
printf("waitting for 5 sec.\n");
usleep(1000000);
printf("waitting for 4 sec.\n");
usleep(1000000);
printf("waitting for 3 sec.\n");
usleep(1000000);
printf("waitting for 2 sec.\n");
usleep(1000000);
printf("waitting for 1 sec.\n");
usleep(1000000);
printf("10 sec over.\n");
if (scanf("%s", test_str) == 1)
{
printf("Receive string is: %s!\n", test_str);
}
else
{
printf("Invalid input.\n");
}
}
printf("test over!\n");
return 0;
}
除此之外,还添加了一个10秒的倒计时。用来判断收到多组数据时,能否及时处理。
编译,下载,可以看到串口打印信息如下:
10秒倒计时结束后,发送三个字符:123,注意,一定要带回车,否则无法识别。点击发送,可以看到如下效果:
数据接收测试完成。
第二个问题,倒计时进行中,scanf函数运行前,发送数据,CPU能否收到?
可以测一下,先发送“123”,带回车,然后在倒计时结束前,再发送“456”,带回车。效果如下:
可以看到,虽然发送的时刻还在倒计时,但是数据已经送到CPU里面了,倒计时结束后scanf函数会读取数据到定义的数组里。因此不用担心会丢数据。
第三个问题,阻塞问题。如果程序运行到scanf函数这里,但是没有设备向CPU发送数据,那么程序就会一直停在这里。这种情况还是比较危险的,所以使用时一定要注意。
我是单片机爱好者-MCU起航,打完收工!