UCOSii项目在NIOSii上的移植

概览

本次使用Altera公司的NIOS II软核。

使用Quatus工具生成BSP并利用BSP打包工具生成UCOSII嵌入环境。

手动书写LCD驱动与显示函数,对UCOS II加入简单图像显示接口。

./
├── create-this-app
├── driver        #板子的具体驱动(非操作系统)
│   ├── init.h    #初始化
│   ├── irs.h     #中断处理
│   ├── lcd.h     #LCD驱动
│   ├── sys.h     #系统驱动
│   └── tools.h   #工具
├── lib          #显示库
│   ├── ansii_lib.h
│   ├── cn_lib.h
│   ├── color.h
│   └── values.h
├── Makefile
├── obj
│   └── default
│       ├── sys_kernel.d
│       └── sys_kernel.o
├── readme.txt
├── sys_kernel.c    #系统的主函数
├── sys_user_interface.elf
├── sys_user_interface.map
├── sys_user_interface.objdump
└── tasks          #任务文件夹
    ├── task1.h
    └── task2.h

NIOS II软核生成

由于这次没有加载其余IP核,这次的软核非常简单,没有预留过多IP核PIO接口:

软核工程中包含以下内容:

  • NIOS II processer
  • 软核时钟信号
  • 外部存储器接口
  • SPI总线接口
  • 一个控制LCD屏幕亮度的接口
  • 一个软核版本控制器

若是有其余IP核需要加入,则需要单独的PIO进行交互,或者选择其余总线协议与IP核交互。

总线的速度非常慢,在软核中推荐使用可编程布线来进行交互。

具体软核IP核交互可以参考我的博客中的DES核与卷积核,这里不做过多描述。

FPGA工程概览

其中由于板载频率问题,加入了PLL

然后右边接了一个处理LCD的亮度的PWM模块也非常简单,不做过多描述。

UCOS II环境配置

由于这里使用的是Altera公司提供的NIOS II软核,其有完整的BSP与系统移植。

这里只需要根据选择软核生成对于此板子的BSP。

选择一个UCOS的系统工程即可。(还提供了其他的RTOS)

LCD 驱动书写

显示器驱动

  • LCD显示屏初始化

    void LCD_init() {
        //************* Reset LCD Driver ****************//
        IOWR_ALTERA_AVALON_PIO_DATA(LCD_RESET_BASE, 1);
        delay_ms(200);
        IOWR_ALTERA_AVALON_PIO_DATA(LCD_RESET_BASE, 0);
        delay_ms(200);
        IOWR_ALTERA_AVALON_PIO_DATA(LCD_RESET_BASE, 1);
        delay_ms(10);
        //************* Start Initial Sequence **********//
        //剩余参数配置见源代码,这里不予展示
    }

    LCD初始化可以直接利用芯片厂商提供的代码,或者参考芯片资料中的参数配置自行完成。

  • LCD显示驱动

    查阅ILI9481芯片手册,可以将发送一次指令和内容打包成Indexcmd两个函数。

    这两个函数内容如下:

    void LCD_ILI9481_INDEX(unsigned int data) {
        IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_BASE, 1);
        IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 0);
        IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE, data);
        IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 1);
    }
    void LCD_ILI9481_CMD(unsigned int data) {
        IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_BASE, 0);
        IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 0);
        IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE, data);
        IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 1);
    }

    发送一个指令的流程为先利用cmd函数发送指令,再用INDEX函数发送指令内容。

    再将LCD显示一个像素的图像打包为set_addrsend_data两个步骤,先通过set_addr发送像素地址,再用send_data发送像素颜色信息。

    send_addr的时序可以通过查阅芯片手册来得知,其代码如下:

    void set_addr(unsigned int x, unsigned int y){
        LCD_ILI9481_CMD(0x002b);
        LCD_ILI9481_INDEX(x >> 8);
        LCD_ILI9481_INDEX(x & 0x00ff);
        LCD_ILI9481_INDEX(0x0001);
        LCD_ILI9481_INDEX(0x00df);
    
        LCD_ILI9481_CMD(0x002a);
        LCD_ILI9481_INDEX(y >> 8);
        LCD_ILI9481_INDEX(y & 0x00ff);
        LCD_ILI9481_INDEX(0x0001);
        LCD_ILI9481_INDEX(0x003f);
    
        LCD_ILI9481_CMD(0x002c);
    }

    同样,可以写出send_data如下:

    void send_data(unsigned int data) {
        IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_BASE, 1);
        IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 0);
        IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE, data);
        IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 1);
    }
  • LCD显示工具

    ascii码显示工具(中文显示工具原理相同),利用lcd_buffer传参数,字母数据保存在word_libc

      void display_ascii(unsigned int x, unsigned int y, unsigned int w_color,
            unsigned int b_color) {
        unsigned int i, j, k = 0;
        unsigned char str;
        unsigned int OffSet, z;
    
        while (1) {
            if (lcd_buffer[k] == 0) {
                set_addr(<
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值